Skip to content

Commit 0d62676

Browse files
[3.12] gh-103956: Fix trace output in case of missing source line (GH-103958) (GH-118832)
Print only filename with lineno if linecache.getline() returns an empty string. (cherry picked from commit 7c87ce7) Co-authored-by: Radislav Chugunov <[email protected]>
1 parent e953956 commit 0d62676

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

Lib/test/test_trace.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from test.support.script_helper import assert_python_ok, assert_python_failure
77
import textwrap
88
import unittest
9+
from types import FunctionType
910

1011
import trace
1112
from trace import Trace
@@ -559,5 +560,29 @@ def test_run_as_module(self):
559560
assert_python_failure('-m', 'trace', '-l', '--module', 'not_a_module_zzz')
560561

561562

563+
class TestTrace(unittest.TestCase):
564+
def setUp(self):
565+
self.addCleanup(sys.settrace, sys.gettrace())
566+
self.tracer = Trace(count=0, trace=1)
567+
self.filemod = my_file_and_modname()
568+
569+
def test_no_source_file(self):
570+
filename = "<unknown>"
571+
co = traced_func_linear.__code__
572+
co = co.replace(co_filename=filename)
573+
f = FunctionType(co, globals())
574+
575+
with captured_stdout() as out:
576+
self.tracer.runfunc(f, 2, 3)
577+
578+
out = out.getvalue().splitlines()
579+
firstlineno = get_firstlineno(f)
580+
self.assertIn(f" --- modulename: {self.filemod[1]}, funcname: {f.__code__.co_name}", out[0])
581+
self.assertIn(f"{filename}({firstlineno + 1})", out[1])
582+
self.assertIn(f"{filename}({firstlineno + 2})", out[2])
583+
self.assertIn(f"{filename}({firstlineno + 3})", out[3])
584+
self.assertIn(f"{filename}({firstlineno + 4})", out[4])
585+
586+
562587
if __name__ == '__main__':
563588
unittest.main()

Lib/trace.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -559,8 +559,12 @@ def localtrace_trace_and_count(self, frame, why, arg):
559559
if self.start_time:
560560
print('%.2f' % (_time() - self.start_time), end=' ')
561561
bname = os.path.basename(filename)
562-
print("%s(%d): %s" % (bname, lineno,
563-
linecache.getline(filename, lineno)), end='')
562+
line = linecache.getline(filename, lineno)
563+
print("%s(%d)" % (bname, lineno), end='')
564+
if line:
565+
print(": ", line, end='')
566+
else:
567+
print()
564568
return self.localtrace
565569

566570
def localtrace_trace(self, frame, why, arg):
@@ -572,8 +576,12 @@ def localtrace_trace(self, frame, why, arg):
572576
if self.start_time:
573577
print('%.2f' % (_time() - self.start_time), end=' ')
574578
bname = os.path.basename(filename)
575-
print("%s(%d): %s" % (bname, lineno,
576-
linecache.getline(filename, lineno)), end='')
579+
line = linecache.getline(filename, lineno)
580+
print("%s(%d)" % (bname, lineno), end='')
581+
if line:
582+
print(": ", line, end='')
583+
else:
584+
print()
577585
return self.localtrace
578586

579587
def localtrace_count(self, frame, why, arg):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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.

0 commit comments

Comments
 (0)