Convert Figma logo to code with AI

pdbpp logopdbpp

pdb++, a drop-in replacement for pdb (the Python debugger)

1,382
71
1,382
105

Top Related Projects

1,923

Integration of IPython pdb

2,131

An implementation of the Debug Adapter Protocol for Python

3,109

Full-screen console debugger for Python

16,511

Never use print for debugging again

Graphical Python debugger which lets you easily view the values of all evaluated expressions

Quick Overview

pdbpp is an enhanced drop-in replacement for pdb, the Python debugger. It offers a more user-friendly interface with syntax highlighting, tab completion, and additional commands. pdbpp aims to improve the debugging experience for Python developers while maintaining compatibility with the standard pdb module.

Pros

  • Enhanced user interface with syntax highlighting and tab completion
  • Additional commands and features not available in standard pdb
  • Seamless integration with existing Python projects
  • Active development and community support

Cons

  • May introduce slight overhead compared to standard pdb
  • Some advanced features might require a learning curve
  • Potential compatibility issues with certain Python environments or setups
  • Dependency on external libraries for some features

Code Examples

  1. Setting a breakpoint in your code:
import pdb; pdb.set_trace()
# or
from pdbpp import set_trace; set_trace()
  1. Using the sticky command to keep context visible:
(Pdb++) sticky
# This will keep the current source code context visible
  1. Executing shell commands within the debugger:
(Pdb++) shell ls -l
# This will execute the 'ls -l' command in the shell
  1. Using the pp command for pretty-printing:
(Pdb++) pp complex_object
# This will pretty-print the complex_object with proper formatting

Getting Started

To get started with pdbpp, follow these steps:

  1. Install pdbpp using pip:

    pip install pdbpp
    
  2. In your Python code, import pdb and set a breakpoint:

    import pdb; pdb.set_trace()
    
  3. Run your Python script as usual. When the breakpoint is hit, you'll enter the enhanced pdb debugger.

  4. Use standard pdb commands or explore pdbpp-specific features like sticky, pp, or shell.

  5. To exit the debugger, use the c (continue) command or q (quit) to terminate the program.

Competitor Comparisons

1,923

Integration of IPython pdb

Pros of ipdb

  • Integrates seamlessly with IPython, providing a more feature-rich debugging environment
  • Offers tab completion and syntax highlighting during debugging sessions
  • Supports remote debugging capabilities

Cons of ipdb

  • May have a steeper learning curve for users unfamiliar with IPython
  • Can be slower to start up compared to pdb or pdbpp
  • Requires additional dependencies (IPython) to be installed

Code Comparison

ipdb:

import ipdb
ipdb.set_trace()

pdbpp:

import pdb
pdb.set_trace()

Both debuggers use similar syntax for setting breakpoints, but ipdb leverages IPython's enhanced features during debugging sessions. pdbpp, on the other hand, focuses on improving the standard pdb experience without introducing additional dependencies.

ipdb is ideal for developers who are comfortable with IPython and desire a more interactive debugging experience. pdbpp is better suited for those who want an enhanced pdb-like experience without the overhead of IPython.

While both debuggers offer improvements over the standard pdb, the choice between them often comes down to personal preference and specific project requirements.

2,131

An implementation of the Debug Adapter Protocol for Python

Pros of debugpy

  • More comprehensive debugging features, including remote debugging and multi-threaded debugging
  • Better integration with IDEs and development environments, especially Visual Studio Code
  • Actively maintained by Microsoft with frequent updates and improvements

Cons of debugpy

  • Steeper learning curve due to more complex features and configuration options
  • Heavier resource usage compared to the lightweight pdbpp
  • May be overkill for simple debugging tasks or small projects

Code Comparison

debugpy:

import debugpy

debugpy.listen(5678)
debugpy.wait_for_client()
debugpy.breakpoint()
print("Hello, debugpy!")

pdbpp:

import pdb

