vim and python scripts debugging - python

Are there any ways to debug python scripts not leaving vim in *nix systems (executing the script, setting up breakpoints, showing variables in watch-list, etc)?

Use pdb:
import pdb
def main():
list = [1,2,3]
pdb.set_trace()
list = [2,3,4]
if __name__ == '__main__':
main()
Now run using :!python % and you'll hit your breakpoint and be able to debug interactively like in gdb.

As of Python 3.7, you can use breakpoint() builtin without importing anything.
Built-in breakpoint() calls sys.breakpointhook(). By default, the latter imports pdb and then calls pdb.set_trace()
Inheriting code from Pierre-Antoine's answer, the code would look like this:
def main():
list = [1,2,3]
breakpoint()
list = [2,3,4]
if __name__ == '__main__':
main()
Source: https://docs.python.org/3/whatsnew/3.7.html#pep-553-built-in-breakpoint

Try pyclewn. It allows to use vim as front end for pdb. You can create/delete break points, control flow of debugging process, look at values of your variables. All from vim!

Also try https://pypi.python.org/pypi/pudb - its like pdb but more advanced. Contains code highlighting, stack, showing avaliable values, etc. Not only-vim solution but for me works perfectly.
Three Steps:
Install:
pip install pudb
Paste set_trace in code
from pudb import set_trace; set_trace()
Run your code

As 2020 the Debugger Adapter Protocol is taken care by vimspector.
Supporting Cpp, Python, Java, Js, Go ...
See my other answer

The vimpdb plugin integrates the Python debugger pdb into the VIM editor.
I do recommend it.
Hope it helps.

Vim and pdb-clone is the combination I use. I use Home - pyclewn which provides a replacement for pdb called pdb-clone that is quite faster than vanilla pdb. It integrates well with vim via a plugin, and the thing I appreciate most is that it takes care of breakpoints outside the code, not setting traces within, thus not messing up my line numbers. It does not have a watch window for python yet. You might have a look at vim-debug too, which I could not get to work with my existing highlighting setup.

See the "Debugging" section in this blog post. It shows how to setup F7 to set breakpoints and Shift+F7 to remove breakpoints. It also uses pdb, as mentioned before. With a little modification, you can replace the use of pdb with ipdb (pdb using ipython), which is a lot nicer to use.

It sounds like you want to use VIM as a Python IDE.
A quick Google search found this and this example, with many more.
EDIT: Well, Ok, it seems likely you've searched more than I have.
I hope someone else has some ideas.

From what I know, there is one more option: You could use Eclipse + PyDev for project managing and Vim as an editor for Eclipse. That way You could use the best of both worlds.
Also, I haven't tried it, but You could try this script.

Related

Is there break function in python (for PyCharm or other IDE)?

There is __debugbreak function in C++.
I need to use similar function that breaks run-time with resume possibility in my Python code (with PyCharm IDE).
There's the pdb (and ipdb) module which provide interactive debuggers.
You can use
import pdb; pdb.set_trace()
to insert a breakpoint wherever you want.
I'm not sure how these will work with PyCharm (for which you should just be able to click to add a breakpoint anyway) but the literal answer to your question is "yes".
Using ipdb from the command line is a very easy way to debug your Python code.
See https://docs.python.org/2.7/library/pdb.html

ipdb doesn't work in vim console

ipdb works fine in the shell, but I want to debug under vim, after I set ipdb.set_trace(), and then !python %,
the console below gives me this messy prompt, any idea?
I guess you are using a GUI Vim. GVim? MacVim? The pseudo terminal you get when executing external tools is not, has never been and will probably never be able to understand the escape characters you see. That means no color and no ncurses-style widgets.
You'd better run it in a separate terminal or find a way to disable colors in iPython.
If you don’t really want to patch vim as well as run in a separate terminal as #romainl suggests then there is Conque plugin which provides a way to have colored pseudo-terminal in a vim buffer. You have to run
ConqueTerm(|[V]Split|Tab) sh
and within it run
python path/to/file.py
(no % is possible) though. It can be narrowed down to a mapping:
nnoremap <expr> ,p ":\<C-u>ConqueTermVSplit sh\n\<C-o>:call feedkeys('python '.shellescape(bufname(".bufnr("%").")).\"\\n\")\n"
I have created my own workaround for this which may be valuable to you depending on how you use ipdb. The idea is that you can pass in no_colors=True to set_trace() and that way the interactive debugger will not produce any colour output. I have also enabled this argument for launch_ipdb_on_exception.
This means that you can do:
import ipdb
ipdb.set_trace(no_colors=True)
And the output looks fine in MacVim.
To use this you will have to use my version of ipdb, which is here, actual relevant commit if you want to see what I did is here.
It turns out that ipdb is merely a convient way of accessing ipython.core.debugger, Pdb the actual debugger is defined there.
For windows users i suggest ConEmu. Works perfectly with ipdb (highlighting, auto-complete, ...)

