Python 3.3.2 doesn't allow me to use 'raise SystemExit' - python

name = input('name? ')
if len(name) == 0:
print('error.\n')
raise SystemExit
I receive an error when using python 3.3.2 (which is the version is school sadly) but it works fine on other versions e.g. 2.7.10 and 3.5
This is the error

Looking at the screenshot I can see Python prompt at the bottom:
This means the script is run in an interactive session (IDLE on Windows I guess). I haven't found any documentation, but other users have discovered that raising SystemExit in an interactive session does print the traceback.
So you should check and ensure that you are not launching the script in an interactive session.
Old answer:
Looks like it's a bug (or a particularity) in Python 3.3.2. According to this blog post:
If nothing catches the exception, then the python interpreter catches
it at the end, does not print a stack trace, and then calls exit.
I tried to raise SystemExit('asd') and the program just printed asd, so looks like it's true.
Either upgrade Python or try os._exit(1).

Not sure if this is what you want, but if you wanna exit use this:
import sys
name = raw_input('name? ')
if len(name) == 0:
print('error.\n')
sys.exit()
This exits the interpreter by raising SystemExit.

Why don't you use sys.exit()?
sys.exit([arg])
Exit from Python. This is implemented by raising the SystemExit exception, so cleanup actions specified by finally clauses of try statements are honored, and it is possible to intercept the exit attempt at an outer level.

You probably have an handler set for excepthook:
https://docs.python.org/3/library/sys.html#sys.excepthook
You should be able to reset it by doing
sys.excepthook = sys.__excepthook__
Nevermind, the hook works correctly for BaseException, but weirdly enough not for SystemExit (which is a subclass of BaseException).
You're probably executing your program with
python3 -i whatever.py
This gives me the same behavior you witnessed:
dario#feynman ~> python3 -i /tmp/a.py
Traceback (most recent call last):
File "/tmp/a.py", line 11, in <module>
raise SystemExit()
SystemExit
>>>
Note the >>> at the end.
Just remove the -i flag, from whatever is executing your program
Alternatively, it's bad practice, but you can also use os._exit(1)

Related

How to make Python "not recognized as an internal or external command" an exception

I have this block of code:
path = askdirectory(title='Choose folder')
os.chdir(path)
try:
os.system('currency.py')
except:
#Error message
ctypes.windll.user32.MessageBoxW(0, u"Error", u"Error", 0)
What I want to accomplish is that when the user chooses the wrong folder (the one in which the 'currency.py' file is not in), it throws this little Error message box.
Instead, when I purposely choose the wrong folder, it says:
"currency.py "is not recognized as an internal or external command
But it doesn't show me the error window. Is there a way to make python recognize this error as an exception? Thank you!
It appears you are using Python to run a Python file using the operating system shell.
You can run the file by importing it and (if needed) instantiating it.
try:
# import the python file
import currency.py
# instantiate the class/function if required
except ImportError:
ctypes.windll.user32.MessageBoxW(0, u"Error", u"Error", 0)
Nevertheless you can avoid using the try/catch scenario by seeing if the file exists, if not, display your error message:
if os.path.isfile(file_path):
os.system('currency.py')
else:
ctypes.windll.user32.MessageBoxW(0, u"Error", u"Error", 0)
You could try listening for the %ErrorLevel% code for anything different than 0 (successful) and, if it matches, then raise Exception.
It would work like this, for example:
if os.system('currency.py'):
raise Exception

pdb bypass error/Jump failed: can only jump from a 'line' trace event

