]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-103956: Fix `trace` output in case of missing source line (GH-103958)
authorRadislav Chugunov <52372310+chgnrdv@users.noreply.github.com>
Thu, 9 May 2024 12:09:44 +0000 (15:09 +0300)
committerGitHub <noreply@github.com>
Thu, 9 May 2024 12:09:44 +0000 (12:09 +0000)
Print only filename with lineno if linecache.getline() returns an empty string.

Lib/test/test_trace.py
Lib/trace.py
Misc/NEWS.d/next/Library/2023-04-28-09-54-15.gh-issue-103956.EyLDPS.rst [new file with mode: 0644]

index c1e289bcaff9e5e24874d3aad56c18323bb00bcb..93966ee31d0a0176bac9f1f17ce69b611b8fb61f 100644 (file)
@@ -6,6 +6,7 @@ from test.support.os_helper import (TESTFN, rmtree, unlink)
 from test.support.script_helper import assert_python_ok, assert_python_failure
 import textwrap
 import unittest
+from types import FunctionType
 
 import trace
 from trace import Trace
@@ -559,5 +560,29 @@ class TestCommandLine(unittest.TestCase):
         assert_python_failure('-m', 'trace', '-l', '--module', 'not_a_module_zzz')
 
 
+class TestTrace(unittest.TestCase):
+    def setUp(self):
+        self.addCleanup(sys.settrace, sys.gettrace())
+        self.tracer = Trace(count=0, trace=1)
+        self.filemod = my_file_and_modname()
+
+    def test_no_source_file(self):
+        filename = "<unknown>"
+        co = traced_func_linear.__code__
+        co = co.replace(co_filename=filename)
+        f = FunctionType(co, globals())
+
+        with captured_stdout() as out:
+            self.tracer.runfunc(f, 2, 3)
+
+        out = out.getvalue().splitlines()
+        firstlineno = get_firstlineno(f)
+        self.assertIn(f" --- modulename: {self.filemod[1]}, funcname: {f.__code__.co_name}", out[0])
+        self.assertIn(f"{filename}({firstlineno + 1})", out[1])
+        self.assertIn(f"{filename}({firstlineno + 2})", out[2])
+        self.assertIn(f"{filename}({firstlineno + 3})", out[3])
+        self.assertIn(f"{filename}({firstlineno + 4})", out[4])
+
+
 if __name__ == '__main__':
     unittest.main()
index 7886959fa64f68422f8c26e62064e7f661b347ec..64fc8037e355ee7a1672c020ab98173a75f4bef3 100755 (executable)
@@ -565,8 +565,12 @@ class Trace:
             if self.start_time:
                 print('%.2f' % (_time() - self.start_time), end=' ')
             bname = os.path.basename(filename)
-            print("%s(%d): %s" % (bname, lineno,
-                                  linecache.getline(filename, lineno)), end='')
+            line = linecache.getline(filename, lineno)
+            print("%s(%d)" % (bname, lineno), end='')
+            if line:
+                print(": ", line, end='')
+            else:
+                print()
         return self.localtrace
 
     def localtrace_trace(self, frame, why, arg):
@@ -578,8 +582,12 @@ class Trace:
             if self.start_time:
                 print('%.2f' % (_time() - self.start_time), end=' ')
             bname = os.path.basename(filename)
-            print("%s(%d): %s" % (bname, lineno,
-                                  linecache.getline(filename, lineno)), end='')
+            line = linecache.getline(filename, lineno)
+            print("%s(%d)" % (bname, lineno), end='')
+            if line:
+                print(": ", line, end='')
+            else:
+                print()
         return self.localtrace
 
     def localtrace_count(self, frame, why, arg):
diff --git a/Misc/NEWS.d/next/Library/2023-04-28-09-54-15.gh-issue-103956.EyLDPS.rst b/Misc/NEWS.d/next/Library/2023-04-28-09-54-15.gh-issue-103956.EyLDPS.rst
new file mode 100644 (file)
index 0000000..4ce1491
--- /dev/null
@@ -0,0 +1 @@
+Fix lack of newline characters in :mod:`trace` module output when line tracing is enabled but source code line for current frame is not available.