pdb.set_trace()
print("Hello, pdbpp!")

Key Differences

  • debugpy offers more advanced features and IDE integration, making it suitable for complex projects and professional development environments
  • pdbpp is lightweight and easy to use, making it ideal for quick debugging sessions and smaller projects
  • debugpy requires more setup and configuration, while pdbpp can be used with minimal setup
  • pdbpp focuses on enhancing the built-in Python debugger, while debugpy provides a more comprehensive debugging solution

Both tools have their strengths, and the choice between them depends on the specific needs of the project and the developer's preferences.

3,109

Full-screen console debugger for Python

Pros of PuDB

  • Full-screen, console-based interface with syntax highlighting
  • Ability to view and edit variables in real-time
  • Built-in stack viewer and breakpoint management

Cons of PuDB

  • Steeper learning curve due to more complex interface
  • May be overkill for simple debugging tasks
  • Requires additional dependencies (urwid library)

Code Comparison

PuDB:

from pudb import set_trace
set_trace()

PDB++:

import pdb
pdb.set_trace()

Key Differences

  • PuDB offers a more feature-rich, visual debugging experience
  • PDB++ enhances the standard PDB with improved functionality and usability
  • PuDB is better suited for complex debugging scenarios, while PDB++ is more lightweight and familiar to users of the standard PDB

Use Cases

  • Choose PuDB for large projects or when dealing with complex data structures
  • Opt for PDB++ when you need a simple, enhanced version of the standard PDB
  • PuDB is ideal for developers who prefer a visual interface, while PDB++ caters to those comfortable with command-line debugging

Community and Maintenance

  • Both projects are actively maintained and have a dedicated user base
  • PuDB has a larger community and more frequent updates
  • PDB++ focuses on incremental improvements to the standard PDB experience
16,511

Never use print for debugging again

Pros of PySnooper

  • Non-intrusive debugging: Automatically logs variable changes and function calls without modifying code
  • Easy to use: Simply add a decorator to the function you want to debug
  • Customizable output: Can log to file or custom output functions

Cons of PySnooper

  • Limited interactivity: Doesn't provide a command-line interface for stepping through code
  • Performance impact: May slow down execution, especially for large functions
  • Less control: Doesn't offer fine-grained control over execution flow

Code Comparison

PySnooper usage:

import pysnooper

@pysnooper.snoop()
def my_function(x, y):
    z = x + y
    return z

pdb++ usage:

import pdb

def my_function(x, y):
    pdb.set_trace()
    z = x + y
    return z

PySnooper focuses on automatic logging and non-intrusive debugging, while pdb++ provides an interactive debugging experience with more control over execution. PySnooper is easier to use for quick debugging tasks, but pdb++ offers more advanced features for complex debugging scenarios.

Graphical Python debugger which lets you easily view the values of all evaluated expressions

Pros of birdseye

  • Provides a graphical interface for debugging, offering a more visual and intuitive experience
  • Allows for detailed inspection of variables and expressions at each step of execution
  • Supports remote debugging, enabling debugging of code running on different machines

Cons of birdseye

  • Requires additional setup and dependencies compared to pdbpp's simpler installation
  • May have a steeper learning curve for users accustomed to traditional command-line debuggers
  • Could potentially impact performance more significantly due to its comprehensive tracing

Code Comparison

birdseye:

from birdseye import eye

@eye
def example_function(x, y):
    return x + y

pdbpp:

import pdb

def example_function(x, y):
    pdb.set_trace()
    return x + y

Both tools enhance Python debugging, but birdseye focuses on providing a rich, visual debugging experience, while pdbpp extends the functionality of Python's built-in pdb debugger with additional features and improved usability in the command-line interface.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

pdb++, a drop-in replacement for pdb

What is it?

This module is an extension of the pdb_ module of the standard library. It is meant to be fully compatible with its predecessor, yet it introduces a number of new features to make your debugging experience as nice as possible.

