| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent b82e17e commit 608876b
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -519,13 +519,13 @@ Signal Handling | |||
| 519 | 519 | single: SIGINT | |
| 520 | 520 | single: KeyboardInterrupt (built-in exception) | |
| 521 | 521 | ||
| 522 | - This function simulates the effect of a :const:`SIGINT` signal arriving --- the | ||
| 523 | - next time :c:func:`PyErr_CheckSignals` is called, :exc:`KeyboardInterrupt` will | ||
| 524 | - be raised. It may be called without holding the interpreter lock. | ||
| 525 | - | ||
| 526 | - .. % XXX This was described as obsolete, but is used in | ||
| 527 | - .. % _thread.interrupt_main() (used from IDLE), so it's still needed. | ||
| 522 | + Simulate the effect of a :const:`SIGINT` signal arriving. The next time | ||
| 523 | + :c:func:`PyErr_CheckSignals` is called, the Python signal handler for | ||
| 524 | + :const:`SIGINT` will be called. | ||
| 528 | 525 | ||
| 526 | + If :const:`SIGINT` isn't handled by Python (it was set to | ||
| 527 | + :data:`signal.SIG_DFL` or :data:`signal.SIG_IGN`), this function does | ||
| 528 | + nothing. | ||
| 529 | 529 | ||
| 530 | 530 | .. c:function:: int PySignal_SetWakeupFd(int fd) | |
| 531 | 531 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -53,8 +53,12 @@ This module defines the following constants and functions: | |||
| 53 | 53 | ||
| 54 | 54 | .. function:: interrupt_main() | |
| 55 | 55 | ||
| 56 | - Raise a :exc:`KeyboardInterrupt` exception in the main thread. A subthread can | ||
| 57 | - use this function to interrupt the main thread. | ||
| 56 | + Simulate the effect of a :data:`signal.SIGINT` signal arriving in the main | ||
| 57 | + thread. A thread can use this function to interrupt the main thread. | ||
| 58 | + | ||
| 59 | + If :data:`signal.SIGINT` isn't handled by Python (it was set to | ||
| 60 | + :data:`signal.SIG_DFL` or :data:`signal.SIG_IGN`), this function does | ||
| 61 | + nothing. | ||
| 58 | 62 | ||
| 59 | 63 | ||
| 60 | 64 | .. function:: exit() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,6 +16,7 @@ | |||
| 16 | 16 | import weakref | |
| 17 | 17 | import os | |
| 18 | 18 | import subprocess | |
| 19 | + import signal | ||
| 19 | 20 | ||
| 20 | 21 | from test import lock_tests | |
| 21 | 22 | from test import support | |
@@ -1168,12 +1169,46 @@ class BoundedSemaphoreTests(lock_tests.BoundedSemaphoreTests): | |||
| 1168 | 1169 | class BarrierTests(lock_tests.BarrierTests): | |
| 1169 | 1170 | barriertype = staticmethod(threading.Barrier) | |
| 1170 | 1171 | ||
| 1172 | + | ||
| 1171 | 1173 | class MiscTestCase(unittest.TestCase): | |
| 1172 | 1174 | def test__all__(self): | |
| 1173 | 1175 | extra = {"ThreadError"} | |
| 1174 | 1176 | blacklist = {'currentThread', 'activeCount'} | |
| 1175 | 1177 | support.check__all__(self, threading, ('threading', '_thread'), | |
| 1176 | 1178 | extra=extra, blacklist=blacklist) | |
| 1177 | 1179 | ||
| 1180 | + | ||
| 1181 | + class InterruptMainTests(unittest.TestCase): | ||
| 1182 | + def test_interrupt_main_subthread(self): | ||
| 1183 | + # Calling start_new_thread with a function that executes interrupt_main | ||
| 1184 | + # should raise KeyboardInterrupt upon completion. | ||
| 1185 | + def call_interrupt(): | ||
| 1186 | + _thread.interrupt_main() | ||
| 1187 | + t = threading.Thread(target=call_interrupt) | ||
| 1188 | + with self.assertRaises(KeyboardInterrupt): | ||
| 1189 | + t.start() | ||
| 1190 | + t.join() | ||
| 1191 | + t.join() | ||
| 1192 | + | ||
| 1193 | + def test_interrupt_main_mainthread(self): | ||
| 1194 | + # Make sure that if interrupt_main is called in main thread that | ||
| 1195 | + # KeyboardInterrupt is raised instantly. | ||
| 1196 | + with self.assertRaises(KeyboardInterrupt): | ||
| 1197 | + _thread.interrupt_main() | ||
| 1198 | + | ||
| 1199 | + def test_interrupt_main_noerror(self): | ||
| 1200 | + handler = signal.getsignal(signal.SIGINT) | ||
| 1201 | + try: | ||
| 1202 | + # No exception should arise. | ||
| 1203 | + signal.signal(signal.SIGINT, signal.SIG_IGN) | ||
| 1204 | + _thread.interrupt_main() | ||
| 1205 | + | ||
| 1206 | + signal.signal(signal.SIGINT, signal.SIG_DFL) | ||
| 1207 | + _thread.interrupt_main() | ||
| 1208 | + finally: | ||
| 1209 | + # Restore original handler | ||
| 1210 | + signal.signal(signal.SIGINT, handler) | ||
| 1211 | + | ||
| 1212 | + | ||
| 1178 | 1213 | if __name__ == "__main__": | |
| 1179 | 1214 | unittest.main() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -261,7 +261,7 @@ Donn Cave | |||
| 261 | 261 | Charles Cazabon | |
| 262 | 262 | Jesús Cea Avión | |
| 263 | 263 | Per Cederqvist | |
| 264 | - Matej Cepl | ||
| 264 | + Matěj Cepl | ||
| 265 | 265 | Carl Cerecke | |
| 266 | 266 | Octavian Cerna | |
| 267 | 267 | Michael Cetrulo | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + ``_thread.interrupt_main()`` now avoids setting the Python error status | ||
| 2 | + if the ``SIGINT`` signal is ignored or not handled by Python. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1683,13 +1683,18 @@ _PyErr_CheckSignals(void) | |||
| 1683 | 1683 | } | |
| 1684 | 1684 | ||
| 1685 | 1685 | ||
| 1686 | - /* Replacements for intrcheck.c functionality | ||
| 1687 | - * Declared in pyerrors.h | ||
| 1688 | - */ | ||
| 1686 | + /* Simulate the effect of a signal.SIGINT signal arriving. The next time | ||
| 1687 | + PyErr_CheckSignals is called, the Python SIGINT signal handler will be | ||
| 1688 | + raised. | ||
| 1689 | + | ||
| 1690 | + Missing signal handler for the SIGINT signal is silently ignored. */ | ||
| 1689 | 1691 | void | |
| 1690 | 1692 | PyErr_SetInterrupt(void) | |
| 1691 | 1693 | { | |
| 1692 | - trip_signal(SIGINT); | ||
| 1694 | + if ((Handlers[SIGINT].func != IgnoreHandler) && | ||
| 1695 | + (Handlers[SIGINT].func != DefaultHandler)) { | ||
| 1696 | + trip_signal(SIGINT); | ||
| 1697 | + } | ||
| 1693 | 1698 | } | |
| 1694 | 1699 | ||
| 1695 | 1700 | void | |
| Back | FazBrowse Home | New Git URL |
0 commit comments