Skip to content

Commit 634f3be

Browse files
committed
add show_lines
1 parent 2dbada1 commit 634f3be

File tree

1 file changed

+84
-45
lines changed

1 file changed

+84
-45
lines changed

Lib/traceback.py

Lines changed: 84 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,18 @@
2626
#
2727

2828

29-
def print_list(extracted_list, file=None):
29+
def print_list(extracted_list, file=None, *, show_lines=True):
3030
"""Print the list of tuples as returned by extract_tb() or
31-
extract_stack() as a formatted stack trace to the given file."""
31+
extract_stack() as a formatted stack trace to the given file.
32+
33+
If show_lines is False, source code lines are not included in the output.
34+
"""
3235
if file is None:
3336
file = sys.stderr
34-
for item in StackSummary.from_list(extracted_list).format():
37+
for item in StackSummary.from_list(extracted_list).format(show_lines=show_lines):
3538
print(item, file=file, end="")
3639

37-
def format_list(extracted_list):
40+
def format_list(extracted_list, *, show_lines=True):
3841
"""Format a list of tuples or FrameSummary objects for printing.
3942
4043
Given a list of tuples or FrameSummary objects as returned by
@@ -45,26 +48,33 @@ def format_list(extracted_list):
4548
same index in the argument list. Each string ends in a newline;
4649
the strings may contain internal newlines as well, for those items
4750
whose source text line is not None.
51+
52+
If show_lines is False, source code lines are not included in the output.
4853
"""
49-
return StackSummary.from_list(extracted_list).format()
54+
return StackSummary.from_list(extracted_list).format(show_lines=show_lines)
5055

5156
#
5257
# Printing and Extracting Tracebacks.
5358
#
5459

55-
def print_tb(tb, limit=None, file=None):
60+
def print_tb(tb, limit=None, file=None, *, show_lines=True):
5661
"""Print up to 'limit' stack trace entries from the traceback 'tb'.
5762
5863
If 'limit' is omitted or None, all entries are printed. If 'file'
5964
is omitted or None, the output goes to sys.stderr; otherwise
6065
'file' should be an open file or file-like object with a write()
6166
method.
67+
68+
If show_lines is False, source code lines are not included in the output.
6269
"""
63-
print_list(extract_tb(tb, limit=limit), file=file)
70+
print_list(extract_tb(tb, limit=limit), file=file, show_lines=show_lines)
71+
72+
def format_tb(tb, limit=None, *, show_lines=True):
73+
"""A shorthand for 'format_list(extract_tb(tb, limit))'.
6474
65-
def format_tb(tb, limit=None):
66-
"""A shorthand for 'format_list(extract_tb(tb, limit))'."""
67-
return extract_tb(tb, limit=limit).format()
75+
If show_lines is False, source code lines are not included in the output.
76+
"""
77+
return extract_tb(tb, limit=limit).format(show_lines=show_lines)
6878

6979
def extract_tb(tb, limit=None):
7080
"""
@@ -80,7 +90,7 @@ def extract_tb(tb, limit=None):
8090
whitespace stripped; if the source is not available it is None.
8191
"""
8292
return StackSummary._extract_from_extended_frame_gen(
83-
_walk_tb_with_full_positions(tb), limit=limit)
93+
_walk_tb_with_full_positions(tb), limit=limit, lookup_lines=False)
8494

8595
#
8696
# Exception formatting and output.
@@ -117,7 +127,7 @@ def _parse_value_tb(exc, value, tb):
117127

118128

119129
def print_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \
120-
file=None, chain=True, **kwargs):
130+
file=None, chain=True, show_lines=True, **kwargs):
121131
"""Print exception up to 'limit' stack trace entries from 'tb' to 'file'.
122132
123133
This differs from print_tb() in the following ways: (1) if
@@ -127,11 +137,14 @@ def print_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \
127137
appropriate format, it prints the line where the syntax error
128138
occurred with a caret on the next line indicating the approximate
129139
position of the error.
140+
141+
If show_lines is False, source code lines are not included in the output.
130142
"""
131143
colorize = kwargs.get("colorize", False)
132144
value, tb = _parse_value_tb(exc, value, tb)
133-
te = TracebackException(type(value), value, tb, limit=limit, compact=True)
134-
te.print(file=file, chain=chain, colorize=colorize)
145+
te = TracebackException(type(value), value, tb, limit=limit, compact=True,
146+
lookup_lines=show_lines)
147+
te.print(file=file, chain=chain, colorize=colorize, show_lines=show_lines)
135148

136149

137150
BUILTIN_EXCEPTION_LIMIT = object()
@@ -144,19 +157,22 @@ def _print_exception_bltin(exc, /):
144157

145158

146159
def format_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \
147-
chain=True, **kwargs):
160+
chain=True, show_lines=True, **kwargs):
148161
"""Format a stack trace and the exception information.
149162
150163
The arguments have the same meaning as the corresponding arguments
151164
to print_exception(). The return value is a list of strings, each
152165
ending in a newline and some containing internal newlines. When
153166
these lines are concatenated and printed, exactly the same text is
154167
printed as does print_exception().
168+
169+
If show_lines is False, source code lines are not included in the output.
155170
"""
156171
colorize = kwargs.get("colorize", False)
157172
value, tb = _parse_value_tb(exc, value, tb)
158-
te = TracebackException(type(value), value, tb, limit=limit, compact=True)
159-
return list(te.format(chain=chain, colorize=colorize))
173+
te = TracebackException(type(value), value, tb, limit=limit, compact=True,
174+
lookup_lines=show_lines)
175+
return list(te.format(chain=chain, colorize=colorize, show_lines=show_lines))
160176

161177

162178
def format_exception_only(exc, /, value=_sentinel, *, show_group=False, **kwargs):
@@ -205,47 +221,61 @@ def _safe_string(value, what, func=str):
205221

206222
# --
207223

208-
def print_exc(limit=None, file=None, chain=True):
209-
"""Shorthand for 'print_exception(sys.exception(), limit=limit, file=file, chain=chain)'."""
210-
print_exception(sys.exception(), limit=limit, file=file, chain=chain)
224+
def print_exc(limit=None, file=None, chain=True, *, show_lines=True):
225+
"""Shorthand for 'print_exception(sys.exception(), limit=limit, file=file, chain=chain)'.
226+
227+
If show_lines is False, source code lines are not included in the output.
228+
"""
229+
print_exception(sys.exception(), limit=limit, file=file, chain=chain, show_lines=show_lines)
230+
231+
def format_exc(limit=None, chain=True, *, show_lines=True):
232+
"""Like print_exc() but return a string.
211233
212-
def format_exc(limit=None, chain=True):
213-
"""Like print_exc() but return a string."""
214-
return "".join(format_exception(sys.exception(), limit=limit, chain=chain))
234+
If show_lines is False, source code lines are not included in the output.
235+
"""
236+
return "".join(format_exception(sys.exception(), limit=limit, chain=chain, show_lines=show_lines))
237+
238+
def print_last(limit=None, file=None, chain=True, *, show_lines=True):
239+
"""This is a shorthand for 'print_exception(sys.last_exc, limit=limit, file=file, chain=chain)'.
215240
216-
def print_last(limit=None, file=None, chain=True):
217-
"""This is a shorthand for 'print_exception(sys.last_exc, limit=limit, file=file, chain=chain)'."""
241+
If show_lines is False, source code lines are not included in the output.
242+
"""
218243
if not hasattr(sys, "last_exc") and not hasattr(sys, "last_type"):
219244
raise ValueError("no last exception")
220245

221246
if hasattr(sys, "last_exc"):
222-
print_exception(sys.last_exc, limit=limit, file=file, chain=chain)
247+
print_exception(sys.last_exc, limit=limit, file=file, chain=chain, show_lines=show_lines)
223248
else:
224249
print_exception(sys.last_type, sys.last_value, sys.last_traceback,
225-
limit=limit, file=file, chain=chain)
250+
limit=limit, file=file, chain=chain, show_lines=show_lines)
226251

227252

228253
#
229254
# Printing and Extracting Stacks.
230255
#
231256

232-
def print_stack(f=None, limit=None, file=None):
257+
def print_stack(f=None, limit=None, file=None, *, show_lines=True):
233258
"""Print a stack trace from its invocation point.
234259
235260
The optional 'f' argument can be used to specify an alternate
236261
stack frame at which to start. The optional 'limit' and 'file'
237262
arguments have the same meaning as for print_exception().
263+
264+
If show_lines is False, source code lines are not included in the output.
238265
"""
239266
if f is None:
240267
f = sys._getframe().f_back
241-
print_list(extract_stack(f, limit=limit), file=file)
268+
print_list(extract_stack(f, limit=limit), file=file, show_lines=show_lines)
269+
242270

271+
def format_stack(f=None, limit=None, *, show_lines=True):
272+
"""Shorthand for 'format_list(extract_stack(f, limit))'.
243273
244-
def format_stack(f=None, limit=None):
245-
"""Shorthand for 'format_list(extract_stack(f, limit))'."""
274+
If show_lines is False, source code lines are not included in the output.
275+
"""
246276
if f is None:
247277
f = sys._getframe().f_back
248-
return format_list(extract_stack(f, limit=limit))
278+
return format_list(extract_stack(f, limit=limit), show_lines=show_lines)
249279

250280

251281
def extract_stack(f=None, limit=None):
@@ -259,7 +289,7 @@ def extract_stack(f=None, limit=None):
259289
"""
260290
if f is None:
261291
f = sys._getframe().f_back
262-
stack = StackSummary.extract(walk_stack(f), limit=limit)
292+
stack = StackSummary.extract(walk_stack(f), limit=limit, lookup_lines=False)
263293
stack.reverse()
264294
return stack
265295

