I'd like to force sys.exit() when the python debugger is stopped. When I stop the debugger I see Terminated: 15 so I assume this is SIGTERM. However, when stopping the debugger, my kill function isn't called.
def kill(sig, frame):
sys.exit(0)
signal.signal(signal.SIGINT, kill)
signal.signal(signal.SIGTERM, kill)
When stopping the vscode debugger, what signal is sent?
Edit:
Just tried all of them. No love
for s in signal.Signals:
try:
signal.signal(s, self._kill)
except:
pass
For now we seem to be OOL (out of luck) - I ran into the same issue and found that VS Code python extension does issue a SIGKILL on debug stop, which cannot be cought.
Unlike the node.js extenstion, the Python extension also does not support setting the type to SIGTERM or SIGINT.
The only workaround I found is to have an open terminal (type: Pythen Debug Terminal) in VS Code. It should show the python command behavior and output during debug. Bring the terminal into focus by clicking on it and press ctrl-C manually. This should stop the debugged program gracefully and your catching the SIGTERM or SIGINT will work.
Related
I want to create a program that does something in which someone terminates the script by clicking the stop button in PyCharm. I tried
from sys import exit
def handler(signal_received, frame):
# Handle any cleanup here
print('SIGINT or CTRL-C detected. Exiting gracefully')
exit(0)
if __name__ == '__main__':
signal(SIGINT, handler)
print('Running. Press CTRL-C to exit.')
while True:
# Do nothing and hog CPU forever until SIGINT received.
pass
from https://www.devdungeon.com/content/python-catch-sigint-ctrl-c.
I tried on both Mac and Windows. On the Mac, PyCharm behaved as expected, when I click the stop button it catches the SIGINT. But on Windows, I did exactly the same thing, but it just straightly returns to me a
Process finished with exit code -1. Is there something I can do to change to make the Windows behave like what on Mac?
Any help is appreciated!
I don't think it's a strange question at all. On unix systems, pycham sends a SIGTERM, waits one second, then send a SIGKILL. On windows, it does something else to end the process, something that seems untrappable. Even during development you need a way to cleanly shut down a process that uses native resources. In my case, there is a CAN controller that, if not shut down properly, can't ever be opened again. My work around was to build a simple UI with a stop button that shuts the process down cleanly. The problem is, out of habit, from using pycharm, goland, and intellij, is to just hit the red, square button. Every time I do that I have to reboot the development system. So I think it is clearly also a development time question.
This actually isnt a simple thing, because PyCharm sends SIGKILL with the stop button. Check the discussion here https://youtrack.jetbrains.com/issue/PY-13316
There is a comment that you can enable "kill windows process softly", however it didnt work for me. The one that does work is emulate terminal in the debug config, then use control c when you select the console window
I have a python 3 script and it runs on boot. And it work with some resources I want it free on exit.
How can I manage that script is going to exit if I'm killing it with kill -6 $PID.
Or any other ideas about how to send exit command and detect it in script.
The signal module is what you are looking for.
import signal
def handler(signum, frame):
print('Signal handler called with signal', signum)
signal.signal(signal.SIGABRT, handler)
Within the handler function you could terminate with sys.exit().
However, it is more common to use SIGINT (that's what happens when you press CTRL+C in the terminal) or SIGTERM to terminate a program. If you don't have cleanup code you don't need to write a single line of code to handle SIGINT - by default it raises a KeyboardInterrupt exception which, if not caught (that's a reason why you should never use blank except: statements), causes your program to terminate.
So I have a python script which I run in the command prompt as you'd expect
python myscript.py
Inside my script I have a line that intercepts Ctrl+C and is suppose to tidy up a few things and shut down the script.
def check_for():
while True:
# Perform check and operation if needed
if __name__ == '__main__':
try:
threading.Thread(target=check_for).start()
# Perform script duties
except KeyboardInterrupt:
print "Tidying up a few things"
# Performs tidying duties
sys.exit()
But it doesn't seem to actual exit the program. It prints the message so I know its getting that interrupt signal, but I don't have control back in the command prompt and when I look in Task Manager I see the python process for it still running. I only regain control once I end that process. In fact, even if the program runs to completion normally without being interrupted the process remains.
My program does spawn child threads, which is why I use sys.exit() over other methods which I heard can't be excepted and do more abrupt ends.
Am I doing something wrong? Is there a cross platform method of doing this (which is what I thought sys.exit() was)?
Edit: So I've isolated the issue. I created a small test script and it seems to be when I create a thread it just doesn't die and thus the program never exits. I've changed my initial code to show the setup.
I have a python 3 script and it runs on boot. And it work with some resources I want it free on exit.
How can I manage that script is going to exit if I'm killing it with kill -6 $PID.
Or any other ideas about how to send exit command and detect it in script.
The signal module is what you are looking for.
import signal
def handler(signum, frame):
print('Signal handler called with signal', signum)
signal.signal(signal.SIGABRT, handler)
Within the handler function you could terminate with sys.exit().
However, it is more common to use SIGINT (that's what happens when you press CTRL+C in the terminal) or SIGTERM to terminate a program. If you don't have cleanup code you don't need to write a single line of code to handle SIGINT - by default it raises a KeyboardInterrupt exception which, if not caught (that's a reason why you should never use blank except: statements), causes your program to terminate.
I am using pytest to run tests and, during the execution of a test, interrupted with ctrl-C.
No matter how many times I ctrl-C to get out of the test session (I've also tried ctrl-D to get out of the environment I'm using), my terminal prompt does not return.
I accidentally pressed F as well... test.py ^CF^C Does the F have something to do with my being stuck in the captured stderr section and the prompt not returning?
Are there any logic explanations why I'm stuck here, and if so, are there any alternatives to exiting this state without closing the window and force exiting the session?
I would suggest trying control-Z. That should suspend it; you can then do kill %1 (or kill -9 %1) to kill it (assuming you don't have anything else running in the background)
What I'm guessing is happening (from personal experience) is that one of your tests is running in a try / except that is catching all exceptions (including the keyboard interrupt which control c triggers) and is inside a while loop / ignoring the exception.