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
40 changes: 28 additions & 12 deletions Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1337,7 +1337,7 @@ def do_commands(self, arg):
complete_commands = _complete_bpnumber

def do_break(self, arg, temporary=False):
"""b(reak) [ ([filename:]lineno | function) [, condition] ]
"""b(reak) [ [filename:](lineno | function) [, condition] ]

Without argument, list all breaks.

Expand All @@ -1347,9 +1347,9 @@ def do_break(self, arg, temporary=False):
present, it is a string specifying an expression which must
evaluate to true before the breakpoint is honored.

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 for on
The line number and function 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 for on
sys.path; the .py suffix may be omitted.
"""
if not arg:
Expand Down Expand Up @@ -1388,8 +1388,12 @@ def do_break(self, arg, temporary=False):
try:
lineno = int(arg)
except ValueError:
self.error('Bad lineno: %s' % arg)
return
func = arg
find_res = find_function(func, self.canonic(filename))
if not find_res:
self.error('Bad lineno or function name: %s' % arg)
return
funcname, filename, lineno = find_res
else:
# no colon; can be lineno or function
try:
Expand Down Expand Up @@ -1650,12 +1654,13 @@ def _prompt_for_confirmation(self, prompt, default):
return reply.strip().lower()

def do_clear(self, arg):
"""cl(ear) [filename:lineno | bpnumber ...]
"""cl(ear) [filename:(lineno | function) | bpnumber ...]

With a space separated list of breakpoint numbers, clear
those breakpoints. Without argument, clear all breaks (but
first ask confirmation). With a filename:lineno argument,
clear all breaks at that line in that file.
clear all breakpoints at that line. With a filename:function
argument, clear all breakpoints at that function.
"""
if not arg:
reply = self._prompt_for_confirmation(
Expand All @@ -1671,13 +1676,24 @@ def do_clear(self, arg):
if ':' in arg:
# Make sure it works for "clear C:\foo\bar.py:12"
i = arg.rfind(':')
filename = arg[:i]
arg = arg[i+1:]
filename = arg[:i].rstrip()
arg = arg[i+1:].lstrip()
err = None
try:
lineno = int(arg)
except ValueError:
err = "Invalid line number (%s)" % arg
else:
f = self.lookupmodule(filename)
if not f:
err = '%r not found from sys.path' % filename
else:
filename = f
func = arg
find_res = find_function(func, self.canonic(filename))
if find_res:
_, filename, lineno = find_res
else:
err = "Invalid line number or function name:(%s)" % arg
if not err:
bplist = self.get_breaks(filename, lineno)[:]
err = self.clear_break(filename, lineno)
if err:
Expand Down
14 changes: 14 additions & 0 deletions Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -4622,6 +4622,20 @@ def foo(self):
stdout, stderr = self.run_pdb_script(script, commands)
self.assertIn("The specified object 'C.foo' is not a function", stdout)

def test_break_function_with_file(self):
script = """
def foo():
pass
"""
commands = """
break main:foo
clear main:foo
quit
"""
stdout, stderr = self.run_pdb_script(script, commands)
self.assertRegex(stdout, r"Breakpoint 1 at .*main\.py:3")
self.assertRegex(stdout, r"Deleted breakpoint 1 at .*main\.py:3")


class ChecklineTests(unittest.TestCase):
def setUp(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:mod:`pdb` now supports setting or clearing breakpoints with the ``filename:function`` syntax.
Loading