@@ -436,7 +466,7 @@ class StackSummary(list):
436466

437467
@classmethod
438468
def extract(klass, frame_gen, *, limit=None, lookup_lines=True,
439-
capture_locals=False):
469+
capture_locals=False):
440470
"""Create a StackSummary from a traceback or stack object.
441471
442472
:param frame_gen: A generator that yields (frame, lineno) tuples
@@ -525,11 +555,13 @@ def from_list(klass, a_list):
525555
result.append(FrameSummary(filename, lineno, name, line=line))
526556
return result
527557

528-
def format_frame_summary(self, frame_summary, **kwargs):
558+
def format_frame_summary(self, frame_summary, *, show_lines=True, **kwargs):
529559
"""Format the lines for a single FrameSummary.
530560
531561
Returns a string representing one frame involved in the stack. This
532562
gets called for every frame to be printed in the stack summary.
563+
564+
If show_lines is False, source code lines are not included in the output.
533565
"""
534566
colorize = kwargs.get("colorize", False)
535567
row = []
@@ -553,7 +585,7 @@ def format_frame_summary(self, frame_summary, **kwargs):
553585
theme.reset,
554586
)
555587
)
556-
if frame_summary._dedented_lines and frame_summary._dedented_lines.strip():
588+
if show_lines and frame_summary._dedented_lines and frame_summary._dedented_lines.strip():
557589
if (
558590
frame_summary.colno is None or
559591
frame_summary.end_colno is None
@@ -742,7 +774,7 @@ def _spawns_full_line(value):
742774
return True
743775
return False
744776

745-
def format(self, **kwargs):
777+
def format(self, *, show_lines=True, **kwargs):
746778
"""Format the stack ready for printing.
747779
748780
Returns a list of strings ready for printing. Each string in the
@@ -753,6 +785,8 @@ def format(self, **kwargs):
753785
For long sequences of the same frame and line, the first few
754786
repetitions are shown, followed by a summary line stating the exact
755787
number of further repetitions.
788+
789+
If show_lines is False, source code lines are not included in the output.
756790
"""
757791
colorize = kwargs.get("colorize", False)
758792
result = []
@@ -761,7 +795,7 @@ def format(self, **kwargs):
761795
last_name = None
762796
count = 0
763797
for frame_summary in self:
764-
formatted_frame = self.format_frame_summary(frame_summary, colorize=colorize)
798+
formatted_frame = self.format_frame_summary(frame_summary, show_lines=show_lines, colorize=colorize)
765799
if formatted_frame is None:
766800
continue
767801
if (last_file is None or last_file != frame_summary.filename or
@@ -1465,7 +1499,7 @@ def _format_syntax_error(self, stype, **kwargs):
14651499
filename_suffix,
14661500
)
14671501

1468-
def format(self, *, chain=True, _ctx=None, **kwargs):
1502+
def format(self, *, chain=True, show_lines=True, _ctx=None, **kwargs):
14691503
"""Format the exception.
14701504
14711505
If chain is not *True*, *__cause__* and *__context__* will not be formatted.
@@ -1476,6 +1510,8 @@ def format(self, *, chain=True, _ctx=None, **kwargs):
14761510
14771511
The message indicating which exception occurred is always the last
14781512
string in the output.
1513+
1514+
If show_lines is False, source code lines are not included in the output.
14791515
"""
14801516
colorize = kwargs.get("colorize", False)
14811517
if _ctx is None:
@@ -1507,7 +1543,7 @@ def format(self, *, chain=True, _ctx=None, **kwargs):
15071543
if exc.exceptions is None:
15081544
if exc.stack:
15091545
yield from _ctx.emit('Traceback (most recent call last):\n')
1510-
yield from _ctx.emit(exc.stack.format(colorize=colorize))
1546+
yield from _ctx.emit(exc.stack.format(show_lines=show_lines, colorize=colorize))
15111547
yield from _ctx.emit(exc.format_exception_only(colorize=colorize))
15121548
elif _ctx.exception_group_depth > self.max_group_depth:
15131549
# exception group, but depth exceeds limit
@@ -1523,7 +1559,7 @@ def format(self, *, chain=True, _ctx=None, **kwargs):
15231559
yield from _ctx.emit(
15241560
'Exception Group Traceback (most recent call last):\n',
15251561
margin_char = '+' if is_toplevel else None)
1526-
yield from _ctx.emit(exc.stack.format(colorize=colorize))
1562+
yield from _ctx.emit(exc.stack.format(show_lines=show_lines, colorize=colorize))
15271563

15281564
yield from _ctx.emit(exc.format_exception_only(colorize=colorize))
15291565
num_excs = len(exc.exceptions)
@@ -1548,7 +1584,7 @@ def format(self, *, chain=True, _ctx=None, **kwargs):
15481584
f'+---------------- {title} ----------------\n')
15491585
_ctx.exception_group_depth += 1
15501586
if not truncated:
1551-
yield from exc.exceptions[i].format(chain=chain, _ctx=_ctx, colorize=colorize)
1587+
yield from exc.exceptions[i].format(chain=chain, show_lines=show_lines, _ctx=_ctx, colorize=colorize)
15521588
else:
15531589
remaining = num_excs - self.max_group_width
15541590
plural = 's' if remaining > 1 else ''
@@ -1566,12 +1602,15 @@ def format(self, *, chain=True, _ctx=None, **kwargs):
15661602
_ctx.exception_group_depth = 0
15671603

15681604

1569-
def print(self, *, file=None, chain=True, **kwargs):
1570-
"""Print the result of self.format(chain=chain) to 'file'."""
1605+
def print(self, *, file=None, chain=True, show_lines=True, **kwargs):
1606+
"""Print the result of self.format(chain=chain) to 'file'.
1607+
1608+
If show_lines is False, source code lines are not included in the output.
1609+
"""
15711610
colorize = kwargs.get("colorize", False)
15721611
if file is None:
15731612
file = sys.stderr
1574-
for line in self.format(chain=chain, colorize=colorize):
1613+
for line in self.format(chain=chain, show_lines=show_lines, colorize=colorize):
15751614
print(line, file=file, end="")
15761615

15771616

0 commit comments

Comments
 (0)