I want to try capturing PyCharm's stop signal (when stop is pressed) in a try block, but I cannot figure out what this signal is or how to capture it in code. JetBrains doesn't provide insight into this in their documentation.
The stacktrace will give:
Traceback (most recent call last):
File "C:/path_to/your_module.py", line 2, in <module>
print("Press stop button here.")
File "C:/path_to/your_module.py", line 2, in <module>
print("Press stop button here.")
File "_pydevd_bundle\pydevd_cython_win32_39_64.pyx", line 1589, in _pydevd_bundle.pydevd_cython_win32_39_64.ThreadTracer.__call__
File "_pydevd_bundle\pydevd_cython_win32_39_64.pyx", line 929, in _pydevd_bundle.pydevd_cython_win32_39_64.PyDBFrame.trace_dispatch
File "_pydevd_bundle\pydevd_cython_win32_39_64.pyx", line 920, in _pydevd_bundle.pydevd_cython_win32_39_64.PyDBFrame.trace_dispatch
File "_pydevd_bundle\pydevd_cython_win32_39_64.pyx", line 317, in _pydevd_bundle.pydevd_cython_win32_39_64.PyDBFrame.do_wait_suspend
File "C:\Program Files\JetBrains\PyCharm 2019.3.2\plugins\python\helpers\pydev\pydevd.py", line 1147, in do_wait_suspend
self._do_wait_suspend(thread, frame, event, arg, suspend_type, from_this_thread)
File "C:\Program Files\JetBrains\PyCharm 2019.3.2\plugins\python\helpers\pydev\pydevd.py", line 1162, in _do_wait_suspend
time.sleep(0.01)
KeyboardInterrupt
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm 2019.3.2\plugins\python\helpers\pydev\pydevd.py", line 2173, in <module>
main()
File "C:\Program Files\JetBrains\PyCharm 2019.3.2\plugins\python\helpers\pydev\pydevd.py", line 2164, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "C:\Program Files\JetBrains\PyCharm 2019.3.2\plugins\python\helpers\pydev\pydevd.py", line 1476, in run
return self._exec(is_module, entry_point_fn, module_name, file, globals, locals)
File "C:\Program Files\JetBrains\PyCharm 2019.3.2\plugins\python\helpers\pydev\pydevd.py", line 1483, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
File "C:\Program Files\JetBrains\PyCharm 2019.3.2\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents "\n", file, 'exec'), glob, loc)
File "C:/path_to/your_module.py", line 4, in <module>
raise Exception('Smelly socks').with_traceback(err.__traceback__)
File "C:/path_to/your_module.py ", line 2, in <module>
print("Press stop button here.")
File "C:/path_to/your_module.py ", line 2, in <module>
print("Press stop button here.")
File "_pydevd_bundle\pydevd_cython_win32_39_64.pyx", line 1589, in _pydevd_bundle.pydevd_cython_win32_39_64.ThreadTracer.__call__
File "_pydevd_bundle\pydevd_cython_win32_39_64.pyx", line 929, in _pydevd_bundle.pydevd_cython_win32_39_64.PyDBFrame.trace_dispatch
File "_pydevd_bundle\pydevd_cython_win32_39_64.pyx", line 920, in _pydevd_bundle.pydevd_cython_win32_39_64.PyDBFrame.trace_dispatch
File "_pydevd_bundle\pydevd_cython_win32_39_64.pyx", line 317, in _pydevd_bundle.pydevd_cython_win32_39_64.PyDBFrame.do_wait_suspend
File "C:\Program Files\JetBrains\PyCharm 2019.3.2\plugins\python\helpers\pydev\pydevd.py", line 1147, in do_wait_suspend
self._do_wait_suspend(thread, frame, event, arg, suspend_type, from_this_thread)
File "C:\Program Files\JetBrains\PyCharm 2019.3.2\plugins\python\helpers\pydev\pydevd.py", line 1162, in _do_wait_suspend
time.sleep(0.01)
Exception: Smelly socks
Process finished with exit code 1
What the stacktrace shows is the exception thrown when you press the stop button is a KeyboardInterrupt
but you could also write the catch
clause using an exception that's higher in the Exception Hierarchy
(e.g. BaseException
) the results would be the same.
CodePudding user response:
I wasn't able to replicate the other answers as the stop button being sent as a keyboard interrupt. I do believe it's possible for the stop button to be implemented differently on different versions of PyCharm and OS (I'm on Linux where a different answer seems to be Windows, but I'm not positive on many aspects here)
It seems to me that a kill signal is being sent, and it doesn't seem like catching that as an exception works (for me). However, I was able to somewhat catch a kill signal by referencing this post that talks about catching kill signals in Python and killing gracefully. Below is the code I used. When I press the stop button I see Hello world
, but I do NOT see foobar
.
Also, the debugger is NOT able to be caught for me by breakpoints in handler_stop_signals
by doing this, but I do see the text. So I'm not sure if this is actually going to answer your question or not, based on your needs. Also note I would never actually write code like this (using globals), but it was the simplest answer I was able to come up with.
import signal
import time
run = True
def handler_stop_signals(signum, frame):
global run
print("Hello world")
run = False
signal.signal(signal.SIGINT, handler_stop_signals)
signal.signal(signal.SIGTERM, handler_stop_signals)
while run:
try:
time.sleep(20) # do stuff including other IO stuff
except: BaseException as e:
print('foobar')