8000 gh-117618: Make package.module searchable for breakpoints and clean up docs by gaogaotiantian · Pull Request #117619 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-117618: Make package.module searchable for breakpoints and clean up docs #117619

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 30, 2024
19 changes: 13 additions & 6 deletions Doc/library/pdb.rst
``package.module``.
Original file line number Diff line number Diff line change
Expand Up @@ -328,12 +328,16 @@ can be overridden by the local file.

.. pdbcommand:: b(reak) [([filename:]lineno | function) [, condition]]

With a *lineno* argument, set a break there in the current file. With a
*function* argument, set a break at the first executable statement within
that function. The line number may be prefixed with a filename and a colon,
to specify a breakpoint in another file (probably one that hasn't been loaded
yet). The file is searched on :data:`sys.path`. Note that each breakpoint
is assigned a number to which all the other breakpoint commands refer.
With a *lineno* argument, set a break at line *lineno* in the current file.
The line number may be prefixed with a *filename* and a colon,
to specify a breakpoint in another file (possibly one that hasn't been loaded
yet). The file is searched on :data:`sys.path`. Accepatable forms of *filename*
are ``/abspath/to/file.py``, ``relpath/file.py``, ``module`` and

With a *function* argument, set a break at the first executable statement within
that function. *function* can be any expression that evaluates to a function
in the current namespace.

If a second argument is present, it is an expression which must evaluate to
true before the breakpoint is honored.
Expand All @@ -342,6 +346,9 @@ can be overridden by the local file.
of times that breakpoint has been hit, the current ignore count, and the
associated condition if any.

Each breakpoint is assigned a number to which all the other
breakpoint commands refer.

.. pdbcommand:: tbreak [([filename:]lineno | function) [, condition]]

Temporary breakpoint, which is removed automatically when it is first hit.
Expand Down
24 changes: 15 additions & 9 deletions Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -2007,17 +2007,23 @@ def lookupmodule(self, filename):

lookupmodule() translates (possibly incomplete) file or module name
into an absolute file name.

filename could be in format of:
* an absolute path like '/path/to/file.py'
* a relative path like 'file.py' or 'dir/file.py'
* a module name like 'module' or 'package.module'

files and modules will be searched in sys.path.
"""
if os.path.isabs(filename) and os.path.exists(filename):
return filename
f = os.path.join(sys.path[0], filename)
if os.path.exists(f) and self.canonic(f) == self.mainpyfile:
return f
root, ext = os.path.splitext(filename)
if ext == '':
filename = filename + '.py'
if not filename.endswith('.py'):
# A module is passed in so convert it to equivalent file
filename = filename.replace('.', os.sep) + '.py'

if os.path.isabs(filename):
return filename
if os.path.exists(filename):
return filename
return None

for dirname in sys.path:
while os.path.islink(dirname):
dirname = os.readlink(dirname)
Expand Down
40 changes: 40 additions & 0 deletions Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,46 @@ def test_pdb_breakpoint_commands():
4
"""

def test_pdb_breakpoint_with_filename():
"""Breakpoints with filename:lineno

>>> def test_function():
... # inspect_fodder2 is a great module as the line number is stable
... from test.test_inspect import inspect_fodder2 as mod2
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
... mod2.func88()
... mod2.func114()
... # Be a good citizen and clean up the mess
... reset_Breakpoint()

First, need to clear bdb state that might be left over from previous tests.
Otherwise, the new breakpoints might get assigned different numbers.

>>> reset_Breakpoint()

>>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
... 'break test.test_inspect.inspect_fodder2:90',
... 'continue', # will stop at func88
... 'break test/test_inspect/inspect_fodder2.py:115',
... 'continue', # will stop at func114
... 'continue',
... ]):
... test_function()
> <doctest test.test_pdb.test_pdb_breakpoint_with_filename[0]>(5)test_function()
-> mod2.func88()
(Pdb) break test.test_inspect.inspect_fodder2:90
Breakpoint 1 at ...inspect_fodder2.py:90
(Pdb) continue
> ...inspect_fodder2.py(90)func88()
-> return 90
(Pdb) break test/test_inspect/inspect_fodder2.py:115
Breakpoint 2 at ...inspect_fodder2.py:115
(Pdb) continue
> ...inspect_fodder2.py(115)func114()
-> return 115
(Pdb) continue
"""

def test_pdb_breakpoints_preserved_across_interactive_sessions():
"""Breakpoints are remembered between interactive sessions

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support ``package.module`` as ``filename`` for ``break`` command of :mod:`pdb`
Loading
0