Search code examples
pythonpretty-printtraceback

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)

Solution

  • 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()))