7

I would like to know if there is a way of programatically stopping a python script execution without killing the process like we do with this code:

import sys
sys.exit()

It would be the code equivalent to Ctrl+c

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
Santi Peñate-Vera
  • 1,053
  • 4
  • 33
  • 68
  • If by "stop" you mean "pause, with the possibility of continuing later", try `raw_input("Press Enter to continue.")` or `import pdb; pdb.set_trace()`. – Kevin Feb 09 '15 at 15:23
  • 4
    `Ctrl+C` throws a `KeyboardInterrupt` exception, which, if not caught, terminates the process. So I'm not sure how `sys.exit` is supposed to be much different. – Colonel Thirty Two Feb 09 '15 at 15:25
  • Also, Python is an interpreted language, that's why stopping execution of the script means stopping execution of the interpreter – ForceBru Feb 09 '15 at 15:26
  • Basically Ctrl + C keeps the terminal open and the objects in memory, while sys.exit() kills everything, and no, I do not mean pause. – Santi Peñate-Vera Feb 09 '15 at 15:29
  • I'm electrical engineer and I basically describe what I see here, so, in the IDE Spyder, when I do Ctrl+C on a console I kill the execution but the console remains open with all the results. With sys.exit() the console becomes unavailable. And I believe the question is quite valid, since from Spyder it is possible to achieve it, only that by keyboard strokes and not with actual orders. – Santi Peñate-Vera Feb 09 '15 at 15:33
  • Just raise an exception. – no_name Feb 09 '15 at 15:34

4 Answers4

9

Define your own exception,

class HaltException(Exception): pass

and wrap the script in

try:
    # script goes here

    # when you want to stop,
    raise HaltException("Somebody stop me!")

except HaltException as h:
    print(h)
    # now what?
Hugh Bothwell
  • 55,315
  • 8
  • 84
  • 99
4

Here is what I've found to work -- staying in the interpreter, while stopping a script.

# ------------------------------------------------------------------
# Reset so get full traceback next time you run the script and a "real"
# exception occurs
if hasattr (sys, 'tracebacklimit'):
    del sys.tracebacklimit

# ------------------------------------------------------------------
# Raise this class for "soft halt" with minimum traceback.
class Stop (Exception):
    def __init__ (self):
        sys.tracebacklimit = 0

# ==================================================================
# ... script here ...
if something_I_want_to_halt_on:
    raise Stop ()

# ... script continues ...
Dan K.
  • 41
  • 3
  • Of everything I've found, this is the nicest way to quietly stop a script. But, is it possible to get away without the reset code, which I have to put in my script? Can the Exception somehow clean up after itself? – A. Donda May 19 '19 at 22:32
4

I had this problem while developing a Sublime Text packages. I was trying to stop a Sublime Text Python package, to test something while the package was being reloaded.

If I call sys.exit(), I kill Sublime Text python interpreter and need to restart Sublime Text. But after searching I figured it out the solution is pretty simple, I just need to call raise ValueError(), instead of sys.exit():

import sys
print(sys.path)

sys.exit()

-->

import sys
print(sys.path)

raise ValueError()

This will stop the python script execution right after running print(sys.path). Although it will print a big stack trace. But if you add the instruction sys.tracebacklimit = 1 before raise ValueError(), you reduce the stack trace call to one line:

import sys
print(sys.path)

raise ValueError()

-->

import sys
print(sys.path)

sys.tracebacklimit = 1
raise ValueError()

Related questions:

  1. Stop running python script without killing the interpreter
  2. Manually raising (throwing) an exception in Python
Evandro Coan
  • 8,560
  • 11
  • 83
  • 144
3

Surely the simplest solution for the OP is raise KeyboardInterrupt?

This produces the same effect as ctrl+C in the terminal but can be called anywhere in the script. No need for import or further definition.

Cameron Hyde
  • 118
  • 7
  • Not incorrect, but explaining why in the future is good practice rather than just a one liner for people that might visit this in the future / 4 years ago and today. – charliebeckwith Jan 28 '19 at 05:42