]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-117618: Make package.module searchable for breakpoints and clean up docs (#117619)
authorTian Gao <gaogaotiantian@hotmail.com>
Tue, 30 Apr 2024 18:18:01 +0000 (11:18 -0700)
committerGitHub <noreply@github.com>
Tue, 30 Apr 2024 18:18:01 +0000 (18:18 +0000)
Doc/library/pdb.rst
Lib/pdb.py
Lib/test/test_pdb.py
Misc/NEWS.d/next/Library/2024-04-08-03-23-22.gh-issue-117618.-4DCUw.rst [new file with mode: 0644]

index ac3007f70c3534dddc1a4b52b201af0a6865c0be..a640976493caba846cb8e664850f2bf3ee80caca 100644 (file)
@@ -328,12 +328,16 @@ can be overridden by the local file.
 
 .. pdbcommand:: b(reak) [([filename:]lineno | function) [, condition]]
 
-   With a *lineno* argument, set a break there in the current file.  With a
-   *function* argument, set a break at the first executable statement within
-   that function.  The line number may be prefixed with a filename and a colon,
-   to specify a breakpoint in another file (probably one that hasn't been loaded
-   yet).  The file is searched on :data:`sys.path`.  Note that each breakpoint
-   is assigned a number to which all the other breakpoint commands refer.
+   With a *lineno* argument, set a break at line *lineno* in the current file.
+   The line number may be prefixed with a *filename* and a colon,
+   to specify a breakpoint in another file (possibly one that hasn't been loaded
+   yet).  The file is searched on :data:`sys.path`.  Accepatable forms of *filename*
+   are ``/abspath/to/file.py``, ``relpath/file.py``, ``module`` and
+   ``package.module``.
+
+   With a *function* argument, set a break at the first executable statement within
+   that function. *function* can be any expression that evaluates to a function
+   in the current namespace.
 
    If a second argument is present, it is an expression which must evaluate to
    true before the breakpoint is honored.
@@ -342,6 +346,9 @@ can be overridden by the local file.
    of times that breakpoint has been hit, the current ignore count, and the
    associated condition if any.
 
+   Each breakpoint is assigned a number to which all the other
+   breakpoint commands refer.
+
 .. pdbcommand:: tbreak [([filename:]lineno | function) [, condition]]
 
    Temporary breakpoint, which is removed automatically when it is first hit.
index d4138b95d3c33223630069f82d8973fb6b54d013..fa2e1ec94be2358cafb6167ecc92f4493929a137 100755 (executable)
@@ -2007,17 +2007,23 @@ class Pdb(bdb.Bdb, cmd.Cmd):
 
         lookupmodule() translates (possibly incomplete) file or module name
         into an absolute file name.
+
+        filename could be in format of:
+            * an absolute path like '/path/to/file.py'
+            * a relative path like 'file.py' or 'dir/file.py'
+            * a module name like 'module' or 'package.module'
+
+        files and modules will be searched in sys.path.
         """
-        if os.path.isabs(filename) and  os.path.exists(filename):
-            return filename
-        f = os.path.join(sys.path[0], filename)
-        if  os.path.exists(f) and self.canonic(f) == self.mainpyfile:
-            return f
-        root, ext = os.path.splitext(filename)
-        if ext == '':
-            filename = filename + '.py'
+        if not filename.endswith('.py'):
+            # A module is passed in so convert it to equivalent file
+            filename = filename.replace('.', os.sep) + '.py'
+
         if os.path.isabs(filename):
-            return filename
+            if os.path.exists(filename):
+                return filename
+            return None
+
         for dirname in sys.path:
             while os.path.islink(dirname):
                 dirname = os.readlink(dirname)
index 2d057e2647f13c4841d3fee987aaaedf8a0a62ef..5635d17c99d2a329069e38ea1cf525387ca4378e 100644 (file)
@@ -354,6 +354,46 @@ def test_pdb_breakpoint_commands():
     4
     """
 
+def test_pdb_breakpoint_with_filename():
+    """Breakpoints with filename:lineno
+
+    >>> def test_function():
+    ...     # inspect_fodder2 is a great module as the line number is stable
+    ...     from test.test_inspect import inspect_fodder2 as mod2
+    ...     import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+    ...     mod2.func88()
+    ...     mod2.func114()
+    ...     # Be a good citizen and clean up the mess
+    ...     reset_Breakpoint()
+
+    First, need to clear bdb state that might be left over from previous tests.
+    Otherwise, the new breakpoints might get assigned different numbers.
+
+    >>> reset_Breakpoint()
+
+    >>> with PdbTestInput([  # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+    ...     'break test.test_inspect.inspect_fodder2:90',
+    ...     'continue', # will stop at func88
+    ...     'break test/test_inspect/inspect_fodder2.py:115',
+    ...     'continue', # will stop at func114
+    ...     'continue',
+    ... ]):
+    ...    test_function()
+    > <doctest test.test_pdb.test_pdb_breakpoint_with_filename[0]>(5)test_function()
+    -> mod2.func88()
+    (Pdb) break test.test_inspect.inspect_fodder2:90
+    Breakpoint 1 at ...inspect_fodder2.py:90
+    (Pdb) continue
+    > ...inspect_fodder2.py(90)func88()
+    -> return 90
+    (Pdb) break test/test_inspect/inspect_fodder2.py:115
+    Breakpoint 2 at ...inspect_fodder2.py:115
+    (Pdb) continue
+    > ...inspect_fodder2.py(115)func114()
+    -> return 115
+    (Pdb) continue
+    """
+
 def test_pdb_breakpoints_preserved_across_interactive_sessions():
     """Breakpoints are remembered between interactive sessions
 
diff --git a/Misc/NEWS.d/next/Library/2024-04-08-03-23-22.gh-issue-117618.-4DCUw.rst b/Misc/NEWS.d/next/Library/2024-04-08-03-23-22.gh-issue-117618.-4DCUw.rst
new file mode 100644 (file)
index 0000000..569c5d5
--- /dev/null
@@ -0,0 +1 @@
+Support ``package.module`` as ``filename`` for ``break`` command of :mod:`pdb`