Santhosh
Santhosh

Reputation: 11834

python: traceback.print_stack(): How to colorize and reformat output

I want to see the full trace of the code till a particular point

so i do

...
import traceback
traceback.print_stack()
...

Then it will show

  File ".venv/lib/python3.7/site-packages/django/db/models/query.py", line 144, in __iter__
    return compiler.results_iter(tuple_expected=True, chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File ".venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1052, in results_iter
    results = self.execute_sql(MULTI, chunked_fetch=chunked_fetch, chunk_size=chunk_size)
  File ".venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1100, in execute_sql
    cursor.execute(sql, params)
  File ".venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 110, in execute
    extra={'duration': duration, 'sql': sql, 'params': params}
  File "/usr/lib64/python3.7/logging/__init__.py", line 1371, in debug
    self._log(DEBUG, msg, args, **kwargs)
  File "/usr/lib64/python3.7/logging/__init__.py", line 1519, in _log
    self.handle(record)
  File "/usr/lib64/python3.7/logging/__init__.py", line 1528, in handle
    if (not self.disabled) and self.filter(record):
  File "/usr/lib64/python3.7/logging/__init__.py", line 762, in filter
    result = f.filter(record)
  File "basic_django/settings.py", line 402, in filter
    traceback.print_stack()

How to make this output more colorful using pygments.

Generally to colorize a json string in python i do

from pygments import highlight
from pygments.lexers import JsonLexer
from pygments.formatters import TerminalTrueColorFormatter
json_str = '{ "name":"John" }'
print(highlight(json_str, JsonLexer(), TerminalTrueColorFormatter()))

Similarly how to do that with traceback.print_stack()

Answer I Used based on Alexander Huszagh

1) we have to use Python3TracebackLexer

2) we have to use traceback.format_stack() which gives a list and then concatenate them as a string using ''.join(traceback.format_stack()).

import traceback
import pygments
from pygments.lexers import Python3TracebackLexer
from pygments.formatters import TerminalTrueColorFormatter
traceback_color = pygments.highlight(''.join(traceback.format_stack()),Python3TracebackLexer(),TerminalTrueColorFormatter(style='trac')) # trac or rainbow_dash i prefer
print(traceback_color)

Upvotes: 4

Views: 3709

Answers (2)

pepoluan
pepoluan

Reputation: 6808

Alternatively, use the rich library.

With just two lines of code, it will prettify your tracebacks... and then some!

from rich.traceback import install
install()

How does it look afterwards? Take a gander:

Fabulous traceback output

And the beauty of it? It supports Pygment themes!

Upvotes: 7

Alex Huszagh
Alex Huszagh

Reputation: 14634

Pygments lists the available lexers. You can do this with Python3TracebackLexer.

from pygments import highlight
from pygments.lexers import Python3TracebackLexer
from pygments.formatters import TerminalTrueColorFormatter

err_str = '''
  File ".venv/lib/python3.7/site-packages/django/db/models/query.py", line 144, in __iter__
    return compiler.results_iter(tuple_expected=True, chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File ".venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1052, in results_iter
    results = self.execute_sql(MULTI, chunked_fetch=chunked_fetch, chunk_size=chunk_size)
  File ".venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1100, in execute_sql
    cursor.execute(sql, params)
  File ".venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 110, in execute
    extra={'duration': duration, 'sql': sql, 'params': params}
  File "/usr/lib64/python3.7/logging/__init__.py", line 1371, in debug
    self._log(DEBUG, msg, args, **kwargs)
  File "/usr/lib64/python3.7/logging/__init__.py", line 1519, in _log
    self.handle(record)
  File "/usr/lib64/python3.7/logging/__init__.py", line 1528, in handle
    if (not self.disabled) and self.filter(record):
  File "/usr/lib64/python3.7/logging/__init__.py", line 762, in filter
    result = f.filter(record)
  File "basic_django/settings.py", line 402, in filter
    traceback.print_stack()
'''

print(highlight(err_str, Python3TracebackLexer(), TerminalTrueColorFormatter()))

In order to get err_str, replace print_stack with format_stack as follows than do:

def colorize_traceback(err_str):
    return highlight(err_str, Python3TracebackLexer(), TerminalTrueColorFormatter())

try:
    ... # Some logic
except Exception:   # Or a more narrow exception
    # tb.print_stack()
    print(colorize_traceback(tb.format_stack()))

Upvotes: 2

Related Questions