I am using Eclipse + PyDev, although I can break on exception using PyDev->Manage Exception Breakpoints, I am unable to continue the execution after the exception.
What I would like to be able to do is to set the next statement before the exception so I can run a few commands in the console window and continue execution. If I use Eclipse -> Run -> Set Next Statement before the exception, the editor will show the next statement being where I set it but then when resuming the execution, the program will be terminated.
Can this be done ?
Unfortunately no, this is a Python restriction on setting the next line to be executed: it can't set the next statement after an exception is thrown (it can't even go to a different block -- i.e.: if you're inside a try..except, you can't set the next statement to be out of that block).
You could in theory take a look at Python itself as it's open source and see how it handles that and make it more generic to handle your situation, but apart from that, what you want is not doable.
Related
A similar question
When developing some Windows desktop stuff in Delphi, I had a habit of inserting
asm(int 3);.
If a debugger is running, that acts like a breakpoint. If no debugger is running, it does nothing (NOOP).
I would like to do something similar for my Python scripts. Is there some Python function like HaltDebugger()? Cross platform, of course.
[Update] I am looking for something that will work with PyCharm
This is the most portable solution. A more difficult one is sketched below for PyCharm.
Kind of depends on the debugger, but if you use pdb (which would be cross platform), the docs state:
The typical usage to break into the debugger from a running program is
to insert
import pdb; pdb.set_trace()
you want this to be conditional, so you can paste at each breakpoint:
try: pdb.set_trace()
except NameError: pass
and when you want to debug just import pdb at the top. If it must be one line you cannot use duck typing. Instead:
if 'pdb' in globals(): pdb.set_trace()
PyCharm only
Assuming you insist on not marking debugging lines with the mouse this might work:
Using exception breakpoints:
PyCharm provides exception breakpoints for Python, Django, and
JavaScript.
Exception breakpoints are triggered when the specified exception is
thrown. Unlike the line breakpoints, which require specific source
references, exception breakpoints apply globally to the exception
condition, rather than to a particular code reference.
Depending on the type of processing an exception, the debugging can
break when a process terminates with an exception, or as soon as an
exception occurs.
You could:
Create a custom exception in your project, DebugException
Set the exception breakpoint as per the link above. Make sure it is set to trigger immediately, not when program exits.
Finally,
paste
try: raise DebugException()
Exception: pass
wherever you want to break. This seems like a lot of trouble to not double click with your mouse to mark a breakpoint.
In my project that based on asyncio and asyncio tcp connections that debugs with PyCharm debugger I got very and very very absurd errors.
If I put breakpoint on code after running, the breakpoint never fires.
But breakpoints fires if breakpoint has been put before starting program.
But in some cases the firing on breakpoints causes strange errors (if paused on breakpoint and resumed).
The next exceptions I remarked:
TypeError: 'coroutine' object not callable
SystemError: unknown opcode
First exception is very rare. Can be raised in any place on code and unrepeatable.
Second exception I remarked the first time recently. This is repeatable in my code. The function where I put breakpoint is function in async task (asyncio.Task). I can't repeat from scratch. But I think the type of exception (unknown opcode??? O_O) should make you think.
Besides! The exception vanished if I change the code: for example I added the a = 0 line. Exception not raised after. The deleting a = 0 will return this exception again.
Is this error of kind of esoteric errors?
I think the PyCharm debugger conflicts with asnycio.
Or maybe I doing something wrong?
Unknown opcode can be any line of code in the function where breakpoint put. Repeats in specific places in code.
This exception also can be at line, but also inside another function. Very rare and unreproducible
which version of python you use? There is new debugger for python3.6 based on inserting opcodes before starting process. You can find some more info in this repo https://github.com/Elizaveta239/frame-eval
Is there a command in the Python debugger (pdb) that says something like "run until the next exception is raised?"
Seems an obvious requirement but can't seem to find it.
Update : To be clear, my problem is an exception which is being caught and turned into an inadequate message in a log file. And I can't find where the exception is raised.
I figured that if I could go into trace mode and say "run until an exception is thrown" that would be the most straightforward way of finding it. I don't think post-mortem will work here.
Execute your script as follows:
python -m pdb myscript.py
Press c and Enter.
When an uncaught exception is raised you program will stop running and fall back to the pdb debug prompt.
Can you search the code in the failing script for the text of the message that is logged (I realize that this may be difficult if the string is generated in a complex way). If you can find the point where the message is generated/logged then you can set an appropriate break point to troubleshoot the problem.
Unfortunately, AFAIK Python pdb debugging does not offer the capability that is present in some other languages to say, for example, break when Exception is raised.
I had a program developed in Python (2.7 & 3.2) that reads three files and generates some code based on those files. In the code, I had several input file checks to capture any input errors by the user. If the program catches an input error, I used os.sys.exit() command to stop processing and issue an error message. I was primarily using IDLE for the process and this worked fine.
Now I have developed a GUI for the program for deployment using PYQT4. The user uses the GUI to input all the necessary input files and conditions and then the GUI calls the earlier code I generated with the necessary arguments.
However, I am finding that if the user makes an error in the input files, when the earlier code catches those errors and the os.sys.exit() is executed, the GUI itself is shutdown completely; which is not good.
I introduced the same checks on the input files into the GUI, so if those are caught, they are treated within the GUI and not by the code. But there are certain processing checks that happen inside the code that the GUI does not have access to them.
The Question: Is there a way to make the called code stop from running, print an error message (to a log file for example; which I already use) without causing the GUI to quit altogether?
Thanks,
note: The code is too large at this point for me to integrate it into the GUI as a class.
I assume you can not or prefer not to change your CLI programs and instead wish to catch the exception raised by sys.exit instead in the GUI. Here is how:
import os
try:
os.sys.exit()
except SystemExit as err:
print('Caught ya')
Have you tried handling exceptions in python.
try:
#some code here
except Exception:
print 'Something bad happened'
Better try catching specific exceptions.
List of built-in exceptions http://docs.python.org/library/exceptions.html#bltin-exceptions
as an alternative to using pdb, I would have a use for the Python continue statement in interactive mode, after control-C during a script invocation with python -i. that way, say at a raw_input('continue->') prompt in my script, I could break out, inspect/modify things, and go right back to the raw_input prompt (or whatever code caused an exception) with a continue command. the break command outside of a loop could also be repurposed for symmetry, but I'd have less use for that. before submitting a PEP for this, I'd like some feedback from the Python community.
it might be possible to do something similar just using a PYTHONSTARTUP script and the inspect module, but if so I haven't figured it out yet.
ctrl-C raised a KeyboardInterrupt exception in your script. Since you didn't catch that exception, the program terminated. Only then the interactive prompt appears.
You can't continue because your program is already over. The fact that you pressed Ctrl-C just raised an exception, the program didn't pause at that exact place. It continued execution, up to the last line, and finished.
There's no way to know where you want to continue to. For that you need a real debugger.