From 137f5932bb4b45268389e9ad648f44e4e54e8c8e Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Mon, 17 Feb 2025 15:58:50 -0500 Subject: [PATCH 1/4] Show explicit errors when required arguments of pdb commands are missing --- Lib/pdb.py | 35 ++++++++++++++++++++++++++++++++++- Lib/test/test_pdb.py | 8 ++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index 4abf216b773780..cf0fa66e2f0c8b 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1286,6 +1286,9 @@ def do_enable(self, arg): Enables the breakpoints given as a space separated list of breakpoint numbers. """ + if not arg: + self._print_invalid_arg(arg) + return args = arg.split() for i in args: try: @@ -1307,6 +1310,9 @@ def do_disable(self, arg): breakpoint, it remains in the list of breakpoints and can be (re-)enabled. """ + if not arg: + self._print_invalid_arg(arg) + return args = arg.split() for i in args: try: @@ -1327,6 +1333,9 @@ def do_condition(self, arg): condition is absent, any existing condition is removed; i.e., the breakpoint is made unconditional. """ + if not arg: + self._print_invalid_arg(arg) + return args = arg.split(' ', 1) try: cond = args[1] @@ -1360,6 +1369,9 @@ def do_ignore(self, arg): and the breakpoint is not disabled and any associated condition evaluates to true. """ + if not arg: + self._print_invalid_arg(arg) + return args = arg.split() if not args: self.error('Breakpoint number expected') @@ -1690,6 +1702,9 @@ def do_jump(self, arg): instance it is not possible to jump into the middle of a for loop or out of a finally clause. """ + if not arg: + self._print_invalid_arg(arg) + return if self.curindex + 1 != len(self.stack): self.error('You can only jump within the bottom frame') return @@ -1715,6 +1730,9 @@ def do_debug(self, arg): argument (which is an arbitrary expression or statement to be executed in the current environment). """ + if not arg: + self._print_invalid_arg(arg) + return sys.settrace(None) globals = self.curframe.f_globals locals = self.curframe.f_locals @@ -1840,6 +1858,9 @@ def do_p(self, arg): Print the value of the expression. """ + if not arg: + self._print_invalid_arg(arg) + return self._msg_val_func(arg, repr) def do_pp(self, arg): @@ -1847,6 +1868,9 @@ def do_pp(self, arg): Pretty-print the value of the expression. """ + if not arg: + self._print_invalid_arg(arg) + return self._msg_val_func(arg, pprint.pformat) complete_print = _complete_expression @@ -1935,6 +1959,9 @@ def do_source(self, arg): Try to get source code for the given object and display it. """ + if not arg: + self._print_invalid_arg(arg) + return try: obj = self._getval(arg) except: @@ -1974,6 +2001,9 @@ def do_whatis(self, arg): Print the type of the argument. """ + if not arg: + self._print_invalid_arg(arg) + return try: value = self._getval(arg) except: @@ -2318,7 +2348,10 @@ def _help_message_from_doc(self, doc, usage_only=False): def _print_invalid_arg(self, arg): """Return the usage string for a function.""" - self.error(f"Invalid argument: {arg}") + if not arg: + self.error("Argument is required for this command") + else: + self.error(f"Invalid argument: {arg}") # Yes it's a bit hacky. Get the caller name, get the method based on # that name, and get the docstring from that method. diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 4d371a6e754b96..2223baaa38701f 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1762,6 +1762,8 @@ def test_pdb_invalid_arg(): ... 'a = 3', ... 'll 4', ... 'step 1', + ... 'p', + ... 'enable ', ... 'continue' ... ]): ... test_function() @@ -1776,6 +1778,12 @@ def test_pdb_invalid_arg(): (Pdb) step 1 *** Invalid argument: 1 Usage: s(tep) + (Pdb) p + *** Argument is required for this command + Usage: p expression + (Pdb) enable + *** Argument is required for this command + Usage: enable bpnumber [bpnumber ...] (Pdb) continue """ From 3fcd198bdb8584332d3411aa2b0bab95628ff56d Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 21:01:31 +0000 Subject: [PATCH 2/4] =?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/2025-02-17-21-01-25.gh-issue-126944.49YTHZ.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-02-17-21-01-25.gh-issue-126944.49YTHZ.rst diff --git a/Misc/NEWS.d/next/Library/2025-02-17-21-01-25.gh-issue-126944.49YTHZ.rst b/Misc/NEWS.d/next/Library/2025-02-17-21-01-25.gh-issue-126944.49YTHZ.rst new file mode 100644 index 00000000000000..afc3ab777646cb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-02-17-21-01-25.gh-issue-126944.49YTHZ.rst @@ -0,0 +1 @@ +Show explicit errors when required arguments of :mod:`pdb` commands are missing From 85b2f5d11ed6de102258c8c5b413ccfef82d2914 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Mon, 17 Feb 2025 16:02:05 -0500 Subject: [PATCH 3/4] Remove extra spaces --- Lib/test/test_pdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 2223baaa38701f..6891e0f9fe8bfe 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1781,7 +1781,7 @@ def test_pdb_invalid_arg(): (Pdb) p *** Argument is required for this command Usage: p expression - (Pdb) enable + (Pdb) enable *** Argument is required for this command Usage: enable bpnumber [bpnumber ...] (Pdb) continue From 6a9041cca3e17ee1be2bd551c911a89781fb605e Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Mon, 17 Feb 2025 16:19:26 -0500 Subject: [PATCH 4/4] Fix test --- Lib/test/test_pdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 6891e0f9fe8bfe..7e8bd73625bb4a 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1758,7 +1758,7 @@ def test_pdb_invalid_arg(): >>> def test_function(): ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() - >>> with PdbTestInput([ + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE ... 'a = 3', ... 'll 4', ... 'step 1',