Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Doc/library/pdb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,8 @@ can be overridden by the local file.

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.
in the current namespace, or in the form ``package.module.function`` if
``package.module`` is importable.

If a second argument is present, it is an expression which must evaluate to
true before the breakpoint is honored.
Expand Down
4 changes: 2 additions & 2 deletions Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1688,10 +1688,10 @@ def lineinfo(self, identifier):
else:
# More than one part.
# First is module, second is method/class
f = self.lookupmodule(parts[0])
f = self.lookupmodule('.'.join(parts[:-1]))
if f:
fname = f
item = parts[1]
item = parts[-1]
else:
return failed
answer = find_function(item, self.canonic(fname))
Expand Down
30 changes: 30 additions & 0 deletions Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,36 @@ def test_pdb_breakpoint_with_filename():
(Pdb) continue
"""

def test_pdb_breakpoint_in_package():
"""Breakpoints for package.module.function should work even if the module is not yet imported.

>>> def test_function():
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
... import multiprocessing.util # Now import the module
... multiprocessing.util.is_abstract_socket_namespace(None) # We should break here

>>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
... 'multiprocessing.util.is_abstract_socket_namespace', # Make sure the module is not imported yet

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does this ensure it'd not imported?

... 'break multiprocessing.util.is_abstract_socket_namespace', # We can still set a bp on it
... 'continue', # will stop at the function call
... 'clear 1',
... 'continue',
... ]):
... test_function()
> <doctest test.test_pdb.test_pdb_breakpoint_in_package[0]>(2)test_function()
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
(Pdb) multiprocessing.util.is_abstract_socket_namespace
*** NameError: name 'multiprocessing' is not defined. Did you forget to import 'multiprocessing'?
(Pdb) break multiprocessing.util.is_abstract_socket_namespace
Breakpoint 1 at .../multiprocessing/util.py:...
(Pdb) continue
> .../multiprocessing/util.py(...)is_abstract_socket_namespace()
-> if not address:
(Pdb) clear 1
Deleted breakpoint 1 at .../multiprocessing/util.py:...
(Pdb) continue
"""

def test_pdb_breakpoint_on_disabled_line():
"""New breakpoint on once disabled line should work

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Support setting breakpoints with the :mod:`pdb` ``break`` and ``tbreak``
commands using ``package.module.function`` names when the module has not been
imported in the current namespace.
Loading