Home > Net >  Capture PyCharm stop signal in Python
Capture PyCharm stop signal in Python

Time:10-12

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.

I've tried catching it as enter image description here

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')
  • Related