Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
4d4313d5
Commit
4d4313d5
authored
May 05, 2009
by
Georg Brandl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
#5142: add module skipping feature to pdb.
parent
e3869c41
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
164 additions
and
7 deletions
+164
-7
Doc/library/pdb.rst
Doc/library/pdb.rst
+49
-4
Lib/bdb.py
Lib/bdb.py
+12
-1
Lib/pdb.py
Lib/pdb.py
+2
-2
Lib/test/test_pdb.py
Lib/test/test_pdb.py
+99
-0
Misc/NEWS
Misc/NEWS
+2
-0
No files found.
Doc/library/pdb.rst
View file @
4d4313d5
.. _debugger:
.. _debugger:
:mod:`pdb` --- The Python Debugger
:mod:`pdb` --- The Python Debugger
...
@@ -53,7 +52,16 @@ useful than quitting the debugger upon program's exit.
...
@@ -53,7 +52,16 @@ useful than quitting the debugger upon program's exit.
.. versionadded:: 2.4
.. versionadded:: 2.4
Restarting post-mortem behavior added.
Restarting post-mortem behavior added.
Typical usage to inspect a crashed program is::
The typical usage to break into the debugger from a running program is to
insert ::
import pdb; pdb.set_trace()
at the location you want to break into the debugger. You can then step through
the code following this statement, and continue running without debugger using
the ``c`` command.
The typical usage to inspect a crashed program is::
>>> import pdb
>>> import pdb
>>> import mymodule
>>> import mymodule
...
@@ -70,10 +78,10 @@ Typical usage to inspect a crashed program is::
...
@@ -70,10 +78,10 @@ Typical usage to inspect a crashed program is::
-> print spam
-> print spam
(Pdb)
(Pdb)
The module defines the following functions; each enters the debugger in a
The module defines the following functions; each enters the debugger in a
slightly different way:
slightly different way:
.. function:: run(statement[, globals[, locals]])
.. function:: run(statement[, globals[, locals]])
Execute the *statement* (given as a string) under debugger control. The
Execute the *statement* (given as a string) under debugger control. The
...
@@ -117,7 +125,38 @@ slightly different way:
...
@@ -117,7 +125,38 @@ slightly different way:
.. function:: pm()
.. function:: pm()
Enter post-mortem debugging of the traceback found in ``sys.last_traceback``.
Enter post-mortem debugging of the traceback found in
:data:`sys.last_traceback`.
The ``run_*`` functions and :func:`set_trace` are aliases for instantiating the
:class:`Pdb` class and calling the method of the same name. If you want to
access further features, you have to do this yourself:
.. class:: Pdb(completekey='tab', stdin=None, stdout=None, skip=None)
:class:`Pdb` is the debugger class.
The *completekey*, *stdin* and *stdout* arguments are passed to the
underlying :class:`cmd.Cmd` class; see the description there.
The *skip* argument, if given, must be an iterable of glob-style module name
patterns. The debugger will not step into frames that originate in a module
that matches one of these patterns. [1]_
Example call to enable tracing with *skip*::
import pdb; pdb.Pdb(skip=['django.*']).set_trace()
.. versionadded:: 2.7
The *skip* argument.
.. method:: run(statement[, globals[, locals]])
runeval(expression[, globals[, locals]])
runcall(function[, argument, ...])
set_trace()
See the documentation for the functions explained above.
.. _debugger-commands:
.. _debugger-commands:
...
@@ -351,3 +390,9 @@ run [*args* ...]
...
@@ -351,3 +390,9 @@ run [*args* ...]
q(uit)
q(uit)
Quit from the debugger. The program being executed is aborted.
Quit from the debugger. The program being executed is aborted.
.. rubric:: Footnotes
.. [1] Whether a frame is considered to originate in a certain module
is determined by the ``__name__`` in the frame globals.
Lib/bdb.py
View file @
4d4313d5
"""Debugger basics"""
"""Debugger basics"""
import
fnmatch
import
sys
import
sys
import
os
import
os
import
types
import
types
...
@@ -19,7 +20,8 @@ class Bdb:
...
@@ -19,7 +20,8 @@ class Bdb:
The standard debugger class (pdb.Pdb) is an example.
The standard debugger class (pdb.Pdb) is an example.
"""
"""
def
__init__
(
self
):
def
__init__
(
self
,
skip
=
None
):
self
.
skip
=
set
(
skip
)
if
skip
else
None
self
.
breaks
=
{}
self
.
breaks
=
{}
self
.
fncache
=
{}
self
.
fncache
=
{}
...
@@ -94,9 +96,18 @@ class Bdb:
...
@@ -94,9 +96,18 @@ class Bdb:
# methods, but they may if they want to redefine the
# methods, but they may if they want to redefine the
# definition of stopping and breakpoints.
# definition of stopping and breakpoints.
def
is_skipped_module
(
self
,
module_name
):
for
pattern
in
self
.
skip
:
if
fnmatch
.
fnmatch
(
module_name
,
pattern
):
return
True
return
False
def
stop_here
(
self
,
frame
):
def
stop_here
(
self
,
frame
):
# (CT) stopframe may now also be None, see dispatch_call.
# (CT) stopframe may now also be None, see dispatch_call.
# (CT) the former test for None is therefore removed from here.
# (CT) the former test for None is therefore removed from here.
if
self
.
skip
and
\
self
.
is_skipped_module
(
frame
.
f_globals
.
get
(
'__name__'
)):
return
False
if
frame
is
self
.
stopframe
:
if
frame
is
self
.
stopframe
:
return
frame
.
f_lineno
>=
self
.
stoplineno
return
frame
.
f_lineno
>=
self
.
stoplineno
while
frame
is
not
None
and
frame
is
not
self
.
stopframe
:
while
frame
is
not
None
and
frame
is
not
self
.
stopframe
:
...
...
Lib/pdb.py
View file @
4d4313d5
...
@@ -58,8 +58,8 @@ line_prefix = '\n-> ' # Probably a better default
...
@@ -58,8 +58,8 @@ line_prefix = '\n-> ' # Probably a better default
class
Pdb
(
bdb
.
Bdb
,
cmd
.
Cmd
):
class
Pdb
(
bdb
.
Bdb
,
cmd
.
Cmd
):
def
__init__
(
self
,
completekey
=
'tab'
,
stdin
=
None
,
stdout
=
None
):
def
__init__
(
self
,
completekey
=
'tab'
,
stdin
=
None
,
stdout
=
None
,
skip
=
None
):
bdb
.
Bdb
.
__init__
(
self
)
bdb
.
Bdb
.
__init__
(
self
,
skip
=
skip
)
cmd
.
Cmd
.
__init__
(
self
,
completekey
,
stdin
,
stdout
)
cmd
.
Cmd
.
__init__
(
self
,
completekey
,
stdin
,
stdout
)
if
stdout
:
if
stdout
:
self
.
use_rawinput
=
0
self
.
use_rawinput
=
0
...
...
Lib/test/test_pdb.py
0 → 100644
View file @
4d4313d5
# A test suite for pdb; at the moment, this only validates skipping of
# specified test modules (RFE #5142).
import
imp
import
os
import
sys
import
doctest
import
tempfile
from
test
import
test_support
# This little helper class is essential for testing pdb under doctest.
from
test_doctest
import
_FakeInput
def
test_pdb_skip_modules
():
"""This illustrates the simple case of module skipping.
>>> def skip_module():
... import string
... import pdb;pdb.Pdb(skip=['string*']).set_trace()
... string.lower('FOO')
>>> real_stdin = sys.stdin
>>> sys.stdin = _FakeInput([
... 'step',
... 'continue',
... ])
>>> try:
... skip_module()
... finally:
... sys.stdin = real_stdin
> <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()
-> string.lower('FOO')
(Pdb) step
--Return--
> <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()->None
-> string.lower('FOO')
(Pdb) continue
"""
# Module for testing skipping of module that makes a callback
mod
=
imp
.
new_module
(
'module_to_skip'
)
exec
'def foo_pony(callback): x = 1; callback(); return None'
in
mod
.
__dict__
def
test_pdb_skip_modules_with_callback
():
"""This illustrates skipping of modules that call into other code.
>>> def skip_module():
... def callback():
... return None
... import pdb;pdb.Pdb(skip=['module_to_skip*']).set_trace()
... mod.foo_pony(callback)
>>> real_stdin = sys.stdin
>>> sys.stdin = _FakeInput([
... 'step',
... 'step',
... 'step',
... 'step',
... 'step',
... 'continue',
... ])
>>> try:
... skip_module()
... finally:
... sys.stdin = real_stdin
> <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()
-> mod.foo_pony(callback)
(Pdb) step
--Call--
> <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(2)callback()
-> def callback():
(Pdb) step
> <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()
-> return None
(Pdb) step
--Return--
> <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()->None
-> return None
(Pdb) step
--Return--
> <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()->None
-> mod.foo_pony(callback)
(Pdb) step
> <doctest test.test_pdb.test_pdb_skip_modules_with_callback[3]>(4)<module>()
-> sys.stdin = real_stdin
(Pdb) continue
"""
def
test_main
():
from
test
import
test_pdb
test_support
.
run_doctest
(
test_pdb
,
verbosity
=
True
)
if
__name__
==
'__main__'
:
test_main
()
Misc/NEWS
View file @
4d4313d5
...
@@ -273,6 +273,8 @@ Core and Builtins
...
@@ -273,6 +273,8 @@ Core and Builtins
Library
Library
-------
-------
- Issue #5142: Add the ability to skip modules while stepping to pdb.
- Issue #1309567: Fix linecache behavior of stripping subdirectories when
- Issue #1309567: Fix linecache behavior of stripping subdirectories when
looking for files given by a relative filename.
looking for files given by a relative filename.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment