Full-screen console debugger for Python

Overview

PuDB: a console-based visual debugger for Python

Gitlab Build Status Github Build Status Python Package Index Release Page

Its goal is to provide all the niceties of modern GUI-based debuggers in a more lightweight and keyboard-friendly package. PuDB allows you to debug code right where you write and test it--in a terminal. If you've worked with the excellent (but nowadays ancient) DOS-based Turbo Pascal or C tools, PuDB's UI might look familiar.

Here's a screenshot:

https://tiker.net/pub/pudb-screenshot.png

You may watch a screencast, too.

Features

  • Syntax-highlighted source, the stack, breakpoints and variables are all visible at once and continuously updated. This helps you be more aware of what's going on in your program. Variable displays can be expanded, collapsed and have various customization options.
  • Simple, keyboard-based navigation using single keystrokes makes debugging quick and easy. PuDB understands cursor-keys and Vi shortcuts for navigation. Other keys are inspired by the corresponding pdb commands.
  • Use search to find relevant source code, or use "m" to invoke the module browser that shows loaded modules, lets you load new ones and reload existing ones.
  • Breakpoints can be set just by pointing at a source line and hitting "b" and then edited visually in the breakpoints window. Or hit "t" to run to the line under the cursor.
  • Drop to a Python shell in the current environment by pressing "!". Or open a command prompt alongside the source-code via "Ctrl-X".
  • PuDB places special emphasis on exception handling. A post-mortem mode makes it easy to retrace a crashing program's last steps.
  • Ability to control the debugger from a separate terminal.
  • IPython integration (see wiki)
  • Should work with Python 3.6 and newer. (Versions 2019.2 and older continue to support Python 2.7.)

Links

PuDB documentation

PuDB also has a mailing list that you may use to submit patches and requests for help. You can also send a pull request to the GitHub repository

Development Version

You may obtain the development version using the Git version control tool.:

git clone https://github.com/inducer/pudb.git

You may also browse the code online.

