From f17462cfb639c42c6bfe8c9c253b409ae54b3462 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sun, 13 Oct 2024 22:02:18 -0400 Subject: [PATCH 1/6] Pass unknown pdb command line args to script instead of fail --- Lib/pdb.py | 20 ++++++++++++++------ Lib/test/test_pdb.py | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index aea6fb70ae3106..003337ba2dbedf 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -2435,8 +2435,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. @@ -2444,21 +2442,31 @@ def main(): parser.print_help() sys.exit(2) - opts = parser.parse_args() + opts, args = parser.parse_known_args() + + invalid_args = [] + for arg in args: + if not arg.startswith('-'): + break + invalid_args.append(arg) + + 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 diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 4c64a800cb32d2..37124947ebfead 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3052,6 +3052,7 @@ def _run_pdb(self, pdb_args, commands, 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'.""" @@ -3069,7 +3070,9 @@ def run_pdb_script(self, script, commands, 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 @@ -3508,6 +3511,19 @@ def test_run_module_with_args(self): stdout, _ = self._run_pdb(["-m", "calendar", "1"], 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__': From 8e8bbd55f80d9bacda6cade3126fc171775097ba Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 02:07:48 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst diff --git a/Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst b/Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst new file mode 100644 index 00000000000000..455c38c6921f22 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst @@ -0,0 +1 @@ +Fixed a bug in :mod:`pdb` where arguments starting with `-` can't be passed to the debugged script. From 1f4004047f8734cef5eceec62ce7357504cc9c22 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sun, 13 Oct 2024 22:23:25 -0400 Subject: [PATCH 3/6] Update 2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst --- .../next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst b/Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst index 455c38c6921f22..3583d537a6ec61 100644 --- a/Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst +++ b/Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst @@ -1 +1 @@ -Fixed a bug in :mod:`pdb` where arguments starting with `-` can't be passed to the debugged script. +Fixed a bug in :mod:`pdb` where arguments starting with ``-`` can't be passed to the debugged script. From 160bab69f96af1a072e73c75e1175f2660504dc8 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 15 Oct 2024 11:40:53 -0400 Subject: [PATCH 4/6] Make arguments starting with - work with modules as well --- Lib/pdb.py | 30 ++++++++++++++++++++++-------- Lib/test/test_pdb.py | 3 +++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index 003337ba2dbedf..947635f921bf97 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -2444,15 +2444,29 @@ def main(): opts, args = parser.parse_known_args() - invalid_args = [] - for arg in args: - if not arg.startswith('-'): - break - invalid_args.append(arg) + 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 automatically raise an error if there are invalid arguments + parser.parse_args(args_to_pdb) + else: + # If a script is being debugged, then pdb expects a script 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 = [] + for arg in args: + if not arg.startswith('-'): + break + invalid_args.append(arg) - if invalid_args: - parser.error(f"unrecognized arguments: {' '.join(invalid_args)}") - sys.exit(2) + if invalid_args: + parser.error(f"unrecognized arguments: {' '.join(invalid_args)}") + sys.exit(2) if opts.module: file = opts.module diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 37124947ebfead..0d7bb6c83dd3b7 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3511,6 +3511,9 @@ def test_run_module_with_args(self): 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 From 36dcdd0004218dd8123e0eea96aac85498492bf7 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 15 Oct 2024 14:04:58 -0400 Subject: [PATCH 5/6] Update comments Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> --- Lib/pdb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index 947635f921bf97..c65d2b1931dd1f 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -2452,10 +2452,10 @@ def main(): # "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 automatically raise an error if there are invalid arguments + # 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 a script as the first argument. + # 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 = [] From aac3cf6c0dd04455651494cc6a02b5c959689b21 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 15 Oct 2024 14:32:27 -0400 Subject: [PATCH 6/6] Use takewhile for arguments --- Lib/pdb.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index c65d2b1931dd1f..4e9578de3f5f55 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -82,6 +82,7 @@ import inspect import textwrap import tokenize +import itertools import traceback import linecache import _colorize @@ -2458,12 +2459,7 @@ def main(): # 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 = [] - for arg in args: - if not arg.startswith('-'): - break - invalid_args.append(arg) - + invalid_args = list(itertools.takewhile(lambda a: a.startswith('-'), args)) if invalid_args: parser.error(f"unrecognized arguments: {' '.join(invalid_args)}") sys.exit(2)