How can I stop a python process in such a way that any active context managers will gracefully call their __exit__ function before closing?
I use context managers (__enter__() and __exit__()) to reliably and safely close connections to optical hardware. This has been working great, although we are now starting to execute routines that run for hours. Often we will realize shortly after starting one that we have a bug, and would rather to stop the process short.
I have been running code from PyCharm, which has allows you to "stop" a running process. This seems to instantly kill the process, whether I'm in debug or run. The __exit__ functions don't seem to get called.
Also, the computer that controls the hardware runs windows, if that somehow comes into play. ***
***Indeed in comes into play. Macosx seems to call the exit function while windows does not.
I decided to write a basic test:
from abc import *
__metaclass__ = ABCMeta
def __init__(self, *args, **kwargs):
def __enter__(self, *args, **kwargs):
def __exit__(self, type, value, traceback):
with Test() as t:
print("Should never get here.")
Traceback (most recent call last):
File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1591, in <module>
globals = debugger.run(setup['file'], None, None, is_module)
File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1018, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/Users/.../Library/Preferences/PyCharmCE2017.1/scratches/scratch_25.py", line 22, in <module>
Process finished with exit code 1
I found a workaround on the PyCharm bug tracker:
If you use Numpy or Scipy, you will also need to add the following environment variable:
os.environ['FOR_DISABLE_CONSOLE_CTRL_HANDLER'] = "1"
Now when I run my test with this applied (on Windows!) I get the following output:
Init called. enter called Exit called Traceback (most recent call last): File "C:/Users/.../.PyCharmCE2017.1/config/scratches/scratch_3.py", line 20, in <module> time.sleep(100) KeyboardInterrupt Process finished with exit code 1