I'm trying to debug a Python program using pdb. The program could be like this:
def main():
a = 1
print(b)
c = 2
d = 3
Apparently, print(b) is a typo which should be print(a) but it is not important and I can fix it with the text editor but I want to bypass this error and continue debugging.
I tried jump, like jump 4(assuming "c=2" is line 4) but I was given error "Jump failed: f_lineno can only be set by a line trace function", which means I need to give a line trace function when I'm programming.
So, is there a way to deal with this problem, or is there some other way to bypass the error line when using pdb?
TLDR: this is pdb's post-mortem mode in which jumping is not supposed to work. But it's still very useful.
Painting by Rembrandt (public domain)
I reproduce it with python 3.8.2 as *** Jump failed: can only jump from a 'line' trace event by running the script "under pdb" like so: python3 -m pdb -c c script.py and trying to jump to another line in pdb prompt which then appears.
What's happened: an unhandled exception, in this case NameError: name 'b' is not defined caused python to stop interpreting the script; pdb intercepted this situation and entered its post-mortem mode.
As Almar Klein nicely put it in his blog post,
Post-mortem debugging refers to the concept of entering debug mode after something has broken. There is no setting of breakpoints involved, so it's very quick and you can inspect the full stack trace, making it an effective way of tracing errors.
Although jump, next, return won't work in post-mortem, bt, up, down, ll and pp, along with the possibility to import modules and run arbitrary python code directly in the pdb's interactive shell can be very effective ways to get the root cause. In our simple example the root cause of the NameError is shown immediately upon a quick ll: pdb prefixes the offending line of code with >>.
Had we not passed -c c (meaning continue), pdb would have shown its prompt and paused before the first line of your program is interpreted, so you'd have a chance to step through the whole program or set a breakpoint before or at the offending line, and jump over it, never entering the post-mortem.
Even in post-mortem, you can prepare a breakpoint anywhere in the program, e.g. break 2 for line 2, and say c or continue so pdb will finish post-mortem, reload the file, and restart the program with the updated set of breakpoints.
Another way to deal with it is to import pdb and pdb.set_trace() in suspicious code - or since python 3.7, simply breakpoint() - and run the python program normally (not "under" pdb anymore) which allows then to jump, next, return etc, as well as everything else - when the breakpoint is hit.
If your Python program is started through behave:
prefer to run behave with --no-capture whenever using pdb or similar debuggers (whether post-mortem mode or not), to avoid problems with behave's stdin/stdout capturing making pdb unresponsive and/or its prompt invisible.
best of all, if you want to end up in the pdb post-mortem mode automatically while potentially still supporting capturing, set the post_mortem environment variable (can also name it differently) to any value (but only on dev machine, not for automated CI or production!) and commit the following permanently into environment.py:
def after_step(context, step):
import os
if 'post_mortem' in os.environ and step.status == 'failed':
import pdb
# Similar to "behave --no-capture" calling stop_capture() ensures visibility of pdb's prompts,
# while still supporting capture until an uncaught error occurs.
# Warning: this does rely on behave's internals which might change
context._runner.stop_capture() # pylint: disable=protected-access
pdb.post_mortem(step.exc_traceback)
I'm not sure, but this may be a bug that was fixed in Mar 2018, so you may need to (patch, upgrade, reinstall?) your Python.

logger.info(traceback.print_exc()) coming on python gui

When I execute logger.info(traceback.print_exc())
the trace gets on console rather than in the log file
I have logger.propagate = False also still the same issue
print_exc prints the stack trace to stderr.
Just use the exc_info=1 argument and it will automaticaly include the exception.
logging.exception("Exception") #or
logging.error("exception ",exc_info=1) #or
logging.info("Exception has occured" ,exc_info=1)
I am using python 2.7 and sadly exc_info=1 never worked for me so I had to use this:
import traceback
...
log.debug(traceback.format_exc())

How do i print the script line number in IronPython?

I am running an IronPython script inside a c# application, i am catching exceptions within the script and i wish to find out the script line at which the exception is thrown. This has to be done while the script is running ie. i do not wish the script to terminate in order to print the exception.
Is this even possible?
If inspect is working as expected under IronPython (not really sure) this could do the trick:
import inspect
filename, linenum, funcname = inspect.getframeinfo(inspect.currentframe())[:3]
print linenum
Edit: alternate solution:
import sys
frame = sys._getframe()
print frame.f_lineno
Haven't tried this on ironpython but:
import traceback
try:
# something that raises exception
except YourException, _:
traceback.print_exc()
This should show you the stack trace of the place where the exception was raised. You can also do other stuff than just print, like print to string, or get the stack frames.
The traceback module documentation will tell you more.

Handling exceptions without try block in Python's interactive shell

See the title of this question. I want to play with the exception raised in the last command. _ didn't help me. Is there anything like that?
Do this:
import sys
sys.exc_info()
It will give you information about the exception. It's a tuple containing the exception type, the exception instance and a traceback object.
If your 'interactive' happens within Jupyter, check this > Jupyter magic to handle notebook exceptions
It is just beautiful.
If you want to add a sound > Jupyter / Colab : Play sound with any error in any cell + Play sound after completing long running cells

Categories