mirror of
https://github.com/python/cpython.git
synced 2025-12-15 21:44:50 +00:00
Patch #1003640: replace checkline() function parsing with new breakpoint logic:
1) When a breakpoint is set via a function name: - the breakpoint gets the lineno of the def statement - a new funcname attribute is attached to the breakpoint 2) bdb.effective() calls new function checkfuncname() to handle: - def statement is executed: don't break. - a first executable line of a function with a breakpoint on the lineno of the def statement is reached: break. This fixes bugs 976878, 926369 and 875404. Thanks Ilya Sandler.
This commit is contained in:
parent
cb7b3f30d6
commit
4a9faa1ea0
2 changed files with 51 additions and 45 deletions
45
Lib/bdb.py
45
Lib/bdb.py
|
|
@ -113,7 +113,12 @@ class Bdb:
|
|||
return False
|
||||
lineno = frame.f_lineno
|
||||
if not lineno in self.breaks[filename]:
|
||||
return False
|
||||
# The line itself has no breakpoint, but maybe the line is the
|
||||
# first line of a function with breakpoint set by function name.
|
||||
lineno = frame.f_code.co_firstlineno
|
||||
if not lineno in self.breaks[filename]:
|
||||
return False
|
||||
|
||||
# flag says ok to delete temp. bp
|
||||
(bp, flag) = effective(filename, lineno, frame)
|
||||
if bp:
|
||||
|
|
@ -210,7 +215,8 @@ class Bdb:
|
|||
# Call self.get_*break*() to see the breakpoints or better
|
||||
# for bp in Breakpoint.bpbynumber: if bp: bp.bpprint().
|
||||
|
||||
def set_break(self, filename, lineno, temporary=0, cond = None):
|
||||
def set_break(self, filename, lineno, temporary=0, cond = None,
|
||||
funcname=None):
|
||||
filename = self.canonic(filename)
|
||||
import linecache # Import as late as possible
|
||||
line = linecache.getline(filename, lineno)
|
||||
|
|
@ -222,7 +228,7 @@ class Bdb:
|
|||
list = self.breaks[filename]
|
||||
if not lineno in list:
|
||||
list.append(lineno)
|
||||
bp = Breakpoint(filename, lineno, temporary, cond)
|
||||
bp = Breakpoint(filename, lineno, temporary, cond, funcname)
|
||||
|
||||
def clear_break(self, filename, lineno):
|
||||
filename = self.canonic(filename)
|
||||
|
|
@ -428,7 +434,10 @@ class Breakpoint:
|
|||
# index 0 is unused, except for marking an
|
||||
# effective break .... see effective()
|
||||
|
||||
def __init__(self, file, line, temporary=0, cond = None):
|
||||
def __init__(self, file, line, temporary=0, cond=None, funcname=None):
|
||||
self.funcname = funcname
|
||||
# Needed if funcname is not None.
|
||||
self.func_first_executable_line = None
|
||||
self.file = file # This better be in canonical form!
|
||||
self.line = line
|
||||
self.temporary = temporary
|
||||
|
|
@ -483,6 +492,32 @@ class Breakpoint:
|
|||
|
||||
# -----------end of Breakpoint class----------
|
||||
|
||||
def checkfuncname(b, frame):
|
||||
"""Check whether we should break here because of `b.funcname`."""
|
||||
if not b.funcname:
|
||||
# Breakpoint was set via line number.
|
||||
if b.line != frame.f_lineno:
|
||||
# Breakpoint was set at a line with a def statement and the function
|
||||
# defined is called: don't break.
|
||||
return False
|
||||
return True
|
||||
|
||||
# Breakpoint set via function name.
|
||||
|
||||
if frame.f_code.co_name != b.funcname:
|
||||
# It's not a function call, but rather execution of def statement.
|
||||
return False
|
||||
|
||||
# We are in the right frame.
|
||||
if not b.func_first_executable_line:
|
||||
# The function is entered for the 1st time.
|
||||
b.func_first_executable_line = frame.f_lineno
|
||||
|
||||
if b.func_first_executable_line != frame.f_lineno:
|
||||
# But we are not at the first line number: don't break.
|
||||
return False
|
||||
return True
|
||||
|
||||
# Determines if there is an effective (active) breakpoint at this
|
||||
# line of code. Returns breakpoint number or 0 if none
|
||||
def effective(file, line, frame):
|
||||
|
|
@ -498,6 +533,8 @@ def effective(file, line, frame):
|
|||
b = possibles[i]
|
||||
if b.enabled == 0:
|
||||
continue
|
||||
if not checkfuncname(b, frame):
|
||||
continue
|
||||
# Count every hit when bp is enabled
|
||||
b.hits = b.hits + 1
|
||||
if not b.cond:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue