Adds variables to python traceback with simple, lightweight, controllable debugging capabilities.
High-level printing functions and context managers for displaying enhanced tracebacks to various output destinations including files, loggers, and standard streams. Provides convenient interfaces for exception handling with automatic variable display.
Print exception tracebacks with variable contexts to files or file-like objects.
def print_exc(
e: Optional[Exception] = None,
num_skipped_frames: int = 0,
fmt: Optional[Format] = None,
file_: Union[TextIO, LoggerAsFile] = sys.stderr,
) -> None:
"""
Print exception traceback with variable contexts.
Parameters:
- e: Exception to print (uses current exception if None)
- num_skipped_frames: Number of frames to skip from the top
- fmt: Format configuration (uses default_format if None)
- file_: Output destination (file object or LoggerAsFile)
"""Print the current call stack with variable contexts.
def print_cur_tb(
num_skipped_frames: int = 0,
fmt: Optional[Format] = None,
file_: Union[TextIO, LoggerAsFile] = sys.stderr,
) -> None:
"""
Print current traceback with variable contexts.
Parameters:
- num_skipped_frames: Number of frames to skip from the top
- fmt: Format configuration (uses default_format if None)
- file_: Output destination (file object or LoggerAsFile)
"""Context manager that automatically prints exceptions with variable contexts when they occur.
def printing_exc(
reraise: bool = True,
file_: Union[TextIO, LoggerAsFile] = sys.stderr,
skip_cur_frame: bool = False,
fmt: Optional[Format] = None,
):
"""
Context manager that prints exceptions with variable contexts.
Parameters:
- reraise: Whether to re-raise the exception after printing
- file_: Output destination (file object or LoggerAsFile)
- skip_cur_frame: Skip the current frame from traceback
- fmt: Format configuration (uses default_format if None)
Usage:
with printing_exc():
# Code that might raise exceptions
pass
"""Decorator that prints exceptions with variable contexts when functions raise them.
def prints_exc(
func__for_noncall_case_only: Optional[Callable] = None,
file_: Union[TextIO, LoggerAsFile] = sys.stderr,
fmt: Optional[Format] = None,
):
"""
Decorator that prints exceptions with variable contexts.
Parameters:
- func__for_noncall_case_only: Function to decorate (for @prints_exc syntax)
- file_: Output destination (file object or LoggerAsFile)
- fmt: Format configuration (uses default_format if None)
Usage:
@prints_exc
def my_function():
pass
# Or with parameters:
@prints_exc(file_=my_file, fmt=my_format)
def my_function():
pass
"""Adapter class that allows Python loggers to be used as file-like objects for traceback output.
class LoggerAsFile:
def __init__(self, logger: logging.Logger, separate_lines: bool = False):
"""
Create a file-like adapter for a Python logger.
Parameters:
- logger: Python logger instance to write to
- separate_lines: If True, log each line separately; if False, collect lines and log together
"""
def write(self, text: str) -> None:
"""
Write text to the logger.
Parameters:
- text: Text to write/log
"""
def flush(self) -> None:
"""Flush any buffered content to the logger."""from traceback_with_variables import print_exc
try:
x = 42
y = "hello"
result = x / 0
except Exception as e:
print_exc(e) # Print to stderr with variablesfrom traceback_with_variables import print_exc
import sys
try:
data = [1, 2, 3]
index = 5
value = data[index]
except Exception as e:
# Print to stdout instead of stderr
print_exc(e, file_=sys.stdout)
# Print to a file
with open('error.log', 'w') as f:
print_exc(e, file_=f)from traceback_with_variables import printing_exc
# Automatically print exceptions but don't reraise
with printing_exc(reraise=False):
x = 42
y = 0
result = x / y # Exception printed, execution continues
print("This line executes because reraise=False")
# Print exceptions and reraise (default behavior)
try:
with printing_exc():
items = [1, 2, 3]
value = items[10] # Exception printed and reraised
except IndexError:
print("Caught the reraised exception")from traceback_with_variables import prints_exc
# Simple decorator usage
@prints_exc
def risky_function():
x = 42
y = 0
return x / y
# Decorator with custom parameters
@prints_exc(file_=open('errors.log', 'a'))
def logged_function():
data = {"key": "value"}
return data["missing_key"]
# Call functions - exceptions will be printed automatically
try:
risky_function()
except ZeroDivisionError:
print("Function completed with exception handling")import logging
from traceback_with_variables import print_exc, LoggerAsFile
# Set up logger
logger = logging.getLogger('my_app')
logger.setLevel(logging.ERROR)
handler = logging.FileHandler('app_errors.log')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
# Create logger adapter
logger_file = LoggerAsFile(logger, separate_lines=False)
try:
config = {"database": {"host": "localhost"}}
db_config = config["database"]["port"] # Missing key
except Exception as e:
# Print exception to logger instead of console
print_exc(e, file_=logger_file)from traceback_with_variables import printing_exc, Format, ColorSchemes
# Custom format for context manager
custom_fmt = Format(
max_value_str_len=200,
color_scheme=ColorSchemes.nice,
before=1,
after=1
)
# Use custom format with context manager
with printing_exc(fmt=custom_fmt, skip_cur_frame=True):
nested_data = {
"users": [
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
]
}
user_id = 3
user = next(u for u in nested_data["users"] if u["id"] == user_id)from traceback_with_variables import print_exc
import sys
try:
items = list(range(10))
calculation = items[5] / items[0] # This will work
problem = items[15] # This will fail
except Exception as e:
# Print to multiple destinations
print("ERROR OCCURRED:", file=sys.stderr)
print_exc(e, file_=sys.stderr)
# Also log to file
with open('detailed_errors.log', 'a') as log_file:
print_exc(e, file_=log_file)Install with Tessl CLI
npx tessl i tessl/pypi-traceback-with-variables