.. image:: https://user-images.githubusercontent.com/412005/64484794-2f373380-d20f-11e9-9f04-e1dabf113c6f.png

pdb++ features include:

  • colorful TAB completion of Python expressions (through fancycompleter_)

  • optional syntax highlighting of code listings (through Pygments_)

  • sticky mode_

  • several new commands to be used from the interactive (Pdb++) prompt

  • smart command parsing_ (hint: have you ever typed r or c at the prompt to print the value of some variable?)

  • additional convenience functions in the pdb module, to be used from your program

pdb++ is meant to be a drop-in replacement for pdb. If you find some unexpected behavior, please report it as a bug.

.. _pdb: http://docs.python.org/library/pdb.html .. _fancycompleter: http://bitbucket.org/antocuni/fancycompleter .. _Pygments: http://pygments.org/

Installation

Since pdb++ is not a valid package name the package is named pdbpp::

$ pip install pdbpp

pdb++ is also available via conda_::

$ conda install -c conda-forge pdbpp

Alternatively, you can just put pdb.py somewhere inside your PYTHONPATH.

.. _conda: https://anaconda.org/conda-forge/pdbpp

Usage

Note that the module is called pdb.py so that pdb++ will automatically be used in all places that do import pdb (e.g. pytest --pdb will give you a pdb++ prompt).

The old pdb module is still available by doing e.g. import pdb; pdb.pdb.set_trace().

New interactive commands

The following are new commands that you can use from the interactive (Pdb++) prompt.

.. _sticky mode:

sticky [start end] Toggle sticky mode. When in this mode, every time the current position changes, the screen is repainted and the whole function shown. Thus, when doing step-by-step execution you can easily follow the flow of the execution. If start and end are given, sticky mode is enabled and only lines within that range (extremes included) will be displayed.

longlist (ll) List source code for the current function. Different from the normal pdb list command, longlist displays the whole function. The current line is marked with ->. In case of post-mortem debugging, the line which actually raised the exception is marked with >>. If the highlight config option_ is set and Pygments_ is installed, the source code is highlighted.

interact Start an interactive interpreter whose global namespace contains all the names found in the current scope.

track EXPRESSION Display a graph showing which objects are the value of the expression refers to and are referred by. This command requires the pypy source code to be importable.

display EXPRESSION Add an expression to the display list; expressions in this list are evaluated at each step, and printed every time its value changes. WARNING: since these expressions are evaluated multiple times, make sure not to put expressions with side-effects in the display list.

undisplay EXPRESSION: Remove EXPRESSION from the display list.

source EXPRESSION Show the source code for the given function/method/class.

edit EXPRESSION Open the editor in the right position to edit the given function/method/class. The editor used is specified in a config option_.

hf_unhide, hf_hide, hf_list Some frames might be marked as "hidden" by e.g. using the @pdb.hideframe_ function decorator. By default, hidden frames are not shown in the stack trace, and cannot be reached using up and down. You can use hf_unhide to tell pdb to ignore the hidden status (i.e., to treat hidden frames as normal ones), and hf_hide to hide them again. hf_list prints a list of hidden frames. The config option enable_hidden_frames can be used to disable handling of hidden frames in general.

Smart command parsing

By default, pdb tries hard to interpret what you enter at the command prompt as one of its builtin commands. However, this is inconvenient if you want to just print the value of a local variable which happens to have the same name as one of the commands. E.g.::

(Pdb) list
  1
  2     def fn():
  3         c = 42
  4         import pdb;pdb.set_trace()
  5  ->     return c
(Pdb) c

In the example above, instead of printing 42 pdb interprets the input as the command continue, and then you lose your prompt. It's even worse than that, because it happens even if you type e.g. c.__class__.

pdb++ fixes this unfriendly (from the author's point of view, of course :-)) behavior by always preferring the variable in scope, if it exists. If you really want to execute the corresponding command, you can prefix it with !!. Thus, the example above becomes::

(Pdb++) list
  1
  2     def fn():
  3         c = 42
  4         import pdb;pdb.set_trace()
  5  ->     return c
(Pdb++) c
42
(Pdb++) !!c

Note that the "smart" behavior takes place only when there is ambiguity, i.e. if there exists a variable with the same name as a command: in all other cases, everything works as usual.

Regarding the list command itself, using list(… is a special case that gets handled as the Python builtin::

(Pdb++) list([1, 2])
[1, 2]

Additional functions in the pdb module

The pdb module that comes with pdb++ includes all the functions and classes that are in the module from the standard library. If you find any difference, please report it as a bug.

In addition, there are some new convenience functions that are unique to pdb++.

pdb.xpm() eXtended Post Mortem: it is equivalent to pdb.post_mortem(sys.exc_info()[2]). If used inside an except clause, it will start a post-mortem pdb prompt from the line that raised the exception being caught.

pdb.disable() Disable pdb.set_trace(): any subsequent call to it will be ignored.

pdb.enable() Re-enable pdb.set_trace(), in case it was disabled by pdb.disable().

.. _@pdb.hideframe:

@pdb.hideframe A function decorator that tells pdb++ to hide the frame corresponding to the function. Hidden frames do not show up when using interactive commands such as up, down or where, unless hf_unhide is invoked.

@pdb.break_on_setattr(attrname, condition=always) class decorator: break the execution of the program every time the attribute attrname is set on any instance of the class. condition is a callable that takes the target object of the setattr and the actual value; by default, it breaks every time the attribute is set. E.g.::

  @break_on_setattr('bar')
  class Foo(object):
      pass
  f = Foo()
  f.bar = 42    # the program breaks here

If can be used even after the class has already been created, e.g. if we want to break when some attribute of a particular object is set::

  class Foo(object):
      pass
  a = Foo()
  b = Foo()

  def break_if_a(obj, value):
      return obj is a

  break_on_setattr('bar', condition=break_if_a)(Foo)
  b.bar = 10   # no break
  a.bar = 42   # the program breaks here

This can be used after pdb.set_trace() also::

  (Pdb++) import pdb
  (Pdb++) pdb.break_on_setattr('tree_id')(obj.__class__)
  (Pdb++) continue

Configuration and customization

.. _config option:

To customize pdb++, you can put a file named .pdbrc.py in your home directory. The file must contain a class named Config inheriting from pdb.DefaultConfig and override the desired values.

The following is a list of the options you can customize, together with their default value:

prompt = '(Pdb++) ' The prompt to show when in interactive mode.

highlight = True Highlight line numbers and the current line when showing the longlist of a function or when in sticky mode.

encoding = 'utf-8' File encoding. Useful when there are international characters in your string literals or comments.

sticky_by_default = False Determine whether pdb++ starts in sticky mode or not.

line_number_color = pdb.Color.turquoise The color to use for line numbers. See Notes on color options_.

filename_color = pdb.Color.yellow The color to use for file names when printing the stack entries. See Notes on color options_.

current_line_color = "39;49;7" The SGR parameters for the ANSI escape sequence to highlight the current line. The default uses the default foreground (39) and background (49) colors, inversed (7). See Notes on color options_.

editor = None The command to invoke when using the edit command. By default, it uses $EDITOR if set, else vim or vi (if found). If only the editor command is specified, the emacs and vi notation will be used to specify the line number: COMMAND +n filename. It's otherwise possible to use another syntax by using the placeholders {filename} and {lineno}. For example with sublime text, specify editor = "subl {filename}:{lineno}".

truncate_long_lines = True Truncate lines which exceed the terminal width.

exec_if_unfocused = None Shell command to execute when starting the pdb prompt and the terminal window is not focused. Useful to e.g. play a sound to alert the user that the execution of the program stopped. It requires the wmctrl_ module.

enable_hidden_frames = True Certain frames can be hidden by default. If enabled, the commands hf_unhide, hf_hide, and hf_list can be used to control display of them.

show_hidden_frames_count = True If enable_hidden_frames is True this controls if the number of hidden frames gets displayed.

def setup(self, pdb): pass This method is called during the initialization of the Pdb class. Useful to do complex setup.

show_traceback_on_error = True Display tracebacks for errors via Pdb.error, that come from Pdb.default (i.e. the execution of an unrecognized pdb command), and are not a direct cause of the expression itself (e.g. NameError with a command like doesnotexist).

With this option disabled only *** exception string gets printed, which often misses useful context.

show_traceback_on_error_limit = None This option sets the limit to be used with traceback.format_exception, when show_traceback_on_error is enabled.

Options relevant for source code highlighting (using Pygments) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

use_pygments = None By default Pygments_ is used for syntax highlighting of source code when it can be imported, e.g. when showing the longlist of a function or when in sticky mode.

pygments_formatter_class = None

You can configure the Pygments formatter to use via the pygments_formatter_class config setting as a string (dotted path). This should be one of the following typically: "pygments.formatters.Terminal256Formatter", "pygments.formatters.TerminalTrueColorFormatter", or "pygments.formatters.TerminalFormatter".

The default is to auto-detect the best formatter based on the $TERM variable, e.g. it uses Terminal256Formatter if the $TERM variable contains "256color" (e.g. xterm-256color), but also knows about e.g. "xterm-kitty" to support true colors (TerminalTrueColorFormatter). TerminalFormatter gets used as a fallback.

pygments_formatter_kwargs = {}

A dictionary of keyword arguments to pass to the formatter's constructor.

The default arguments (updated with this setting) are::

  {
      "style": "default",
      "bg": self.config.bg,
      "colorscheme": self.config.colorscheme,
  }

``style = 'default'``

 The style to use, can be a string or a Pygments Style subclass.
 E.g. ``"solarized-dark"``.
 See http://pygments.org/docs/styles/.

bg = 'dark'

 Selects a different palette for dark/light backgrounds.
 Only used by ``TerminalFormatter``.

colorscheme = None

 A dictionary mapping token types to (lightbg, darkbg) color names or
 ``None`` (default: ``None`` = use builtin colorscheme).
 Only used by ``TerminalFormatter``.

Example::

class Config(pdb.DefaultConfig):
    pygments_formatter_class = "pygments.formatters.TerminalTrueColorFormatter"
    pygments_formatter_kwargs = {"style": "solarized-light"}

.. _wmctrl: http://bitbucket.org/antocuni/wmctrl .. _SGR parameters: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters

Notes on color options ^^^^^^^^^^^^^^^^^^^^^^

The values for color options will be used inside of the SGR escape sequence \e[%sm where \e is the ESC character and %s the given value. See SGR parameters_.

The following means "reset all colors" (0), set foreground color to 18 (48;5;18), and background to 21: "0;48;5;18;38;5;21".

Constants are available via pdb.Color, e.g. pdb.Color.red ("31;01"), but in general any string can be used here.

Coding guidelines

pdb++ is developed using Test Driven Development, and we try to keep test coverage high.

As a general rule, every commit should come with its own test. If it's a new feature, it should come with one or many tests which exercise it. If it's a bug fix, the test should fail before the fix, and pass after.

The goal is to make refactoring easier in the future: if you wonder why a certain line of code does something, in principle it should be possible to comment it out and see which tests fail.

In exceptional cases, the test might be too hard or impossible to write: in such cases it is fine to do a commit without a test, but you should explain very precisely in the commit message why it is hard to write a test and how to reproduce the buggy behavior by hand.

It is fine NOT to write a test in the following cases:

  • typos, documentation, and in general any non-coding commit

  • code refactorings which do not add any feature

  • commits which fix an already failing test

  • commits to silence warnings

  • purely cosmetic changes, such as change the color of the output