|
3 | 3 | import collections.abc |
4 | 4 | import itertools |
5 | 5 | import linecache |
| 6 | +import os |
6 | 7 | import sys |
7 | 8 | import textwrap |
8 | 9 | import warnings |
|
17 | 18 | 'FrameSummary', 'StackSummary', 'TracebackException', |
18 | 19 | 'walk_stack', 'walk_tb', 'print_list'] |
19 | 20 |
|
| 21 | + |
| 22 | +ENABLE_TRACEBACK_TIMESTAMPS = os.environb.get(b"PYTHON_TRACEBACK_TIMESTAMPS", b"") == b"1" |
| 23 | + |
| 24 | + |
20 | 25 | # |
21 | 26 | # Formatting and printing lists of traceback lines. |
22 | 27 | # |
@@ -182,7 +187,7 @@ def format_exception_only(exc, /, value=_sentinel, *, show_group=False, **kwargs |
182 | 187 | def _format_final_exc_line(etype, value, *, insert_final_newline=True, colorize=False, timestamp=0): |
183 | 188 | valuestr = _safe_string(value, 'exception') |
184 | 189 | end_char = "\n" if insert_final_newline else "" |
185 | | - ts = f" <@t={timestamp:.6f}>" if timestamp else "" |
| 190 | + ts = f" <@T={timestamp:.6f}>" if timestamp else "" |
186 | 191 | if colorize: |
187 | 192 | timestamp = f"{ANSIColors.GREY}{ts}{ANSIColors.RESET}" if timestamp else "" |
188 | 193 | if value is None or not valuestr: |
@@ -1007,7 +1012,7 @@ class TracebackException: |
1007 | 1012 | - :attr:`__cause__` A TracebackException of the original *__cause__*. |
1008 | 1013 | - :attr:`__context__` A TracebackException of the original *__context__*. |
1009 | 1014 | - :attr:`__notes__` A reference to the original *__notes__* list. |
1010 | | - - :attr:`timestamp` When the original exception was created (seconds). |
| 1015 | + - :attr:`_timestamp` When the exception was created (seconds), if enabled. |
1011 | 1016 | - :attr:`exceptions` For exception groups - a list of TracebackException |
1012 | 1017 | instances for the nested *exceptions*. ``None`` for other exceptions. |
1013 | 1018 | - :attr:`__suppress_context__` The *__suppress_context__* value from the |
@@ -1061,7 +1066,10 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, |
1061 | 1066 | self.__notes__ = [ |
1062 | 1067 | f'Ignored error getting __notes__: {_safe_string(e, '__notes__', repr)}'] |
1063 | 1068 |
|
1064 | | - self.timestamp = exc_value.__timestamp_ns__ / 1_000_000_000 |
| 1069 | + if ENABLE_TRACEBACK_TIMESTAMPS: |
| 1070 | + self._timestamp = exc_value.__timestamp_ns__ / 1_000_000_000 |
| 1071 | + else: |
| 1072 | + self._timestamp = 0 |
1065 | 1073 |
|
1066 | 1074 | self._is_syntax_error = False |
1067 | 1075 | self._have_exc_type = exc_type is not None |
@@ -1234,22 +1242,22 @@ def format_exception_only(self, *, show_group=False, _depth=0, **kwargs): |
1234 | 1242 |
|
1235 | 1243 | indent = 3 * _depth * ' ' |
1236 | 1244 | if not self._have_exc_type: |
1237 | | - yield indent + _format_final_exc_line(None, self._str, colorize=colorize, timestamp=self.timestamp) |
| 1245 | + yield indent + _format_final_exc_line(None, self._str, colorize=colorize, timestamp=self._timestamp) |
1238 | 1246 | return |
1239 | 1247 |
|
1240 | 1248 | stype = self.exc_type_str |
1241 | 1249 | if not self._is_syntax_error: |
1242 | 1250 | if _depth > 0: |
1243 | 1251 | # Nested exceptions needs correct handling of multiline messages. |
1244 | 1252 | formatted = _format_final_exc_line( |
1245 | | - stype, self._str, insert_final_newline=False, colorize=colorize, timestamp=self.timestamp |
| 1253 | + stype, self._str, insert_final_newline=False, colorize=colorize, timestamp=self._timestamp |
1246 | 1254 | ).split('\n') |
1247 | 1255 | yield from [ |
1248 | 1256 | indent + l + '\n' |
1249 | 1257 | for l in formatted |
1250 | 1258 | ] |
1251 | 1259 | else: |
1252 | | - yield _format_final_exc_line(stype, self._str, colorize=colorize, timestamp=self.timestamp) |
| 1260 | + yield _format_final_exc_line(stype, self._str, colorize=colorize, timestamp=self._timestamp) |
1253 | 1261 | else: |
1254 | 1262 | yield from [indent + l for l in self._format_syntax_error(stype, colorize=colorize)] |
1255 | 1263 |
|
|
0 commit comments