From 8c6fb0514346ba85aac4187ca0e682a559774b72 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 5 Sep 2024 21:24:22 -0400 Subject: [PATCH 01/18] Only allow restart in command line mode --- Lib/pdb.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index 228de489a9cef1..5bf5840401737b 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -309,7 +309,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): _last_pdb_instance = None def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, - nosigint=False, readrc=True): + nosigint=False, readrc=True, allow_restart=False): bdb.Bdb.__init__(self, skip=skip) cmd.Cmd.__init__(self, completekey, stdin, stdout) sys.audit("pdb.Pdb") @@ -321,6 +321,7 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, self.mainpyfile = '' self._wait_for_mainpyfile = False self.tb_lineno = {} + self.allow_restart = allow_restart # Try to load readline if it exists try: import readline @@ -1607,6 +1608,10 @@ def do_run(self, arg): sys.argv. History, breakpoints, actions and debugger options are preserved. "restart" is an alias for "run". """ + if not self.allow_restart: + self.error('run/restart command is only allowed in command line usage:\n' + 'e.g. "python -m pdb myscript.py"') + return if arg: import shlex argv0 = sys.argv[0:1] @@ -2476,7 +2481,7 @@ def main(): # modified by the script being debugged. It's a bad idea when it was # changed by the user from the command line. There is a "restart" command # which allows explicit specification of command line arguments. - pdb = Pdb() + pdb = Pdb(allow_restart=True) pdb.rcLines.extend(opts.commands) while True: try: From 8a46e08e477871a062b373485c22083c2012cacf Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 01:35:14 +0000 Subject: [PATCH 02/18] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst diff --git a/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst b/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst new file mode 100644 index 00000000000000..924cee288c0621 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst @@ -0,0 +1 @@ +Only allow command line usage of :mod:`pdb` to use ``restart`` command. From 2342a348494a1d5a1c552e5df538a337a4938769 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Fri, 6 Sep 2024 21:23:19 -0400 Subject: [PATCH 03/18] Use an invocation type enum for restart check --- Lib/pdb.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index 5bf5840401737b..5c574151450bf1 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -73,6 +73,7 @@ import bdb import dis import code +import enum import glob import token import types @@ -99,6 +100,12 @@ class Restart(Exception): "post_mortem", "help"] +class PdbInvokeType(enum.Enum): + """Enum to specify the type of invocation for the debugger.""" + CommandLine = 1 + InlineBreakpoint = 2 + + def find_first_executable_line(code): """ Try to find the first executable line of the code object. @@ -309,7 +316,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): _last_pdb_instance = None def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, - nosigint=False, readrc=True, allow_restart=False): + nosigint=False, readrc=True, invoke_type=None): bdb.Bdb.__init__(self, skip=skip) cmd.Cmd.__init__(self, completekey, stdin, stdout) sys.audit("pdb.Pdb") @@ -321,7 +328,7 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, self.mainpyfile = '' self._wait_for_mainpyfile = False self.tb_lineno = {} - self.allow_restart = allow_restart + self.invoke_type = invoke_type # Try to load readline if it exists try: import readline @@ -1608,8 +1615,9 @@ def do_run(self, arg): sys.argv. History, breakpoints, actions and debugger options are preserved. "restart" is an alias for "run". """ - if not self.allow_restart: - self.error('run/restart command is only allowed in command line usage:\n' + if self.invoke_type == PdbInvokeType.InlineBreakpoint: + self.error('run/restart command is not allowed with inline breakpoints.\n' + 'Use the command line interface if you want to restart your program\n' 'e.g. "python -m pdb myscript.py"') return if arg: @@ -2366,7 +2374,7 @@ def set_trace(*, header=None): if Pdb._last_pdb_instance is not None: pdb = Pdb._last_pdb_instance else: - pdb = Pdb() + pdb = Pdb(invoke_type=PdbInvokeType.InlineBreakpoint) if header is not None: pdb.message(header) pdb.set_trace(sys._getframe().f_back) @@ -2481,7 +2489,7 @@ def main(): # modified by the script being debugged. It's a bad idea when it was # changed by the user from the command line. There is a "restart" command # which allows explicit specification of command line arguments. - pdb = Pdb(allow_restart=True) + pdb = Pdb(invoke_type=PdbInvokeType.CommandLine) pdb.rcLines.extend(opts.commands) while True: try: From 1d731c7f659863f0b5c19f9169bab3ac0f8b9b9d Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Fri, 6 Sep 2024 21:26:48 -0400 Subject: [PATCH 04/18] Add PdbInvokeType to __all__ --- Lib/pdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index 5c574151450bf1..dcde6d0b954da3 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -97,7 +97,7 @@ class Restart(Exception): pass __all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace", - "post_mortem", "help"] + "post_mortem", "help", "PdbInvokeType"] class PdbInvokeType(enum.Enum): From 78746ba7f99258968a793fc7343ba57534b59582 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Fri, 6 Sep 2024 21:44:53 -0400 Subject: [PATCH 05/18] Fix pyclbr test --- Lib/test/test_pyclbr.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 4bf0576586cca5..e791d9a185ef2f 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -233,8 +233,8 @@ def test_others(self): cm('sre_parse', ignore=('dump', 'groups', 'pos')) # from sre_constants import *; property cm( 'pdb', - # pyclbr does not handle elegantly `typing` or properties - ignore=('Union', '_ModuleTarget', '_ScriptTarget', '_ZipTarget'), + # pyclbr does not handle elegantly `typing` or properties or enum + ignore=('Union', '_ModuleTarget', '_ScriptTarget', '_ZipTarget', 'PdbInvokeType'), ) cm('pydoc', ignore=('input', 'output',)) # properties From 2b9e2253e8b1c7ea97bb927fd48455002d8cff33 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sat, 7 Sep 2024 13:17:03 -0400 Subject: [PATCH 06/18] Add unknown for invocation type --- Lib/pdb.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index dcde6d0b954da3..3b9b39ca7f4547 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -102,8 +102,9 @@ class Restart(Exception): class PdbInvokeType(enum.Enum): """Enum to specify the type of invocation for the debugger.""" - CommandLine = 1 - InlineBreakpoint = 2 + Unknown = "Unknown" + CommandLine = "CommandLine" + InlineBreakpoint = "InlineBreakpoint" def find_first_executable_line(code): @@ -316,7 +317,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): _last_pdb_instance = None def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, - nosigint=False, readrc=True, invoke_type=None): + nosigint=False, readrc=True, invoke_type=PdbInvokeType.Unknown): bdb.Bdb.__init__(self, skip=skip) cmd.Cmd.__init__(self, completekey, stdin, stdout) sys.audit("pdb.Pdb") From 420e498d55fa4848068ec1426abe9ccb90066f40 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 19 Sep 2024 22:20:56 -0400 Subject: [PATCH 07/18] Change the enum name and update docs/tests --- Doc/library/pdb.rst | 32 +++++++++++++++++++++++++++++++- Lib/pdb.py | 14 +++++++------- Lib/test/test_pdb.py | 22 ++++++++++++++++++++++ 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index d696161876e99d..dcf2b07841325c 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -192,7 +192,7 @@ The ``run*`` functions and :func:`set_trace` are aliases for instantiating the access further features, you have to do this yourself: .. class:: Pdb(completekey='tab', stdin=None, stdout=None, skip=None, \ - nosigint=False, readrc=True) + nosigint=False, readrc=True, invoke_origin=PdbInvokeOrigin.Unknown) :class:`Pdb` is the debugger class. @@ -211,6 +211,10 @@ access further features, you have to do this yourself: The *readrc* argument defaults to true and controls whether Pdb will load .pdbrc files from the filesystem. + The *invoke_origin* argument is used to determine the origin of the debugger. + It should be a value from the :class:`PdbInvokeOrigin` enumeration. The value + is used to determine whether certain commands are available or not. + Example call to enable tracing with *skip*:: import pdb; pdb.Pdb(skip=['django.*']).set_trace() @@ -227,6 +231,9 @@ access further features, you have to do this yourself: .. versionchanged:: 3.6 The *readrc* argument. + .. versionadded:: 3.14 + Added the *invoke_origin* argument. + .. method:: run(statement, globals=None, locals=None) runeval(expression, globals=None, locals=None) runcall(function, *args, **kwds) @@ -235,6 +242,25 @@ access further features, you have to do this yourself: See the documentation for the functions explained above. +.. class:: PdbInvokeOrigin + + An enumeration of the possible origins of the debugger invocation. + + .. attribute:: Unknown + + The origin of the debugger invocation is unknown. + + .. attribute:: CommandLine + + The origin of the debugger invocation is from the command line. + (e.g. ``python -m pdb script.py``) + + .. attribute:: InlineBreakpoint + + The origin of the debugger invocation is from an inline breakpoint. + (e.g. ``breakpoint()`` or ``import pdb; pdb.set_trace()``) + + .. _debugger-commands: Debugger Commands @@ -669,6 +695,10 @@ can be overridden by the local file. History, breakpoints, actions and debugger options are preserved. :pdbcmd:`restart` is an alias for :pdbcmd:`run`. + .. versionchanged:: 3.14 + :pdbcmd:`run` and :pdbcmd:`restart` commands are not allowed when the + debugger is invoked from an inline breakpoint. + .. pdbcommand:: q(uit) Quit from the debugger. The program being executed is aborted. diff --git a/Lib/pdb.py b/Lib/pdb.py index 3b9b39ca7f4547..937c9970de4f68 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -97,10 +97,10 @@ class Restart(Exception): pass __all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace", - "post_mortem", "help", "PdbInvokeType"] + "post_mortem", "help", "PdbInvokeOrigin"] -class PdbInvokeType(enum.Enum): +class PdbInvokeOrigin(enum.Enum): """Enum to specify the type of invocation for the debugger.""" Unknown = "Unknown" CommandLine = "CommandLine" @@ -317,7 +317,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): _last_pdb_instance = None def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, - nosigint=False, readrc=True, invoke_type=PdbInvokeType.Unknown): + nosigint=False, readrc=True, invoke_origin=PdbInvokeOrigin.Unknown): bdb.Bdb.__init__(self, skip=skip) cmd.Cmd.__init__(self, completekey, stdin, stdout) sys.audit("pdb.Pdb") @@ -329,7 +329,7 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, self.mainpyfile = '' self._wait_for_mainpyfile = False self.tb_lineno = {} - self.invoke_type = invoke_type + self.invoke_origin = invoke_origin # Try to load readline if it exists try: import readline @@ -1616,7 +1616,7 @@ def do_run(self, arg): sys.argv. History, breakpoints, actions and debugger options are preserved. "restart" is an alias for "run". """ - if self.invoke_type == PdbInvokeType.InlineBreakpoint: + if self.invoke_origin == PdbInvokeOrigin.InlineBreakpoint: self.error('run/restart command is not allowed with inline breakpoints.\n' 'Use the command line interface if you want to restart your program\n' 'e.g. "python -m pdb myscript.py"') @@ -2375,7 +2375,7 @@ def set_trace(*, header=None): if Pdb._last_pdb_instance is not None: pdb = Pdb._last_pdb_instance else: - pdb = Pdb(invoke_type=PdbInvokeType.InlineBreakpoint) + pdb = Pdb(invoke_origin=PdbInvokeOrigin.InlineBreakpoint) if header is not None: pdb.message(header) pdb.set_trace(sys._getframe().f_back) @@ -2490,7 +2490,7 @@ def main(): # modified by the script being debugged. It's a bad idea when it was # changed by the user from the command line. There is a "restart" command # which allows explicit specification of command line arguments. - pdb = Pdb(invoke_type=PdbInvokeType.CommandLine) + pdb = Pdb(invoke_origin=PdbInvokeOrigin.CommandLine) pdb.rcLines.extend(opts.commands) while True: try: diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index db7d1b1e9cd935..4bd590bd6f0031 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -901,6 +901,28 @@ def test_pdb_where_command(): (Pdb) continue """ +def test_pdb_restart_command(): + """Test restart command + + >>> def test_function(): + ... from pdb import Pdb, PdbInvokeOrigin; + ... Pdb(nosigint=True, readrc=False, invoke_origin=PdbInvokeOrigin.InlineBreakpoint).set_trace() + ... x = 1 + + >>> with PdbTestInput([ # doctest: +ELLIPSIS + ... 'restart', + ... 'continue', + ... ]): + ... test_function() + > (3)test_function() + -> Pdb(nosigint=True, readrc=False, invoke_origin=PdbInvokeOrigin.InlineBreakpoint).set_trace() + (Pdb) restart + *** run/restart command is not allowed with inline breakpoints. + Use the command line interface if you want to restart your program + e.g. "python -m pdb myscript.py" + (Pdb) continue + """ + # skip this test if sys.flags.no_site = True; # exit() isn't defined unless there's a site module. From a49a13e993debc185766a81350831a93ddc3aaf7 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 19 Sep 2024 22:22:31 -0400 Subject: [PATCH 08/18] Update news --- .../next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst b/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst index 924cee288c0621..9d1046d687333f 100644 --- a/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst +++ b/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst @@ -1 +1 @@ -Only allow command line usage of :mod:`pdb` to use ``restart`` command. +Added a new argument ``invoke_origin`` to :class:`pdb.Pdb`. Only allow :mod:`pdb` from command line to use ``restart`` command. From a4b995e58eaa63a375745bd0520245e6655f0703 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Fri, 20 Sep 2024 01:09:20 -0400 Subject: [PATCH 09/18] Fix test_pyclbr.py --- Lib/test/test_pyclbr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index e791d9a185ef2f..cbce669c64bfd2 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -234,7 +234,7 @@ def test_others(self): cm( 'pdb', # pyclbr does not handle elegantly `typing` or properties or enum - ignore=('Union', '_ModuleTarget', '_ScriptTarget', '_ZipTarget', 'PdbInvokeType'), + ignore=('Union', '_ModuleTarget', '_ScriptTarget', '_ZipTarget', 'PdbInvokeOrigin'), ) cm('pydoc', ignore=('input', 'output',)) # properties From 03f91dc62c8a265d7ffb27f33165f88e2711a7f6 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 24 Sep 2024 09:56:05 -0700 Subject: [PATCH 10/18] Use simple strings for mode --- Doc/library/pdb.rst | 29 +++++------------------------ Lib/pdb.py | 20 ++++++-------------- Lib/test/test_pdb.py | 7 +++---- 3 files changed, 14 insertions(+), 42 deletions(-) diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index dcf2b07841325c..ba41117b1c6327 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -192,7 +192,7 @@ The ``run*`` functions and :func:`set_trace` are aliases for instantiating the access further features, you have to do this yourself: .. class:: Pdb(completekey='tab', stdin=None, stdout=None, skip=None, \ - nosigint=False, readrc=True, invoke_origin=PdbInvokeOrigin.Unknown) + nosigint=False, readrc=True, mode=None) :class:`Pdb` is the debugger class. @@ -211,9 +211,9 @@ access further features, you have to do this yourself: The *readrc* argument defaults to true and controls whether Pdb will load .pdbrc files from the filesystem. - The *invoke_origin* argument is used to determine the origin of the debugger. - It should be a value from the :class:`PdbInvokeOrigin` enumeration. The value - is used to determine whether certain commands are available or not. + The *mode* argument is used to indicate the origin of the debugger. + It should be either ``None``, ``'inline'`` or ``'cli'``. It impacts + the workings of some debugger commands. Example call to enable tracing with *skip*:: @@ -232,7 +232,7 @@ access further features, you have to do this yourself: The *readrc* argument. .. versionadded:: 3.14 - Added the *invoke_origin* argument. + Added the *mode* argument. .. method:: run(statement, globals=None, locals=None) runeval(expression, globals=None, locals=None) @@ -242,25 +242,6 @@ access further features, you have to do this yourself: See the documentation for the functions explained above. -.. class:: PdbInvokeOrigin - - An enumeration of the possible origins of the debugger invocation. - - .. attribute:: Unknown - - The origin of the debugger invocation is unknown. - - .. attribute:: CommandLine - - The origin of the debugger invocation is from the command line. - (e.g. ``python -m pdb script.py``) - - .. attribute:: InlineBreakpoint - - The origin of the debugger invocation is from an inline breakpoint. - (e.g. ``breakpoint()`` or ``import pdb; pdb.set_trace()``) - - .. _debugger-commands: Debugger Commands diff --git a/Lib/pdb.py b/Lib/pdb.py index 937c9970de4f68..7f9960598e700c 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -73,7 +73,6 @@ import bdb import dis import code -import enum import glob import token import types @@ -97,14 +96,7 @@ class Restart(Exception): pass __all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace", - "post_mortem", "help", "PdbInvokeOrigin"] - - -class PdbInvokeOrigin(enum.Enum): - """Enum to specify the type of invocation for the debugger.""" - Unknown = "Unknown" - CommandLine = "CommandLine" - InlineBreakpoint = "InlineBreakpoint" + "post_mortem", "help"] def find_first_executable_line(code): @@ -317,7 +309,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): _last_pdb_instance = None def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, - nosigint=False, readrc=True, invoke_origin=PdbInvokeOrigin.Unknown): + nosigint=False, readrc=True, mode=None): bdb.Bdb.__init__(self, skip=skip) cmd.Cmd.__init__(self, completekey, stdin, stdout) sys.audit("pdb.Pdb") @@ -329,7 +321,7 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, self.mainpyfile = '' self._wait_for_mainpyfile = False self.tb_lineno = {} - self.invoke_origin = invoke_origin + self.mode = mode # Try to load readline if it exists try: import readline @@ -1616,7 +1608,7 @@ def do_run(self, arg): sys.argv. History, breakpoints, actions and debugger options are preserved. "restart" is an alias for "run". """ - if self.invoke_origin == PdbInvokeOrigin.InlineBreakpoint: + if self.mode == 'inline': self.error('run/restart command is not allowed with inline breakpoints.\n' 'Use the command line interface if you want to restart your program\n' 'e.g. "python -m pdb myscript.py"') @@ -2375,7 +2367,7 @@ def set_trace(*, header=None): if Pdb._last_pdb_instance is not None: pdb = Pdb._last_pdb_instance else: - pdb = Pdb(invoke_origin=PdbInvokeOrigin.InlineBreakpoint) + pdb = Pdb(mode='inline') if header is not None: pdb.message(header) pdb.set_trace(sys._getframe().f_back) @@ -2490,7 +2482,7 @@ def main(): # modified by the script being debugged. It's a bad idea when it was # changed by the user from the command line. There is a "restart" command # which allows explicit specification of command line arguments. - pdb = Pdb(invoke_origin=PdbInvokeOrigin.CommandLine) + pdb = Pdb(mode='cli') pdb.rcLines.extend(opts.commands) while True: try: diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 4bd590bd6f0031..efb84eb0c6fb8a 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -905,8 +905,7 @@ def test_pdb_restart_command(): """Test restart command >>> def test_function(): - ... from pdb import Pdb, PdbInvokeOrigin; - ... Pdb(nosigint=True, readrc=False, invoke_origin=PdbInvokeOrigin.InlineBreakpoint).set_trace() + ... import pdb; pdb.Pdb(nosigint=True, readrc=False, mode='inline').set_trace() ... x = 1 >>> with PdbTestInput([ # doctest: +ELLIPSIS @@ -914,8 +913,8 @@ def test_pdb_restart_command(): ... 'continue', ... ]): ... test_function() - > (3)test_function() - -> Pdb(nosigint=True, readrc=False, invoke_origin=PdbInvokeOrigin.InlineBreakpoint).set_trace() + > (2)test_function() + -> import pdb; pdb.Pdb(nosigint=True, readrc=False, mode='inline').set_trace() (Pdb) restart *** run/restart command is not allowed with inline breakpoints. Use the command line interface if you want to restart your program From 8284118c69395857ca38bf7fc6b74a9606bd9a33 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 24 Sep 2024 09:57:43 -0700 Subject: [PATCH 11/18] Revert changes to test_pyclbr --- Lib/test/test_pyclbr.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index cbce669c64bfd2..4bf0576586cca5 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -233,8 +233,8 @@ def test_others(self): cm('sre_parse', ignore=('dump', 'groups', 'pos')) # from sre_constants import *; property cm( 'pdb', - # pyclbr does not handle elegantly `typing` or properties or enum - ignore=('Union', '_ModuleTarget', '_ScriptTarget', '_ZipTarget', 'PdbInvokeOrigin'), + # pyclbr does not handle elegantly `typing` or properties + ignore=('Union', '_ModuleTarget', '_ScriptTarget', '_ZipTarget'), ) cm('pydoc', ignore=('input', 'output',)) # properties From 162c53cdb54658f0a9fd9a73d774b9530061775b Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 24 Sep 2024 09:58:22 -0700 Subject: [PATCH 12/18] Update 2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst --- .../next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst b/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst index 9d1046d687333f..258dd591fce767 100644 --- a/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst +++ b/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst @@ -1 +1 @@ -Added a new argument ``invoke_origin`` to :class:`pdb.Pdb`. Only allow :mod:`pdb` from command line to use ``restart`` command. +Added a new argument ``mode`` to :class:`pdb.Pdb`. Only allow :mod:`pdb` from command line to use ``restart`` command. From f9d01f910409a4eff1cf5458bf37609185c36e92 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 24 Sep 2024 12:44:15 -0700 Subject: [PATCH 13/18] Update docs Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> --- Doc/library/pdb.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index ba41117b1c6327..e4ff7a7e885e7b 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -211,9 +211,12 @@ access further features, you have to do this yourself: The *readrc* argument defaults to true and controls whether Pdb will load .pdbrc files from the filesystem. - The *mode* argument is used to indicate the origin of the debugger. - It should be either ``None``, ``'inline'`` or ``'cli'``. It impacts - the workings of some debugger commands. + The *mode* argument specifies how the debugger was invoked. + It impacts the workings of some debugger commands. + Valid values are ``'inline'`` (when called from the breakpoint() builtin), + ``'cli'`` (when called from a command line invocation) + or ``None`` (for backwards compatible behaviour, as before the *mode* + argument was added). Example call to enable tracing with *skip*:: From 0265d90b07616d5aeee9e7d6354649393f238d21 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 24 Sep 2024 21:47:10 -0700 Subject: [PATCH 14/18] Update error messages 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 7f9960598e700c..ad1ee6c09f7390 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1609,8 +1609,8 @@ def do_run(self, arg): are preserved. "restart" is an alias for "run". """ if self.mode == 'inline': - self.error('run/restart command is not allowed with inline breakpoints.\n' - 'Use the command line interface if you want to restart your program\n' + self.error('run/restart command is disabled in inline breakpoints.\n' + 'Use the command line interface to enable restarting your program\n' 'e.g. "python -m pdb myscript.py"') return if arg: From c50b03995a092e414a5285da3a87766727b7f335 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Wed, 25 Sep 2024 09:58:57 -0700 Subject: [PATCH 15/18] Update docs Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> --- Doc/library/pdb.rst | 8 ++++---- Lib/pdb.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 3924b5deb2fcc9..1682eb0fbea42d 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -219,8 +219,8 @@ access further features, you have to do this yourself: The *mode* argument specifies how the debugger was invoked. It impacts the workings of some debugger commands. - Valid values are ``'inline'`` (when called from the breakpoint() builtin), - ``'cli'`` (when called from a command line invocation) + Valid values are ``'inline'`` (used by the breakpoint() builtin), + ``'cli'`` (used by the command line invocation) or ``None`` (for backwards compatible behaviour, as before the *mode* argument was added). @@ -686,8 +686,8 @@ can be overridden by the local file. :pdbcmd:`restart` is an alias for :pdbcmd:`run`. .. versionchanged:: 3.14 - :pdbcmd:`run` and :pdbcmd:`restart` commands are not allowed when the - debugger is invoked from an inline breakpoint. + :pdbcmd:`run` and :pdbcmd:`restart` commands are disabled when the + debugger is invoked in ``'inline'`` mode. .. pdbcommand:: q(uit) diff --git a/Lib/pdb.py b/Lib/pdb.py index 2f02e2299cdc60..443160eaaae887 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1613,7 +1613,7 @@ def do_run(self, arg): are preserved. "restart" is an alias for "run". """ if self.mode == 'inline': - self.error('run/restart command is disabled in inline breakpoints.\n' + self.error('run/restart command is disabled when pdb is running in inline mode.\n' 'Use the command line interface to enable restarting your program\n' 'e.g. "python -m pdb myscript.py"') return From 27f065689c86391d9e4ac7953acfad35aa531992 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Wed, 25 Sep 2024 10:00:12 -0700 Subject: [PATCH 16/18] Update test to match the error message --- 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 914c0c6ccef1cb..84c0e1073a1054 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -916,7 +916,7 @@ def test_pdb_restart_command(): > (2)test_function() -> import pdb; pdb.Pdb(nosigint=True, readrc=False, mode='inline').set_trace() (Pdb) restart - *** run/restart command is disabled in inline breakpoints. + *** run/restart command is disabled when pdb is running in inline mode. Use the command line interface to enable restarting your program e.g. "python -m pdb myscript.py" (Pdb) continue From 7281465250d789f7b0e05539e6e5ad91c23236b4 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Wed, 25 Sep 2024 10:03:43 -0700 Subject: [PATCH 17/18] Add whatsnew entry to the change --- Doc/whatsnew/3.14.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 5acb9bfe18b2d0..7752ee9adadea3 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -318,6 +318,9 @@ pdb :pdbcmd:`commands` are preserved across hard-coded breakpoints. (Contributed by Tian Gao in :gh:`121450`.) +* Added a new argument ``mode`` to :class:`pdb.Pdb`. Disabled ``restart`` + command when :mod:`pdb` is in ``inline`` mode. + (Contributed by Tian Gao in :gh:`123757`.) pickle ------ From 3ce16ec83932cf5186cd288f3e5253686be0ec3a Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Wed, 25 Sep 2024 10:33:03 -0700 Subject: [PATCH 18/18] Remove trailing space --- Doc/whatsnew/3.14.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 7752ee9adadea3..4d22f7ac58a5b7 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -319,7 +319,7 @@ pdb (Contributed by Tian Gao in :gh:`121450`.) * Added a new argument ``mode`` to :class:`pdb.Pdb`. Disabled ``restart`` - command when :mod:`pdb` is in ``inline`` mode. + command when :mod:`pdb` is in ``inline`` mode. (Contributed by Tian Gao in :gh:`123757`.) pickle