How to use python's gevent.monkey.path_sys() with ipdb debugger? - python

I am using python's gevent library and do not want raw_input (or more specifically the event loop in cmd.Cmd) to block when awaiting user input. So as a result I use gevent.monkey.patch_sys() to ensure that my other greenlets may run when waiting for user input. Works great except that it seems to interact with readline.
For example, I no longer have history and auto-complete in ipython's ipdb debugger since the arrow keys no longer work. This can be seen with this simple snippet:
from gevent import monkey
monkey.patch_sys()
import ipdb; ipdb.set_trace()
# now hit arrow keys at the prompt
I get the following:
ipdb> ^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A
*** SyntaxError: invalid syntax (<stdin>, line 1)
I have traced it to what I think could be an issue with python's readline as I know that ipython depends on it.
Also this appears to be a similar situation:
https://github.com/gevent/gevent/issues/6
but in my case I want to specifically use auto completion and history in the debugger.
I am running on OSX within iterm. Is this something specific to a console setting? Or is something in the patch fundamentally breaking readline?
Any ideas on how to resolve?

Related

How do you debug pydoit?

I have a python doit script that is getting stuck on one step but doesn't throw an error. It would sit all day if I let it. I've checked all the inputs and they look exactly the same as the last time I ran it. How do I debug? I tried using pdb but maybe I don't know how to use it and I googled and couldn't find example code. I can't post my code since its confidential. Just a general how to debug in doit would help me greatly. I use Python 2.7 and yes eventually I'll have to update to 3 but for now I'm using 2.7. (Sorry I have had quite a few ask why I continue with 2.7--- no time right now to update all my scripts, there are over 200)
https://pydoit.org/tools.html#set-trace
doit provides a set_trace() function that will call PDB set_trace and make sure stdout output is printed on terminal.
Not your case, but doit also provides a command line option --pdb that automatically drops in PDB when an unhandled exception occurs.

Use of Breakpoint Method

I am new to python and am unsure of how the breakpoint method works. Does it open the debugger for the IDE or some built-in debugger?
Additionally, I was wondering how that debugger would be able to be operated.
For example, I use Spyder, does that mean that if I use the breakpoint() method, Spyder's debugger will open, through which I could the Debugger dropdown menu, or would some other debugger open?
I would also like to know how this function works in conjunction with the breakpointhook() method.
No, debugger will not open itself automatically as a consequence of setting a breakpoint.
So you have first set a breakpoint (or more of them), and then manually launch a debugger.
After this, the debugger will perform your code as usually, but will stop performing instructions when it reaches a breakpoint - the instruction at the breakpoint itself it will not perform. It will pause just before it, given you an opportunity to perform some debug tasks, as
inspect variable values,
set variables manually to other values,
continue performing instructions step by step (i. e. only the next instruction),
continue performing instructions to the next breakpoint,
prematurely stop debugging your program.
This is the common scenario for all debuggers of all programming languages (and their IDEs).
For IDEs, launching a debugger will
enable or reveal debugging instructions in their menu system,
show a toolbar for them and will,
enable hot keys for them.
Without setting at least one breakpoint, most debuggers perform the whole program without a pause (as launching it without a debugger), so you will have no opportunity to perform any debugging task.
(Some IDEs have an option to launch a debugger in the "first instruction, then a pause" mode, so you need not set breakpoints in advance in this case.)
Yes, the breakpoint() built-in function (introduced in Python 3.7) stops executing your program, enters it in the debugging mode, and you may use Spyder's debugger drop-down menu.
(It isn't a Spyders' debugger, only its drop-down menu; the used debugger will be still the pdb, i. e. the default Python DeBugger.)
The connection between the breakpoint() built-in function and the breakpointhook() function (from the sys built-in module) is very straightforward - the first one directly calls the second one.
The natural question is why we need two functions with the exactly same behavior?
The answer is in the design - the breakpoint() function may be changed indirectly, by changing the behavior of the breakpointhook() function.
For example, IDE creators may change the behavior of the breakpointhook() function so that it will launch their own debugger, not the pdb one.
The default behavior of the breakpoint() builtin is to open the pdb debugger at that point.
That is, by default the line
breakpoint()
Should behave identically to
import pdb; pdb.set_trace()
The behavior can be customized (e.g. to open a different debugger) by modifying sys.breakpointhook. Generally the only time you would do this is if you were implementing a debugger or something that functioned like a debugger. If you're running code from an IDE, the IDE itself should modify sys.breakpointhook so that it opens the IDE debugger. (I don't know if all Python IDEs actually do this, but they should.)
For more information, including the rationale of why this function was added, see the PEP 553 proposal. The actual implementation was landed into Python 3.7.

stopping execution of Python program on exception in ipython

I have a long running Python program that raises exception at some point. Is there some way to run this from ipython session and stop on the exception so I could examine the live data?
You may want ipython -i yourscript.py, which will execute your script in the interpreter environment. But this won't let you inspect the local environment where the exception happened, for example local variables within a function – you'll just be able to inspect globals. You probably want this instead:
In [1]: %run test.py
<exception occurs>
In [2]: %debug test.py
If you're not familiar with using PDB, check out some docs first.
Edit thanks to Thomas K
yes, depending on how you are setup. you can import your program and run it like any other module inside a try except block.
import yourprogram
try:
yourprogram.main_function(args)
except:
print "we blew up, investigate why"
If your program is not in a function you may need to put the try block around your import.
The problem with this approach is that the variables you are wanting to look at may be no longer in scope. I usually use print statements or log messages at various points to figure out what is not looking like I am expecting.

Python script drops into pdb without reason

I have a python function that I'm calling from inside an iPython session.
In a very specific situation, in which a conditional in a certain line comes out as True, the script consistently drops into a pdb debug mode.
There is no trace or any other indication of a problem with the code, and as soon as I type c to continue, the code continues perfectly well.
The script doesn't include any import pdb not to mention a set_trace()...
Any ideas what could account for this?
Depending on your ipython config it automatically goes into PDB if an exception is raised.
Seems like there was a import pdb; pdb.set_trace() line in the code after all, which I missed due to source control issues.

Using a debugger and curses at the same time?

I'm calling python -m pdb myapp.py, when an exception fires, and I'd normally be thrown back to the pdb interpreter to investigate the problem. However this exception is being thrown after I've called through curses.wrapper() and entered curses mode, rendering the pdb interpreter useless. How can I work around this?
James` answer is a good and I've upvoted it but I'd also consider trying to split the logic and presentation layers of my program. Keep the curses part a thin layer on top of a library and write a simple driver that invokes the correct routines to recreate the error. Then you can dive in and do what's necessary.
Another way I can think of is to create a function called debug or something that throws you back into the regular screen and invokes pdb. Then stick it just before the code that raises the exception and run your program. Something like
def debug(stdscr):
curses.nocbreak()
stdscr.keypad(0)
curses.echo()
curses.endwin()
import pdb; pdb.set_trace()
Apparently, this is similar to what is done with the curses.wrapper function. It's mentioned briefly at http://www.amk.ca/python/howto/curses/.
Not being familiar with Python, this may not be exactly what you want. But apparently, winpdb can attach to a script - just like gdb can to a running process (IIUC).
http://winpdb.org/docs/launch-time/
Don't be mislead by the name, it is platform independent.
use pyclewn
you can use pyclewn with vim.
or use pdb-clone,the core of pyclewn
its good ,its like gdb ,can remote debug

Categories