cdo-bindings icon indicating copy to clipboard operation
cdo-bindings copied to clipboard

Python binding captures "kill" and "KeyboardInterrupt" signals in all processes after initialization

Open lukelbd opened this issue 2 years ago • 3 comments

Attempting to interrupt a process with Ctrl-C after initializing the python binding with cdo = Cdo() often fails and prints weird messages, even when interrupting python processes unrelated to the cdo commands. The nco python bindings (originally forked from this repo) also have the same issue.

Here's an example before initializing the binding:

In [1]: import time
   ...: while True:
   ...:     print('hi')
   ...:     time.sleep(1)
hi
hi
^[^C---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-2-0bf96da52d4a> in <module>
      2 while True:
      3     print('hi')
----> 4     time.sleep(1)

KeyboardInterrupt:

And here's an example after initializing the binding and holding down Ctrl+C:

In [3]: import time
   ...: from cdo import Cdo
   ...: cdo = Cdo()
   ...: while True:
   ...:     print('hi')
   ...:     time.sleep(1)
hi
hi
^Ccaught signal <cdo.Cdo object at 0x7f596c07dee0> 2 <frame at 0x7f5932049d40, file '<ipython-input-3-742fa89f637e>', line 6, code <module>>
hi
^Ccaught signal <cdo.Cdo object at 0x7f596c07dee0> 2 <frame at 0x7f5932049d40, file '<ipython-input-3-742fa89f637e>', line 6, code <module>>
hi
^Ccaught signal <cdo.Cdo object at 0x7f596c07dee0> 2 <frame at 0x7f5932049d40, file '<ipython-input-3-742fa89f637e>', line 6, code <module>>
hi
^Ccaught signal <cdo.Cdo object at 0x7f596c07dee0> 2 <frame at 0x7f5932049d40, file '<ipython-input-3-742fa89f637e>', line 6, code <module>>
hi

It's impossible to kill the while-loop without killing the parent shell -- even sending the ipython session to the background with Ctrl+Z and trying to kill the session with kill %1 fails because cdo seems to capture that signal as well:

$ kill %1
caught signal <cdo.Cdo object at 0x7f596c07dee0> 15 <frame at 0x7f5932049d40, file '<ipython-input-3-742fa89f637e>', line 6, code <module>>

The only way to stop the while loop is to kill the parent shell running the python process. Not sure how the binding is implemented but it seems to be changing something persistent about the python state.

lukelbd avatar Apr 23 '22 21:04 lukelbd

Seems to be related to these lines:

https://github.com/Try2Code/cdo-bindings/blob/8fa5b48389943ee1546cdc58114dc4877afeccf5/python/cdo.py#L177-L194

which cause interrupt signals to use this block:

https://github.com/Try2Code/cdo-bindings/blob/8fa5b48389943ee1546cdc58114dc4877afeccf5/python/cdo.py#L650-L653

I think it could be fixed by having __catch__ subsequently trigger the default signal action after deleting tempfiles.

@Try2Code I'd create a fork to try to fix it but would prefer to wait until #42 is merged.

lukelbd avatar Apr 23 '22 21:04 lukelbd

hi @lukelbd - thx for the work. I will have a lool into it

Try2Code avatar Apr 26 '22 08:04 Try2Code

Seems to be related to these lines:

https://github.com/Try2Code/cdo-bindings/blob/8fa5b48389943ee1546cdc58114dc4877afeccf5/python/cdo.py#L177-L194

which cause interrupt signals to use this block:

https://github.com/Try2Code/cdo-bindings/blob/8fa5b48389943ee1546cdc58114dc4877afeccf5/python/cdo.py#L650-L653

I think it could be fixed by having __catch__ subsequently trigger the default signal action after deleting tempfiles.

@Try2Code I'd create a fork to try to fix it but would prefer to wait until #42 is merged.

True, that catch should not eat up the signal but do something before letting the process die.

#42 is merged

Try2Code avatar Apr 26 '22 10:04 Try2Code

Solved by #44. Thanks @Try2Code for the merge!

lukelbd avatar Mar 29 '23 19:03 lukelbd