Comments
  • Ctrl-x not function to leave console

    Ctrl-x not function to leave console

    When attempting to make local calls in the console, pressing ctrl-x merely prints ^x rather than leaving the console. At this point, the only way out is to kill pudb. An interesting behavior is that this only happens after issuing a command in the console; ctrl-x works fine until then.

    Details: pudb version: 2015.4.1 installed with pip running in osx 10.11.2 in iTerm2, Terminal, and Neovim's terminal mode

    opened by ghost 58
  • A way to un-breakpoint a set_trace() line

    A way to un-breakpoint a set_trace() line

    This sounds kind of odd, let me explain. I usually enter the debugger with an explicit call to set_trace(). Often, once I've hit that line a few times, I no longer need to stop there, but I don't want to restart the process.

    Just as I can manually turn a regular line into a breakpoint with the 'b' command, I would love a way to turn a set_trace() line back into a regular, non-breaking line. The set_trace function would still be called of course, but could examine the calling line to see if it had been marked as non-breaking, and continue.

    enhancement 
    opened by nedbat 33
  • Add set_continue() function to __init__.py

    Add set_continue() function to __init__.py

    This lets you start the debugger and immediately continue, i.e., it only stops on a previously defined breakpoint.

    Fixes #234.

    Let me know if you would prefer a better name, or just a flag to set_trace().

    opened by asmeurer 22
  • Two New Features

    Two New Features

    Hey there. Here are two features I've wanted for a little while (sorry, probably should have put them in separate branches but they're small and you should be able to cherry pick if you don't want both).

    One of them adds support for bpython-urwid (I think maybe I'll experiment later with getting this to run inside pudb's mainloop, since that can open up some possibilities).

    The other adds support for specifying an arbitrary expression to use as the stringifier for each variable.

    opened by Julian 22
  • Problems when setting breakpoints

    Problems when setting breakpoints

    When I try to set a breakpoin, I get the errormessage: The breakpoint you just set may be invalid, for the following reason: File failed to compile.

    I can set breakpoint with Set Anyway. After some debugging, the breakpoint(s) disappear.

    Version of pudb is 2017.1, python 2.7.12+ and Ubuntu 16.10.

    Eivind

    opened by enmy211 21
  • running set_trace() multiple times displays stdlib bdb.py

    running set_trace() multiple times displays stdlib bdb.py

    Reproduction steps:

    1. Save below script as foobar.py
    2. python foobar.py foo bar
    3. You'll break at function foo
    4. Defined a breakpoint at foobar.py:11 (the first line of main(): for arg in argv:)
    5. c
    6. You'll be brought to line 11
    7. c
    8. You'll be brought to /usr/lib/python2.6/bdb.py at _ste_stopinfo(), and also see that you now have two breakpoints at foobar.py:11
    9. Pressing s fourteen times eventually brings you to the correct breakpoint in bar()

    The expected behavior is to not display bdb.py, and not create duplicate breakpoints.

    Obviously there are other ways to accomplish the desired debugging session, but in a large, complex code base, it is sometimes extremely convenient to have multiple set_trace lines, which may or may not cause set_trace to be called twice.

    If you can tell me how to induce this error automatically, I can write a unit test for it, at minimum, and likely produce a patch for the bug as well.

    # Script: foobar.py
    def foo():
        import pudb; pudb.set_trace()
        print 'foo'
    
    def bar():
        import pudb; pudb.set_trace()
        print 'bar'
    
    def main(argv):
        for arg in argv:
            if arg == 'foo':
                foo()
            elif arg == 'bar':
                bar()
    
    import sys
    main(sys.argv)
    
    Bug 
    opened by bukzor 20
  • don't provoke undefined signal handling

    don't provoke undefined signal handling

    mod_wsgi installs a non-default signal handler for SIGINT.

    The current behavior of pudb utterly clobbers this signal handler and causes undefined behavior (in practice, the process becomes impossible to kill with SIGINT).

    Until pudb has better support for non-default signal handlers in the process-under-test, I've added this small amount of code to detect the situation, throw a warning, and continue without interrupt support.

    The new warning looks like this under apache.

    [Mon Jun 10 18:44:30 2013] [error] /home/buck/trees/theirs/pudb/pudb/__init__.py:166: UserWarning: A non-default handler for signal 2 is already installed (not installed from python). Skipping pudb interrupt support.
    [Mon Jun 10 18:44:30 2013] [error]   % (interrupt_signal, old_handler))
    

    Then the process continues to work as well as previous versions of pudb.

    In terms of priority, this is driving everyone that has upgraded pudb completely nuts, and the only recourse is to downgrade.

    opened by bukzor 18
  • Add mouse support and a few changes/fix

    Add mouse support and a few changes/fix

    I know I should have asked when I started adding mouse support. So, I will highlight the changes I have made:

    mouse support

    • add
      • class double_press_input_filter for double click,
      • def listen_mouse_event like def listen, and
      • def mouse_event like def keypress for mouse support.
    • change some event handlers because the argument difference of key event and mouse event, e.g. def move_down(w, size, key) to move_down(w, size, *args). Almost all of those handlers I changed don't use key at all.
    • add some mouse event handler, which are not documented in HELP yet.

    changes

    • change change_rhs_box sizing method, which cause both above and below the selected sidebox resize, which is strange to me. I changed it so it would only affect the box below.
    • add non_post_mortem_only decorator, just try to reduce few lines.

    fix

    • exception when key press on empty variables list.

    It's fine if no one else wants the mouse support; however if it's accepted, but some naming or style/method don't fit into pudb, please let me know I will add additional changes to meet the need.

    The two changes I made, especially first one, might need more input because not everyone likes the sizing method I like as I don't like the current.

    enhancement 
    opened by livibetter 16
  • Fix the midnight theme

    Fix the midnight theme

    This reverts the changes to the midnight theme that were made in #469 and also cleans it up a little bit.

    CC @mvanderkamp I don't know if any of the changes in c7a8fbb0 were actually important.

    opened by asmeurer 15
  • Latest PuDB (2017.1.3) dies with ListBoxError in some cases

    Latest PuDB (2017.1.3) dies with ListBoxError in some cases

    Stacktrace (edited slightly for anonymity):

      File "/usr/lib/python2.7/bdb.py", line 49, in trace_dispatch
        return self.dispatch_line(frame)
      File ".../site-packages/pudb/debugger.py", line 160, in dispatch_line
        self.user_line(frame)
      File ".../site-packages/pudb/debugger.py", line 381, in user_line
        self.interaction(frame)
      File ".../site-packages/pudb/debugger.py", line 349, in interaction
        show_exc_dialog=show_exc_dialog)
      File ".../site-packages/pudb/debugger.py", line 2084, in call_with_ui
        return f(*args, **kwargs)
      File ".../site-packages/pudb/debugger.py", line 2322, in interaction
        self.event_loop()
      File ".../site-packages/pudb/debugger.py", line 2280, in event_loop
        canvas = toplevel.render(self.size, focus=True)
      File ".../site-packages/urwid/widget.py", line 141, in cached_render
        canv = fn(self, size, focus=focus)
      File ".../site-packages/urwid/widget.py", line 1751, in render
        canv = get_delegate(self).render(size, focus=focus)
      File ".../site-packages/urwid/widget.py", line 141, in cached_render
        canv = fn(self, size, focus=focus)
      File ".../site-packages/urwid/container.py", line 1083, in render
        focus and self.focus_part == 'body')
      File ".../site-packages/urwid/widget.py", line 141, in cached_render
        canv = fn(self, size, focus=focus)
      File ".../site-packages/urwid/decoration.py", line 225, in render
        canv = self._original_widget.render(size, focus=focus)
      File ".../site-packages/urwid/widget.py", line 141, in cached_render
        canv = fn(self, size, focus=focus)
      File ".../site-packages/urwid/container.py", line 2085, in render
        focus = focus and self.focus_position == i)
      File ".../site-packages/urwid/widget.py", line 141, in cached_render
        canv = fn(self, size, focus=focus)
      File ".../site-packages/urwid/widget.py", line 1751, in render
        canv = get_delegate(self).render(size, focus=focus)
      File ".../site-packages/urwid/widget.py", line 141, in cached_render
        canv = fn(self, size, focus=focus)
      File ".../site-packages/urwid/container.py", line 1526, in render
        canv = w.render((maxcol, rows), focus=focus and item_focus)
      File ".../site-packages/urwid/widget.py", line 141, in cached_render
        canv = fn(self, size, focus=focus)
      File ".../site-packages/urwid/decoration.py", line 225, in render
        canv = self._original_widget.render(size, focus=focus)
      File ".../site-packages/urwid/widget.py", line 141, in cached_render
        canv = fn(self, size, focus=focus)
      File ".../site-packages/urwid/container.py", line 1526, in render
        canv = w.render((maxcol, rows), focus=focus and item_focus)
      File ".../site-packages/urwid/widget.py", line 141, in cached_render
        canv = fn(self, size, focus=focus)
      File ".../site-packages/urwid/decoration.py", line 225, in render
        canv = self._original_widget.render(size, focus=focus)
      File ".../site-packages/urwid/widget.py", line 141, in cached_render
        canv = fn(self, size, focus=focus)
      File ".../site-packages/urwid/widget.py", line 1751, in render
        canv = get_delegate(self).render(size, focus=focus)
      File ".../site-packages/urwid/widget.py", line 141, in cached_render
        canv = fn(self, size, focus=focus)
      File ".../site-packages/urwid/listbox.py", line 489, in render
        raise ListBoxError, "Widget %r at position %r within listbox calculated %d rows but rendered %d!"% (widget,w_pos,w_rows, canvas.rows())
    ListBoxError: Widget <VariableWidget selectable flow widget> at position 3 within listbox calculated 1 rows but rendered 0!
    

    This happens under Ubuntu 17.04 using Gnome Terminal (pudb is being run inside of a docker container also running Ubuntu 17.04 if it matters). The error goes away when using PuDB 2017.1.2. It also seems to be dependent on the terminal size. For example it happens both with my "maximized" terminal size (158x46) as well as at 132x43, but it does not happen when the terminal is resized to 80x24. My pudb.cfg:

    [pudb]
    breakpoints_weight = 1
    current_stack_frame = top
    custom_shell = 
    custom_stringifier = 
    custom_theme = 
    display = auto
    line_numbers = True
    prompt_on_quit = True
    seen_welcome = e032
    shell = internal
    sidebar_width = 0.5
    stack_weight = 1
    stringifier = type
    theme = classic
    variables_weight = 1
    wrap_variables = True
    

    This is also potentially related to #269

    opened by cdman 14
  • Fix make_canvas for lines with multiple attrs

    Fix make_canvas for lines with multiple attrs

    As I was saying in #174, I was seeing some dangling characters issue. The issue was more severe than that, because I was always using line[i:count] instead of line[i:i+count]. To ensure this two chars fix works I added unit tests. They can be run by using 'py.test' from the root pudb directory.

    opened by pquentin 14
  • default urwid bright-is-bold false

    default urwid bright-is-bold false

    Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

    I've noticed urwid looks strange since I've started using "kitty" terminal. kitty comes with its own custom termaps, and so it's necessary to set TERM=kitty. In urwid, rather than using termap, they use a simple "not xterm" heuristic for their "bright is bold" flag. This results in a random half of all syntax becoming bold.

    https://github.com/urwid/urwid/blob/master/urwid/raw_display.py#L79

    Describe the solution you'd like A clear and concise description of what you want to happen.

    Could we call set_terminal_properties(bright_is_bold=False) during startup? If you want to get fancy we could determine this boolean via termcap (as urwid should have done).

    enhancement 
    opened by bukzor-sentryio 1
  • Allow function definition locals() to be modified in the shell

    Allow function definition locals() to be modified in the shell

    This still requires more testing, especially for the different shells.

    For the IPython shell, this requires not making a copy of locals(), but this also causes the IPython shell to pollute the locals() namespace with all its internal variables (like _0 and so on), so a better fix is needed.

    Fixes #26.

    opened by asmeurer 4
  • pudb, when run on a Python 3.x invoked with -bb, tracebacks

    pudb, when run on a Python 3.x invoked with -bb, tracebacks

    Describe the bug python3 -bb is for finding comparisons between str and bytes. I am using it to assist with porting some old code from CPython 2.7 to CPython 3.10. pudb appears to be doing at least one such comparison that interferes with its operation when used with python3 -bb. That may or may not be intentional.

    The traceback looks like:

    lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
    x                                                          Pudb Internal Exception Encountered                                                         x
    x                                                                                                                                                      x
    xPudb has encountered and safely caught an internal exception.                                                                          < OK          >x
    x                                                                                                                                       < Save        >x
    xThe full traceback and some other information can be found below. Please report this information, along with details on what you were    traceback    x
    xdoing at the time the exception occurred, at: https://github.com/inducer/pudb/issues                                                                  x
    x                                                                                                                                                      x
    xpython version: 3.10.2 (main, Mar  2 2022, 03:29:23) [GCC 10.2.1 20210110]                                                                            x
    xpudb version: 2022.1.2                                                                                                                                x
    xurwid version: 2.1.2                                                                                                                                  x
    xTraceback (most recent call last):                                                                                                                    x
    x  File "/usr/local/lib/python3.10/site-packages/pudb/debugger.py", line 460, in user_line                                                             x
    x    self.interaction(frame)                                                                                                                           x
    x  File "/usr/local/lib/python3.10/site-packages/pudb/debugger.py", line 426, in interaction                                                           x
    x    self.ui.call_with_ui(self.ui.interaction, exc_tuple,                                                                                              x
    x  File "/usr/local/lib/python3.10/site-packages/pudb/debugger.py", line 2428, in call_with_ui                                                         x
    x    self.hide()                                                                                                                                       x
    x  File "/usr/local/lib/python3.10/site-packages/pudb/debugger.py", line 2421, in hide                                                                 x
    x    self.screen.stop()                                                                                                                                x
    x  File "/usr/local/lib/python3.10/site-packages/urwid/display_common.py", line 821, in stop                                                           x
    x    self._stop()                                                                                                                                      x
    x  File "/usr/local/lib/python3.10/site-packages/urwid/raw_display.py", line 275, in _stop                                                             x
    x    self.tty_signal_keys(*(self._old_signal_keys + (fd,)))                                                                                            x
    x  File "/usr/local/lib/python3.10/site-packages/urwid/display_common.py", line 761, in tty_signal_keys                                                x
    x    if intr == 'undefined': intr = 0                                                                                                                  x
    xBytesWarning: Comparison between bytes and string                                                                                                     x
    x                                                                                                                                                      x
    x                                                                                                                                                      x
    x                                                                                                                                                      x
    x                                                                                                                                                      x
    x                                                                                                                                                      x
    x                                                                                                                                                      x
    x                                                                                                                                                      x
    mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj
    

    To Reproduce Steps to reproduce the behavior:

    1. Debug code with python3 -bb and a pudb.set_trace()
    2. Unfortunately, I cannot share the code that is triggering this, but there's a good chance pudb does it frequently

    Expected behavior A debugging session that doesn't give a Pudb Internal Exception.

    Screenshots

    Additional context

    Versions

    What version of pudb? What version of Python? pudb v2022.1.2, CPython 3.10.8.

    Thanks for the great tool!

    Bug 
    opened by dstromberg 1
  • Nord Theme

    Nord Theme

    Is your feature request related to a problem? Please describe.

    I'd like to have a pudb theme similar to this one:

    https://github.com/arcticicestudio/nord-vim https://www.nordtheme.com/ports/tmux https://www.nordtheme.com/

    Describe the solution you'd like

    I'd like to have a nord theme.

    enhancement 
    opened by jgarte 1
  • Customizable breakpoint file location

    Customizable breakpoint file location

    First, love to use pudb daily, thanks :heart:

    Issue

    Currently, breakpoint is saved globally, usually in ~/.config/pudb/saved-breakpoints-3.X.

    But in most use cases, breakpoints are natual to be set by project.

    • Breakpoint set for project A means nothing for project B, and vice versa

    So while debugging for several projects, the breakpoint file is getting bigger and bigger. This is not scalable nor ideal.

    Suggest

    It might be wonderful if there's way to set breakpoint by session. There are plenty of options I can imagine.

    pudb cli option to get breakpoint file from user

    pudb --breakpoint ./my_breakpoint.txt ...
    

    I see #539 suggested to do this for configuration. This suggestion is breakpoint version of #539. I think configuration is mostly global, while breakpoint is natively per project. So getting local breakpoint file from user seems natual.

    Convention for project-wise breakpoint file location to override global setting

    Like .pudb_saved_breakpoint in project root overrides global breakpoint file, if exists.

    pudb cli option to take breakpoint at runtime (#500)

    #500 might be one option (but I prefer getting file as argument)

    enhancement 
    opened by cgbahk 2
Releases(v2022.1.3)
A simple rubber duck debugger

Rubber Duck Debugger I found myself many times asking a question on StackOverflow or to one of my colleagues just for finding the solution simply by d

1 Nov 10, 2021
AryaBota: An app to teach Python coding via gradual programming and visual output

AryaBota An app to teach Python coding, that gradually allows students to transition from using commands similar to natural language, to more Pythonic

5 Feb 08, 2022
Pyinstrument - a Python profiler. A profiler is a tool to help you optimize your code - make it faster.

Pyinstrument🚴 Call stack profiler for Python. Shows you why your code is slow!

Joe Rickerby 5k Jan 08, 2023
EDB 以太坊单合约交易调试工具

EDB 以太坊单合约交易调试工具 Idea 在刷题的时候遇到一类JOP(Jump-Oriented-Programming)的题目,fuzz或者调试这类题目缺少简单易用的工具,由此开发了一个简单的调试工具EDB(The Ethereum Debugger),利用debug_traceTransact

16 May 21, 2022
Sweeter debugging and benchmarking Python programs.

Do you ever use print() or log() to debug your code? If so, ycecream, or y for short, will make printing debug information a lot sweeter. And on top o

42 Dec 12, 2022
Graphical Python debugger which lets you easily view the values of all evaluated expressions

birdseye birdseye is a Python debugger which records the values of expressions in a function call and lets you easily view them after the function exi

Alex Hall 1.5k Dec 24, 2022
Trace any Python program, anywhere!

lptrace lptrace is strace for Python programs. It lets you see in real-time what functions a Python program is running. It's particularly useful to de

Karim Hamidou 687 Nov 20, 2022
Little helper to run Steam apps under Proton with a GDB debugger

protongdb A small little helper for running games with Proton and debugging with GDB Requirements At least Python 3.5 protontricks pip package and its

Joshie 21 Nov 27, 2022
A toolbar overlay for debugging Flask applications

Flask Debug-toolbar This is a port of the excellent django-debug-toolbar for Flask applications. Installation Installing is simple with pip: $ pip ins

863 Dec 29, 2022
Parsing ELF and DWARF in Python

pyelftools pyelftools is a pure-Python library for parsing and analyzing ELF files and DWARF debugging information. See the User's guide for more deta

Eli Bendersky 1.6k Jan 04, 2023
Integration of IPython pdb

IPython pdb Use ipdb exports functions to access the IPython debugger, which features tab completion, syntax highlighting, better tracebacks, better i

Godefroid Chapelle 1.7k Jan 07, 2023
Full featured multi arch/os debugger built on top of PyQt5 and frida

Full featured multi arch/os debugger built on top of PyQt5 and frida

iGio90 1.1k Dec 26, 2022
A powerful set of Python debugging tools, based on PySnooper

snoop snoop is a powerful set of Python debugging tools. It's primarily meant to be a more featureful and refined version of PySnooper. It also includ

Alex Hall 874 Jan 08, 2023
Never use print for debugging again

PySnooper - Never use print for debugging again PySnooper is a poor man's debugger. If you've used Bash, it's like set -x for Python, except it's fanc

Ram Rachum 15.5k Jan 01, 2023
Debugging manhole for python applications.

Overview docs tests package Manhole is in-process service that will accept unix domain socket connections and present the stacktraces for all threads

Ionel Cristian Mărieș 332 Dec 07, 2022
VizTracer is a low-overhead logging/debugging/profiling tool that can trace and visualize your python code execution.

VizTracer is a low-overhead logging/debugging/profiling tool that can trace and visualize your python code execution.

2.8k Jan 08, 2023
Cyberbrain: Python debugging, redefined.

Cyberbrain1(电子脑) aims to free programmers from debugging.

laike9m 2.3k Jan 07, 2023
Hypothesis debugging with vscode

Hypothesis debugging with vscode

Oliver Mannion 0 Feb 09, 2022
Python's missing debug print command and other development tools.

python devtools Python's missing debug print command and other development tools. For more information, see documentation. Install Just pip install de

Samuel Colvin 637 Jan 02, 2023
A package containing a lot of useful utilities for Python developing and debugging.

Vpack A package containing a lot of useful utilities for Python developing and debugging. Features Sigview: press Ctrl+C to print the current stack in

volltin 16 Aug 18, 2022