staticshock / colored-traceback.py

Automatically color Python's uncaught exception tracebacks
ISC License
58 stars 11 forks source link

Use the py3tb traceback lexer on Python 3 #10

Closed mjpieters closed 4 months ago

mjpieters commented 5 years ago

In Python 3, tracebacks can contain additional, chained exceptions:

>>> try:
...     raise ValueError
... except ValueError:
...     raise TypeError
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
TypeError

and

>>> try:
...     raise ValueError
... except ValueError as e:
...     raise TypeError from e
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
TypeError

The standard Python traceback lexer doesn't handle the additional text very well:

>>> from pygments import highlight
>>> from pygments.lexers import get_lexer_by_name
>>> from pygments.formatters import RawTokenFormatter
>>> tbtext = """\
... Traceback (most recent call last):
...   File "<stdin>", line 2, in <module>
... ValueError
...
... During handling of the above exception, another exception occurred:
...
... Traceback (most recent call last):
...   File "<stdin>", line 4, in <module>
... TypeError
... """
>>> print(highlight(tbtext, get_lexer_by_name("pytb"), RawTokenFormatter()).decode())
Token.Generic.Traceback 'Traceback (most recent call last):\n'
Token.Text      '  File '
Token.Name.Builtin      '"<stdin>"'
Token.Text      ', line '
Token.Literal.Number    '2'
Token.Text      ', in '
Token.Name      '<module>'
Token.Text      '\n'
Token.Generic.Error     'ValueError'
Token.Text      '\n'
Token.Other     '\n'
Token.Other     'During handling of the above exception, another exception occurred:\n'
Token.Other     '\n'
Token.Generic.Traceback 'Traceback (most recent call last):\n'
Token.Text      '  File '
Token.Name.Builtin      '"<stdin>"'
Token.Text      ', line '
Token.Literal.Number    '4'
Token.Text      ', in '
Token.Name      '<module>'
Token.Text      '\n'
Token.Generic.Error     'TypeError'
Token.Text      '\n'

Note the Token.Other lines.

However, Pygments has a dedicated Python 3 traceback lexer, py3tb, which marks those lines as Token.Generic.Traceback:

>>> print(highlight(tbtext, get_lexer_by_name("py3tb"), RawTokenFormatter()).decode())
Token.Generic.Traceback 'Traceback (most recent call last):\n'
Token.Text      '  File '
Token.Name.Builtin      '"<stdin>"'
Token.Text      ', line '
Token.Literal.Number    '2'
Token.Text      ', in '
Token.Name      '<module>'
Token.Text      '\n'
Token.Generic.Error     'ValueError'
Token.Text      '\n'
Token.Text      '\n'
Token.Generic.Traceback 'During handling of the above exception, another exception occurred:\n\n'
Token.Generic.Traceback 'Traceback (most recent call last):\n'
Token.Text      '  File '
Token.Name.Builtin      '"<stdin>"'
Token.Text      ', line '
Token.Literal.Number    '4'
Token.Text      ', in '
Token.Name      '<module>'
Token.Text      '\n'
Token.Generic.Error     'TypeError'
Token.Text      '\n'

Please use this lexer instead of the standard lexer when running on Python 3.

staticshock commented 4 months ago

Thanks! Sorry I'm late, covid ate my homework.