Adds variables to python traceback with simple, lightweight, controllable debugging capabilities.
Comprehensive formatting configuration system with customizable output options, color schemes, variable filtering, and display preferences. The Format class provides fine-grained control over every aspect of traceback display and variable representation.
Main configuration class that controls all aspects of traceback formatting and variable display.
class Format:
def __init__(
self,
max_value_str_len: int = 1000,
ellipsis_rel_pos: float = 0.7,
max_exc_str_len: int = 10000,
objects_details: int = 1,
ellipsis_: str = '...',
before: int = 0,
after: int = 0,
color_scheme: Optional[ColorScheme] = None,
skip_files_except: Patterns = None,
brief_files_except: Patterns = None,
custom_var_printers: Optional[VarPrinters] = None,
):
"""
Configure traceback formatting and variable display options.
Parameters:
- max_value_str_len: Maximum length for variable value strings (default: 1000)
- ellipsis_rel_pos: Relative position for ellipsis placement (0.0-1.0, default: 0.7)
- max_exc_str_len: Maximum length for exception strings (default: 10000)
- objects_details: Depth level for object inspection (default: 1)
- ellipsis_: String to use for truncation (default: '...')
- before: Number of context lines before exception line (default: 0)
- after: Number of context lines after exception line (default: 0)
- color_scheme: ColorScheme instance for output styling (default: auto-detect)
- skip_files_except: File patterns to skip unless matching (default: None)
- brief_files_except: File patterns to show briefly unless matching (default: None)
- custom_var_printers: Custom variable printing functions (default: None)
"""Methods for manipulating and creating Format configurations.
def replace(self, **kwargs: Dict[str, Any]) -> 'Format':
"""
Create a new Format instance with specified attributes modified.
Parameters:
- **kwargs: Attribute names and values to override
Returns:
New Format instance with changes applied
"""
@classmethod
def add_arguments(cls, parser: argparse.ArgumentParser) -> None:
"""
Add Format configuration arguments to command-line parser.
Parameters:
- parser: ArgumentParser instance to add arguments to
"""
@classmethod
def parse(cls, ns: argparse.Namespace) -> 'Format':
"""
Create a Format instance from parsed command-line arguments.
Parameters:
- ns: Namespace object from ArgumentParser.parse_args()
Returns:
New Format instance configured from command-line arguments
"""
@classmethod
def add_arguments(cls, parser: argparse.ArgumentParser) -> None:
"""
Add Format configuration arguments to an ArgumentParser.
Parameters:
- parser: ArgumentParser instance to add arguments to
"""
@classmethod
def parse(cls, ns: argparse.Namespace) -> 'Format':
"""
Create Format instance from parsed command-line arguments.
Parameters:
- ns: Parsed arguments namespace
Returns:
Format instance configured from command-line arguments
"""Pre-configured Format instance with sensible defaults and security-focused variable hiding.
default_format: Format
"""
Default Format instance with built-in security features.
Automatically hides variables with sensitive names (password, secret, token,
key, api_key, credential, pwd) by replacing their values with '...hidden...'.
"""
# Short alias for interactive usage
fmt: Format # Alias for default_format# File filtering patterns
Patterns = Union[None, str, List[str]]
# Variable filtering and printing types
ShouldPrint = Callable[[str, Type, str, bool], bool] # (name, type, filename, is_global) -> bool
VarFilterItem = Union[str, Type, ShouldPrint] # String pattern, type class, or function
VarFilter = Union[VarFilterItem, List[VarFilterItem]] # Single filter or list of filters
Print = Callable[[Any], Optional[str]] # Custom printer function
VarPrinters = List[Tuple[ShouldPrint, Print]] # List of (filter, printer) pairsfrom traceback_with_variables import Format, ColorSchemes, print_exc
# Create custom format with specific settings
custom_format = Format(
max_value_str_len=500, # Shorter variable values
color_scheme=ColorSchemes.nice, # Use nice color scheme
before=2, # Show 2 lines before error
after=1, # Show 1 line after error
objects_details=2 # Deeper object inspection
)
try:
data = {"key": {"nested": {"value": 123}}}
result = data["missing"]
except Exception as e:
print_exc(e, fmt=custom_format)from traceback_with_variables import Format, hide, skip, print_exc
import re
# Create custom variable printers
def custom_printer(obj):
if isinstance(obj, dict) and len(obj) > 10:
return f"<large dict with {len(obj)} keys>"
return None # Use default printing
# Configure custom variable filtering
custom_format = Format(
custom_var_printers=[
# Hide variables matching sensitive patterns
(r'.*(?i:password|secret|token|key|credential).*', hide),
# Skip displaying large data structures
(lambda name, type_, filename, is_global: name.startswith('_temp'), skip),
# Custom printer for dictionaries
(dict, custom_printer),
# Skip global variables in specific files
(lambda name, type_, filename, is_global:
is_global and 'test_' in filename, skip),
]
)
try:
password = "secret123"
api_key = "abc123def456"
large_dict = {f"key_{i}": i for i in range(100)}
_temp_data = [1] * 1000
result = 1 / 0
except Exception as e:
print_exc(e, fmt=custom_format)from traceback_with_variables import Format, print_exc
# Configure file filtering
file_filtered_format = Format(
# Only show frames from specific files
skip_files_except=[r'.*myproject.*', r'.*main\.py'],
# Show brief output for these files unless they match above
brief_files_except=[r'.*third_party.*', r'.*/__pycache__/.*'],
max_value_str_len=200
)
try:
# Code that involves multiple files
import os
import json
data = json.loads('invalid json')
except Exception as e:
print_exc(e, fmt=file_filtered_format)from traceback_with_variables import default_format, ColorSchemes
# Create variations of the default format
verbose_format = default_format.replace(
before=3,
after=2,
objects_details=3,
max_value_str_len=2000
)
colorful_format = default_format.replace(
color_scheme=ColorSchemes.synthwave
)
compact_format = default_format.replace(
max_value_str_len=100,
objects_details=0,
ellipsis_='…'
)
# Use different formats for different scenarios
try:
debug_data = {"complex": {"nested": {"structure": [1, 2, 3]}}}
value = debug_data["missing"]["key"]
except Exception as e:
print("=== VERBOSE OUTPUT ===")
print_exc(e, fmt=verbose_format)
print("\n=== COMPACT OUTPUT ===")
print_exc(e, fmt=compact_format)from traceback_with_variables import Format, hide, skip
import logging
# Create security-focused format for production
production_format = Format(
# Hide all sensitive variables
custom_var_printers=[
# Comprehensive sensitive data patterns
(r'.*(?i:pass|pwd|password|secret|token|key|api|auth|credential|private).*', hide),
# Skip displaying environment variables
(lambda name, type_, filename, is_global:
name.startswith('ENV_') or name.startswith('os.environ'), skip),
# Hide large data structures in production
(lambda name, type_, filename, is_global:
isinstance(type_, (list, dict)) and name.startswith('cache'), hide),
],
# Shorter output for production logs
max_value_str_len=200,
max_exc_str_len=5000,
objects_details=1,
# No colors in production logs
color_scheme=None
)
# Example usage in production error handler
def handle_error(e: Exception):
logger = logging.getLogger('production')
from traceback_with_variables import LoggerAsFile, print_exc
logger_file = LoggerAsFile(logger)
print_exc(e, fmt=production_format, file_=logger_file)import argparse
from traceback_with_variables import Format
# Set up argument parser with Format options
parser = argparse.ArgumentParser()
Format.add_arguments(parser)
# Parse arguments and create format
args = parser.parse_args()
fmt = Format.parse(args)
# Use the configured format
try:
# Your application code here
pass
except Exception as e:
print_exc(e, fmt=fmt)from traceback_with_variables import default_format as fmt, ColorSchemes
# Modify the global default format for interactive use
fmt.color_scheme = ColorSchemes.synthwave
fmt.before = 1
fmt.after = 1
fmt.max_value_str_len = 300
# Now all traceback calls will use these settings
try:
interactive_data = {"session": "active", "user_id": 12345}
result = interactive_data["nonexistent"]
except Exception as e:
print_exc(e) # Uses modified global formatInstall with Tessl CLI
npx tessl i tessl/pypi-traceback-with-variables