mirror of
https://github.com/python/cpython.git
synced 2024-11-23 09:54:58 +08:00
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
commit
37e533a397
2
.github/ISSUE_TEMPLATE/bug.yml
vendored
2
.github/ISSUE_TEMPLATE/bug.yml
vendored
@ -34,12 +34,12 @@ body:
|
||||
label: "CPython versions tested on:"
|
||||
multiple: true
|
||||
options:
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
- "3.10"
|
||||
- "3.11"
|
||||
- "3.12"
|
||||
- "3.13"
|
||||
- "3.14"
|
||||
- "CPython main branch"
|
||||
validations:
|
||||
required: true
|
||||
|
2
.github/ISSUE_TEMPLATE/crash.yml
vendored
2
.github/ISSUE_TEMPLATE/crash.yml
vendored
@ -27,12 +27,12 @@ body:
|
||||
label: "CPython versions tested on:"
|
||||
multiple: true
|
||||
options:
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
- "3.10"
|
||||
- "3.11"
|
||||
- "3.12"
|
||||
- "3.13"
|
||||
- "3.14"
|
||||
- "CPython main branch"
|
||||
validations:
|
||||
required: true
|
||||
|
@ -461,6 +461,14 @@ class Bdb:
|
||||
return 'Line %s:%d does not exist' % (filename, lineno)
|
||||
self._add_to_breaks(filename, lineno)
|
||||
bp = Breakpoint(filename, lineno, temporary, cond, funcname)
|
||||
# After we set a new breakpoint, we need to search through all frames
|
||||
# and set f_trace to trace_dispatch if there could be a breakpoint in
|
||||
# that frame.
|
||||
frame = self.enterframe
|
||||
while frame:
|
||||
if self.break_anywhere(frame):
|
||||
frame.f_trace = self.trace_dispatch
|
||||
frame = frame.f_back
|
||||
return None
|
||||
|
||||
def _load_breaks(self):
|
||||
|
30
Lib/pdb.py
30
Lib/pdb.py
@ -82,6 +82,7 @@ import signal
|
||||
import inspect
|
||||
import textwrap
|
||||
import tokenize
|
||||
import itertools
|
||||
import traceback
|
||||
import linecache
|
||||
import _colorize
|
||||
@ -2433,8 +2434,6 @@ def main():
|
||||
parser.add_argument('-c', '--command', action='append', default=[], metavar='command', dest='commands',
|
||||
help='pdb commands to execute as if given in a .pdbrc file')
|
||||
parser.add_argument('-m', metavar='module', dest='module')
|
||||
parser.add_argument('args', nargs='*',
|
||||
help="when -m is not specified, the first arg is the script to debug")
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
# If no arguments were given (python -m pdb), print the whole help message.
|
||||
@ -2442,21 +2441,40 @@ def main():
|
||||
parser.print_help()
|
||||
sys.exit(2)
|
||||
|
||||
opts = parser.parse_args()
|
||||
opts, args = parser.parse_known_args()
|
||||
|
||||
if opts.module:
|
||||
# If a module is being debugged, we consider the arguments after "-m module" to
|
||||
# be potential arguments to the module itself. We need to parse the arguments
|
||||
# before "-m" to check if there is any invalid argument.
|
||||
# e.g. "python -m pdb -m foo --spam" means passing "--spam" to "foo"
|
||||
# "python -m pdb --spam -m foo" means passing "--spam" to "pdb" and is invalid
|
||||
idx = sys.argv.index('-m')
|
||||
args_to_pdb = sys.argv[1:idx]
|
||||
# This will raise an error if there are invalid arguments
|
||||
parser.parse_args(args_to_pdb)
|
||||
else:
|
||||
# If a script is being debugged, then pdb expects the script name as the first argument.
|
||||
# Anything before the script is considered an argument to pdb itself, which would
|
||||
# be invalid because it's not parsed by argparse.
|
||||
invalid_args = list(itertools.takewhile(lambda a: a.startswith('-'), args))
|
||||
if invalid_args:
|
||||
parser.error(f"unrecognized arguments: {' '.join(invalid_args)}")
|
||||
sys.exit(2)
|
||||
|
||||
if opts.module:
|
||||
file = opts.module
|
||||
target = _ModuleTarget(file)
|
||||
else:
|
||||
if not opts.args:
|
||||
if not args:
|
||||
parser.error("no module or script to run")
|
||||
file = opts.args.pop(0)
|
||||
file = args.pop(0)
|
||||
if file.endswith('.pyz'):
|
||||
target = _ZipTarget(file)
|
||||
else:
|
||||
target = _ScriptTarget(file)
|
||||
|
||||
sys.argv[:] = [file] + opts.args # Hide "pdb.py" and pdb options from argument list
|
||||
sys.argv[:] = [file] + args # Hide "pdb.py" and pdb options from argument list
|
||||
|
||||
# Note on saving/restoring sys.argv: it's a good idea when sys.argv was
|
||||
# modified by the script being debugged. It's a bad idea when it was
|
||||
|
@ -3089,6 +3089,7 @@ class PdbTestCase(unittest.TestCase):
|
||||
def run_pdb_script(self, script, commands,
|
||||
expected_returncode=0,
|
||||
extra_env=None,
|
||||
script_args=None,
|
||||
pdbrc=None,
|
||||
remove_home=False):
|
||||
"""Run 'script' lines with pdb and the pdb 'commands'."""
|
||||
@ -3106,7 +3107,9 @@ class PdbTestCase(unittest.TestCase):
|
||||
if remove_home:
|
||||
homesave = os.environ.pop('HOME', None)
|
||||
try:
|
||||
stdout, stderr = self._run_pdb([filename], commands, expected_returncode, extra_env)
|
||||
if script_args is None:
|
||||
script_args = []
|
||||
stdout, stderr = self._run_pdb([filename] + script_args, commands, expected_returncode, extra_env)
|
||||
finally:
|
||||
if homesave is not None:
|
||||
os.environ['HOME'] = homesave
|
||||
@ -3393,6 +3396,36 @@ def bœr():
|
||||
self.assertRegex(res, "Restarting .* with arguments:\na b c")
|
||||
self.assertRegex(res, "Restarting .* with arguments:\nd e f")
|
||||
|
||||
def test_issue58956(self):
|
||||
# Set a breakpoint in a function that already exists on the call stack
|
||||
# should enable the trace function for the frame.
|
||||
script = """
|
||||
import bar
|
||||
def foo():
|
||||
ret = bar.bar()
|
||||
pass
|
||||
foo()
|
||||
"""
|
||||
commands = """
|
||||
b bar.bar
|
||||
c
|
||||
b main.py:5
|
||||
c
|
||||
p ret
|
||||
quit
|
||||
"""
|
||||
bar = """
|
||||
def bar():
|
||||
return 42
|
||||
"""
|
||||
with open('bar.py', 'w') as f:
|
||||
f.write(textwrap.dedent(bar))
|
||||
self.addCleanup(os_helper.unlink, 'bar.py')
|
||||
stdout, stderr = self.run_pdb_script(script, commands)
|
||||
lines = stdout.splitlines()
|
||||
self.assertIn('-> pass', lines)
|
||||
self.assertIn('(Pdb) 42', lines)
|
||||
|
||||
def test_step_into_botframe(self):
|
||||
# gh-125422
|
||||
# pdb should not be able to step into the botframe (bdb.py)
|
||||
@ -3559,6 +3592,22 @@ def bœr():
|
||||
stdout, _ = self._run_pdb(["-m", "calendar", "1"], commands)
|
||||
self.assertIn("December", stdout)
|
||||
|
||||
stdout, _ = self._run_pdb(["-m", "calendar", "--type", "text"], commands)
|
||||
self.assertIn("December", stdout)
|
||||
|
||||
def test_run_script_with_args(self):
|
||||
script = """
|
||||
import sys
|
||||
print(sys.argv[1:])
|
||||
"""
|
||||
commands = """
|
||||
continue
|
||||
quit
|
||||
"""
|
||||
|
||||
stdout, stderr = self.run_pdb_script(script, commands, script_args=["--bar", "foo"])
|
||||
self.assertIn("['--bar', 'foo']", stdout)
|
||||
|
||||
def test_breakpoint(self):
|
||||
script = """
|
||||
if __name__ == '__main__':
|
||||
|
@ -0,0 +1 @@
|
||||
Fixed a bug in :mod:`pdb` where sometimes the breakpoint won't trigger if it was set on a function which is already in the call stack.
|
@ -0,0 +1 @@
|
||||
Fixed a bug in :mod:`pdb` where arguments starting with ``-`` can't be passed to the debugged script.
|
Loading…
Reference in New Issue
Block a user