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.
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
orc
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.
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
.
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()
.
The following are new commands that you can use from the interative
(Pdb++)
prompt.
sticky [start end]
start
and end
are given, sticky mode is enabled and
only lines within that range (extremes included) will be displayed.longlist
(ll
)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
track EXPRESSION
pypy
source code to
be importable.display EXPRESSION
undisplay EXPRESSION
:EXPRESSION
from the display list.source EXPRESSION
edit EXPRESSION
hf_unhide
, hf_hide
, hf_list
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.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 prefering 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]
pdb
moduleThe 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()
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()
pdb.set_trace()
: any subsequent call to it will be ignored.pdb.enable()
pdb.set_trace()
, in case it was disabled by pdb.disable()
.@pdb.hideframe
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
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++) '
highlight = True
longlist
of
a function or when in sticky mode.encoding = 'utf-8'
sticky_by_default = False
line_number_color = pdb.Color.turquoise
filename_color = pdb.Color.yellow
current_line_color = "39;49;7"
39
) and background
(49
) colors, inversed (7
).
See Notes on color options.editor = None
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
exec_if_unfocused = None
enable_hidden_frames = True
hf_unhide
, hf_hide
, and hf_list
can be
used to control display of them.show_hidden_frames_count = True
enable_hidden_frames
is True
this controls if the number of
hidden frames gets displayed.def setup(self, pdb): pass
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
traceback.format_exception
,
when show_traceback_on_error
is enabled.use_pygments = None
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 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 usesTerminal256Formatter
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 contructor.
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"}
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.
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 excercise 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 that cases it is fine to do a commmit 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 behaviour 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
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。