Emacs: methods for debugging python

I use emacs for all my code edit needs. Typically, I will use M-x compile to run my test runner which I would say gets me about 70% of what I need to do to keep the code on track however lately I've been wondering how it might be possible to use M-x pdb on occasions where it would be nice to hit a breakpoint and inspect things.
In my googling I've found some things that suggest that this is useful/possible. However I have not managed to get it working in a way that I fully understand.
I don't know if it's the combination of buildout + appengine that might be making it more difficult but when I try to do something like
M-x pdb
Run pdb (like this): /Users/twillis/projects/hydrant/bin/python /Users/twillis/bin/pdb /Users/twillis/projects/hydrant/bin/devappserver /Users/twillis/projects/hydrant/parts/hydrant-app/
Where .../bin/python is the interpreter buildout makes with the path set for all the eggs.
~/bin/pdb is a simple script to call into pdb.main using the current python interpreter
HellooKitty:hydrant twillis$ cat ~/bin/pdb
#! /usr/bin/env python
if __name__ == "__main__":
import sys
sys.version_info
import pdb
pdb.main()
HellooKitty:hydrant twillis$
.../bin/devappserver is the dev_appserver script that the buildout recipe makes for gae project and .../parts/hydrant-app is the path to the app.yaml
I am first presented with a prompt
Current directory is /Users/twillis/bin/
C-c C-f
Nothing happens but
HellooKitty:hydrant twillis$ ps aux | grep pdb
twillis 469 100.0 1.6 168488 67188 s002 Rs+ 1:03PM 0:52.19 /usr/local/bin/python2.5 /Users/twillis/projects/hydrant/bin/python /Users/twillis/bin/pdb /Users/twillis/projects/hydrant/bin/devappserver /Users/twillis/projects/hydrant/parts/hydrant-app/
twillis 477 0.0 0.0 2435120 420 s000 R+ 1:05PM 0:00.00 grep pdb
HellooKitty:hydrant twillis$
something is happening
C-x [space]
will report that a breakpoint has been set. But I can't manage to get get things going.
It feels like I am missing something obvious here. Am I?
So, is interactive debugging in emacs worthwhile? is interactive debugging a google appengine app possible? Any suggestions on how I might get this working?
Hmm. You're doing this a little differently than I do. I haven't experimented with your method. I use the pdb library module directly, with no wrapper script, just using the "-m" python command-line option to tell python to run the module as a script.
To be excessively thorough, here's my sequence of operations:
I hit Alt-X in EMACS, type "pdb", then return.
EMACS prompts me with "Run pdb (like this):" and I type "python -m pdb myprogram.py".
EMACS creates a debugger mode window for pdb, where I can give the debugger commands, and tracks the execution of the program in the source code.
I suppose it's possible there's some reason this doesn't work well with the appengine. I recommend getting it working first with a trivial python program and once you know that's working, try stepping up to the full app.
In practice, I don't do much python debugging with pdb. Most of my debugging is essentially "printf debugging", done inserting print statements into my unit tests and (occasionally) into the actual code.

How to pause python execution in eclipse and return to an interactive prompt

I am using Eclipse as a Python IDE. Is there anyway for me to Debug my program and break to an interactive prompt. I am interested in exploring the existing data and running/testing commands.
I believe there has to be a way, but I am so used to compiling languages that I have not been able to find where the options are.
Any ideas?
You can easily do that by using PDB (Python Debugger) inside a python shell.
Look at http://docs.python.org/library/pdb.html for more info.
Anyway I believe Eclipse will let you inspect you data when setting a breakpoint.

Is it possible to tell a python script to stop at some point and give you the hand interactively, for example with ipython?

Suppose I have a script that does a lot of stuff, and doesn't work well somewhere near the end. I'd love to be able to add a start_ipython() function at that point, which would stop the script at this point, and let me inspect variables and so on with ipython. How can I do this?
Note that this has changed in IPython-0.11. Instead of what is described below, simply use the following import:
from IPython import embed as shell
The answer below works for IPython versions prior to 0.11.
In the region where you want to drop into ipython, define this
def start_ipython():
from IPython.Shell import IPShellEmbed
shell = IPShellEmbed()
shell()
and call start_ipython where you want to drop into the interpreter.
This will drop you into an interpreter and will preserve the locals() at that point.
If you want a regular shell, do this
def start_python():
import code
code.interact()
Check the documentation for the above functions for details. I'd recommend that you try the ipython one and if it throws an ImportError, switch to normal so that it will work even if ipython is not installed.
Easiest way is to use the built-in debugger. At the point you want execution to stop, just do:
import pdb; pdb.set_trace()
and you'll be dumped into the pdb shell, which allows you to inspect variables and change them.
There is also an external ipdb package which you can get via easy_install which should work the same way.

Categories