31
Python 2.7.5 (default, Feb 26 2014, 13:43:17)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> try:
...  sys.exit()
... except:
...  print "in except"
...
in except
>>> try:
...  sys.exit(0)
... except:
...  print "in except"
...
in except
>>> try:
...  sys.exit(1)
... except:
...  print "in except"
...
in except

Why am not able to trigger sys.exit() in try, any suggestions...!!!

The code posted here has all the version details.

I have tried all possible ways i know to trigger it, but i failed. It gets to 'except' block.

Thanks in advance..

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
onlyvinish
  • 435
  • 1
  • 5
  • 20
  • 4
    I closed this as a duplicate, because the other post explains a) what goes wrong and b) how to avoid this. Blanket `except:` clauses are not a good idea, at best use `except Exception:` to avoid catching `SystemExit`. – Martijn Pieters Sep 18 '14 at 06:52
  • use os._exit(0) if you don't want to trigger an exception. – Back2Basics Sep 18 '14 at 06:54
  • 4
    @Back2Basics: **Don't** call `os._exit()`; that just ensures nothing gets cleaned up as the processor exits. – Martijn Pieters Sep 18 '14 at 07:00

2 Answers2

39

sys.exit() raises an exception, namely SystemExit. That's why you land in the except-block.

See this example:

import sys

try:
    sys.exit()
except:
    print(sys.exc_info()[0])

This gives you:

<type 'exceptions.SystemExit'>

Although I can't imagine that one has any practical reason to do so, you can use this construct:

import sys

try:
    sys.exit() # this always raises SystemExit
except SystemExit:
    print("sys.exit() worked as expected")
except:
    print("Something went horribly wrong") # some other exception got raised
tamasgal
  • 24,826
  • 18
  • 96
  • 135
  • Is there any way to do this in try block. – onlyvinish Sep 18 '14 at 06:48
  • There is no reason, since what you try to achieve is raising an exception in `try` and "catch" it in the next moment. It is absolutely clueless ;-) – tamasgal Sep 18 '14 at 06:49
  • 5
    Use `except Exception`, because `SystemExit` inherits directly from `BaseException`. See the [exception hierarchy](https://docs.python.org/2/library/exceptions.html#exception-hierarchy) – Vincent Sep 18 '14 at 06:50
  • Thanks buddy..!! If u come across any idea regarding this, plz do update me. – onlyvinish Sep 18 '14 at 06:52
  • See the updated code example to achieve what you wanted. However, still no idea why you would do that. – tamasgal Sep 18 '14 at 06:55
  • 2
    @onlyvinish He already gave you an idea! What else are you missing? – glglgl Sep 18 '14 at 07:23
12

based on python wiki :

Since exit() ultimately “only” raises an exception, it will only exit the process when called from the main thread, and the exception is not intercepted.

And:

The exit function is not called when the program is killed by a signal, when a Python fatal internal error is detected, or when os._exit() is called.

Therefore, If you use sys.exit() within a try block python after raising the SystemExit exception python refuses of completing the exits's functionality and executes the exception block.

Now, from a programming perspective you basically don't need to put something that you know definitely raises an exception in a try block. Instead you can either raise a SystemExit exception manually or as a more Pythonic approach if you don't want to loose the respective functionalities of sys.exit() like passing optional argument to its constructor you can call sys.exit() in a finally, else or even except block.

Method 1 (not recommended)

try:
    # do stuff
except some_particular_exception:
    # handle this exception and then if you want 
    # do raise SystemExit
else:
    # do stuff and/or do raise SystemExit
finally:
    # do stuff and/or do raise SystemExit

Method 2 (Recommended):

try:
    # do stuff
except some_particular_exception:
    # handle this exception and then if you want 
    # do sys.exit(stat_code)
else:
    # do stuff and/or do sys.exit(stat_code)
finally:
    # do stuff and/or do sys.exit(stat_code)
Mazdak
  • 105,000
  • 18
  • 159
  • 188
  • 4
    Don't call `os._exit()` yourself, *just don't catch `SystemExit`*. Calling `os._exit()` means nothing gets cleaned up either. – Martijn Pieters Sep 18 '14 at 06:59