I'm using python.el
If I choose 'debugger' from the menu, and enter 'python -m pdb myfile.py', gud starts, and in a split frame I see the (Pdb) prompt in one, and my python code in the other with a caret on the first line, indicating that it's ready to go. For example 'n' steps to the next line and the caret moves accordingly.
If instead I enter 'python -m ipdb myfile.py', the frame splits, and one split is labeled gud, but there's no ipdb console evident. In other words, this way of starting ipdb doesn't seem to work. Ipdb works just fine if I manually insert a breakpoint into my python code using ipdb.set_trace(), except that it does not use the gud interface. Is this intentional so that ipdb's stack trace will work nicely?
If so, that's fine, but is there a way to start ipdb from emacs without manually adding a set_trace() command?
The basic problem here is that gud is looking for a (Pdb) prompt and ipdb doesn't prompt this way. There are three ways to fix this: fix ipdb to give a (Pdb) prompt, fix gud not to need to look for (Pdb) or (my favorite) use something else either on the gud side or on the ipdb side.
The problem with fixing up gud is that it is rather old and to my mind a bit creaky using global variables and not making use of Emacs Lisp data structures available other than lists and cons cells. A total rewrite of gud is called realgud, it is currently in MELPA and ELPA. And ipdb is supported.
The last option is to use something else, so let me suggest the Python trepan debugger which is already integrated into realgud (but not gud since I consider that a dead end). Although the backtraces it gives are not exactly like ipdb's, it does colorize them and the source code.
And recent versions of trepan3k backtraces will even show, on demand, you where in the line you are. So if you had say two calls of a function, like fib() it would distinguish which of the calls function was the one in progress.
Related
In a gdb python script, how do I set or modify the commands list for a breakpoint?
I can do this trivially by hand. For example to change the commands list for breakpoint 2, at the prompt I can enter:
(gdb) commands 2
Type commands for breakpoint(s) 2, one per line.
End with a line saying just "end".
>info reg rax
>set $rax=0x1234
>end
Yet, from a gdb python script I cannot seem to execute a multiline command.
gdb.execute("commands 2\ninfo reg rax\nset $rax=0x1234\nend\n")
Just gets me an output like
(gdb) source blah.py
>
and it is sitting there for more input. It won't move on until I type end and press enter. Then it just gives complaints making it clear it has not correctly parsed anything after the commands 2 of that string.
Trying to input each line separately doesn't help. For example the script:
gdb.execute("commands 2")
gdb.execute("info reg rax")
gdb.execute("set $rax=0x1234")
gdb.execute("end")
waits for more input from the user during the first execute, and so has similar problems. And while mostly wishful, the following doesn't work either:
gdb.execute(["commands 2","info reg rax","set $rax=0x1234","end"])
It is easy to programatically get the list of breakpoints with gdb.breakpoints(). And these objects have a property commands, which I can see any commands I set by hand or from a native gdb script. However if I try to modify this property, it fails. So once something is set by hand, or a gdb script, there appears to be no way for a python script to edit it. The API document is missing a lot of helpful information, but it does state https://sourceware.org/gdb/onlinedocs/gdb/Breakpoints-In-Python.html#Breakpoints-In-Python Variable: Breakpoint.commands ... This attribute is not writable.
And no, I don't consider it a useful answer to "never use gdb scripts" or "never enter commands by hand" and "instead always write a python gdb.Breakpoint subclass with Breakpoint.stop() set to do something special, and rewrite all existing scripts to use such features". I can only seem to find information for that workaround. But I'm not willing to give up current methods of interaction just due to a gdb quirk.
Since I can easily run commands to do what I want by hand, there must be a way to modify or set the breakpoint commands from a gdb python script. How do I do this?
I don't think there is a way at present.
As you found, gdb.execute doesn't support multiple lines. This is just a limitation in the Python layer that nobody ever fixed. (I didn't see a bug for it so I filed bug 22730.
Also, a breakpoint's commands field is not assignable. I filed bug 22731 for this.
Your source idea, while horrible, would work fine.
I am entirely new to this (this website as well as programming), so this is probably horribly worded. I should also note that I am using python on an RPi2 so I can't paste anything. The problem is that python ignores the assignment operator when I type it into the editor, but understands it when typed into the shell. For example, if I type
x = 5
x
into the shell, the shell will respond with
5
Whereas if I type the same thing into the editor window and run the module, the shell responds with the nothing, just the restart bar and then the three arrows.
==========RESTART==========
.>>>
I can't find any information on this and I never encountered this problem using python on my desktop.
When you just type x in your program, you basically do nothing. If you want to print it, use print x to explicitly tell python to print it. Note that having a plain x in your module would be a valid python statement (though if you were using pyflakes or pylint or other some such tool, it would cry out loud that you are not doing anything in that statement).
In the shell, this typing x works simply because it is the shell which supports this, it is the shell's feature.
I just noticed an odd behavior when using l (i.e. the list command) in ipdb. I think I have seen something similar with the Perl debugger in the past, but it still puzzles me.
The first time I inoke it shows corerectly ~10 lines of code around the current step (breakpoint). However, if I press it repeatedly, it does not show code around the current location anymore, but instead it shows code that comes below it.
Eventually list shows the final lines of the script, and if I press l again it doesn't show anything anymore.
Why is this, and how can I have it behave consistently as the first time I invoke it?
Many command line debuggers behave that way. (pdb, gdb, ipdb ...).
If you want display current line again, specify the line number.
l 42
If you don't know the current line number, issue where command.
The reason several list commands in most debuggers show different lines is for the simple reason that it doesn't make a lot of sense to show the same source code lines over and over. Presumably you can scroll back to see what you saw before.
That said, let me say that if you are willing to use the trepan debugger, it does have the ability to show the same source code lines for where you are currently stopped using "list .". To see lines before the last list, use "list -".
You can also set how many lines you want to list by default using "set listsize".
This command in pdb always shows the source text around the debugger's current line
(pdb) l .
I'm using PDB a lot and it seems it would be even better if I could add systax highlighting in color.
Ideally, I'd like to have to the path to the code a lighter color.
The line of actual code would be syntax highlighted.
I'm using OS X and the Terminal app.
Python 2.7
pdb doesn't support colorization. However, it's not that hard to get it, even if you're a command-line addict (as I am;-) -- you don't have to switch to GUIs/IDEs just to get colorization while debugging Python. In particular, command-line tools usually work much better when you're accessing a remote machine via SSH, saving a lot of the bandwidth and latency issues that any remote access to GUIs and IDEs can inflict on you;-).
Specifically, for the task you're asking about, consider ipdb (you also need ipython, which offers a far more advanced shell than plain interactive Python, on which ipdb relies). Both offer you good tab completion, enhanced tracebacks, and colorization -- ipython for your normal interactive work, ipdb with the same features when you're debugging (otherwise just about the same as pdb).
You could try pudb, which works in the terminal and looks like this:
I haven't tried some of the options mentioned in other answers, but to judge from the PyPI pages, pudb is better maintained and better documented.
Take a look at pdb++ - it is a drop-in replacement for pdb that fills all your requirements and adds some other nice features such as tab completion and new commands such as watch and sticky.
Here is a sample config file that will enable colours (add this after creating the file: touch ~/.pdbrc.py):
import pdb
class Config(pdb.DefaultConfig):
use_pygments = True
pygments_formatter_class = "pygments.formatters.TerminalTrueColorFormatter"
pygments_formatter_kwargs = {"style": "monokai"}
This might not possible for you, but have you tried using a graphical debugger (like the one in eclipse/pydev)? It will give you your syntax highlighting and much more.
I only use pdb directly if I don't have an option, because a graphical interface is just that much nicer.
In case someone hit the problem with colorization in a console.
My console had white background while ipdb was also adding rather light colors to syntax (for example variables were white). Pressing man ipython shows that we have 3 colors available: 'nocolor', 'linux', 'LightBG'. Ipdb was in my case installed via easy_install into my virtualenv. So it was trivial to look into ipdb source and modify it (hint search for ipdb/init.py in your env). Then I've modified following:
def set_trace():
ip = ipapi.get()
+ def_colors = ip.options.colors
+ def_colors = 'LightBG'
Pdb(def_colors).set_trace(sys._getframe().f_back)
It's a kinda hackish solution but well its for debugging purpose on my working station so its sufficient. But if anyone finds something better. Please send me a message on what to do.
When I am working with a Python Interpreter, I always find it a pain to try and copy code from it because it inserts all of these >>> and ...
Is there a Python interpreter that will let me copy code, without having to deal with this? Or alternatively, is there a way to clean the output.
Additionally, sometimes I would like to paste code in, but the code is indented. Is there any console that can automatically indent it instead of throwing an error?
Related
Why can I not paste the output of Pythons REPL without manual-editing?
IPython lets you show, save and edit your command history, for example to show the first three commands of your session without line numbers you'd type %hist -n 1 4.
WingIDE from Wingware will let you evaluate any chunk of code in a separate interpreter window.
IPython will let you paste Python code with leading indents without giving you an IndentationError. You can also change your prompts to remove >>> and ... if you wish.
I have a vim macro to "paste while cleaning interpreter prompts and sample output [[==stuff NOT preceded by prompts" and I'll be happy to share it if vim is what you're using. Any editor or IDE worth that name will of course be similarly easy to program for such purposes!
Decent text editors such as Notepad++ can make global search and replace operations that can replace >>> with nothing.