Skip to content

Commit eacae21

Browse files
gh-160125: Support package.module.function for pdb breakpoint command (#160126)
1 parent 5ca490b commit eacae21

4 files changed

Lines changed: 37 additions & 3 deletions

File tree

‎Doc/library/pdb.rst‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,8 @@ can be overridden by the local file.
458458

459459
With a *function* argument, set a break at the first executable statement within
460460
that function. *function* can be any expression that evaluates to a function
461-
in the current namespace.
461+
in the current namespace, or in the form ``package.module.function`` if
462+
``package.module`` is importable.
462463

463464
If a second argument is present, it is an expression which must evaluate to
464465
true before the breakpoint is honored.

‎Lib/pdb.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,10 +1688,10 @@ def lineinfo(self, identifier):
16881688
else:
16891689
# More than one part.
16901690
# First is module, second is method/class
1691-
f = self.lookupmodule(parts[0])
1691+
f = self.lookupmodule('.'.join(parts[:-1]))
16921692
if f:
16931693
fname = f
1694-
item = parts[1]
1694+
item = parts[-1]
16951695
else:
16961696
return failed
16971697
answer = find_function(item, self.canonic(fname))

‎Lib/test/test_pdb.py‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,36 @@ def test_pdb_breakpoint_with_filename():
514514
(Pdb) continue
515515
"""
516516

517+
def test_pdb_breakpoint_in_package():
518+
"""Breakpoints for package.module.function should work even if the module is not yet imported.
519+
520+
>>> def test_function():
521+
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
522+
... import multiprocessing.util # Now import the module
523+
... multiprocessing.util.is_abstract_socket_namespace(None) # We should break here
524+
525+
>>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
526+
... 'multiprocessing.util.is_abstract_socket_namespace', # Make sure the module is not imported yet
527+
... 'break multiprocessing.util.is_abstract_socket_namespace', # We can still set a bp on it
528+
... 'continue', # will stop at the function call
529+
... 'clear 1',
530+
... 'continue',
531+
... ]):
532+
... test_function()
533+
> <doctest test.test_pdb.test_pdb_breakpoint_in_package[0]>(2)test_function()
534+
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
535+
(Pdb) multiprocessing.util.is_abstract_socket_namespace
536+
*** NameError: name 'multiprocessing' is not defined. Did you forget to import 'multiprocessing'?
537+
(Pdb) break multiprocessing.util.is_abstract_socket_namespace
538+
Breakpoint 1 at ...util.py:...
539+
(Pdb) continue
540+
> ...util.py(...)is_abstract_socket_namespace()
541+
-> if not address:
542+
(Pdb) clear 1
543+
Deleted breakpoint 1 at ...util.py:...
544+
(Pdb) continue
545+
"""
546+
517547
def test_pdb_breakpoint_on_disabled_line():
518548
"""New breakpoint on once disabled line should work
519549
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Support setting breakpoints with the :mod:`pdb` ``break`` and ``tbreak``
2+
commands using ``package.module.function`` names when the module has not been
3+
imported in the current namespace.

0 commit comments

Comments
 (0)