Adds variables to python traceback with simple, lightweight, controllable debugging capabilities.
ANSI color system with automatic terminal capability detection and pre-defined color schemes for different environments and preferences. Provides comprehensive color support across platforms including Windows, macOS, and Linux terminals.
Automatically detect if a terminal or file supports ANSI color codes across different platforms.
def supports_ansi(file_: TextIO) -> bool:
"""
Detect if a file or terminal supports ANSI color codes.
Checks multiple conditions across platforms:
- Terminal TTY capability
- Windows Terminal support (VirtualTerminalLevel, Windows Terminal, VS Code, ANSICON)
- Platform-specific color support detection
Parameters:
- file_: File-like object to test (typically sys.stdout or sys.stderr)
Returns:
True if ANSI colors are supported, False otherwise
"""Define and configure ANSI color schemes for different traceback elements.
class ColorScheme:
def __init__(
self,
common: str, # General text color
file_: str, # File path color
line_num: str, # Line number color
func_name: str, # Function name color
func_snippet: str, # Source code color
name: str, # Variable name color
value: str, # Variable value color
exc_class: str, # Exception class color
exc_text: str, # Exception message color
end: str, # Reset/end color
):
"""
Create a color scheme with ANSI color codes for traceback elements.
Each parameter accepts ANSI color code strings (e.g., '31' for red,
'32;1' for bright green). Empty strings disable coloring for that element.
The class automatically creates convenient attributes:
- c, f, ln, fn, fs, n, v, ec, et, e: Direct color codes
- c_, f_, ln_, fn_, fs_, n_, v_, ec_, et_: Color codes with reset prefixes
"""Collection of ready-to-use color schemes for different environments and preferences.
class ColorSchemes:
auto: None
"""Auto-detect appropriate color scheme based on terminal capabilities."""
none: ColorScheme
"""No colors - plain text output suitable for files and non-color terminals."""
common: ColorScheme
"""Standard color scheme with good compatibility across terminals."""
synthwave: ColorScheme
"""Retro synthwave color scheme with bright neon colors."""
nice: ColorScheme
"""Subtle, pleasant color scheme with muted tones."""from traceback_with_variables import Format, ColorSchemes, print_exc
import sys
# Auto-detect color support
if supports_ansi(sys.stderr):
fmt = Format(color_scheme=ColorSchemes.common)
print("Colors enabled!")
else:
fmt = Format(color_scheme=ColorSchemes.none)
print("No color support detected")
try:
data = {"numbers": [1, 2, 3]}
result = data["missing"]
except Exception as e:
print_exc(e, fmt=fmt)from traceback_with_variables import Format, ColorSchemes, print_exc
# Test different color schemes
schemes = {
"No Colors": ColorSchemes.none,
"Common": ColorSchemes.common,
"Synthwave": ColorSchemes.synthwave,
"Nice": ColorSchemes.nice
}
def test_exception():
user_data = {"id": 123, "name": "Alice", "preferences": {"theme": "dark"}}
missing_value = user_data["settings"]["notification"]
for scheme_name, scheme in schemes.items():
print(f"\n=== {scheme_name} Color Scheme ===")
fmt = Format(color_scheme=scheme)
try:
test_exception()
except Exception as e:
print_exc(e, fmt=fmt)from traceback_with_variables import ColorScheme, Format, print_exc
# Create custom color scheme
custom_scheme = ColorScheme(
common='0', # Normal text
file_='94', # Bright blue for files
line_num='93', # Bright yellow for line numbers
func_name='95', # Bright magenta for functions
func_snippet='37', # White for source code
name='96', # Bright cyan for variable names
value='92', # Bright green for values
exc_class='91', # Bright red for exception class
exc_text='31', # Red for exception message
end='0' # Reset
)
# Use custom scheme
custom_fmt = Format(color_scheme=custom_scheme)
try:
config = {"database": {"host": "localhost", "port": 5432}}
connection_string = config["database"]["password"]
except Exception as e:
print_exc(e, fmt=custom_fmt)from traceback_with_variables import Format, ColorSchemes, supports_ansi
import sys
import os
def get_appropriate_color_scheme():
"""Select color scheme based on environment."""
# Check if we're in a specific environment
if os.getenv('TERM_PROGRAM') == 'vscode':
return ColorSchemes.nice # VS Code integrated terminal
elif os.getenv('JUPYTER_SERVER_ROOT'):
return ColorSchemes.common # Jupyter environment
elif 'WT_SESSION' in os.environ:
return ColorSchemes.synthwave # Windows Terminal
elif supports_ansi(sys.stderr):
return ColorSchemes.common # Generic color terminal
else:
return ColorSchemes.none # No color support
# Apply environment-appropriate colors
env_fmt = Format(color_scheme=get_appropriate_color_scheme())
try:
project_config = {
"version": "1.0.0",
"dependencies": ["requests", "numpy"],
"dev_dependencies": ["pytest", "black"]
}
missing_config = project_config["build"]["target"]
except Exception as e:
print_exc(e, fmt=env_fmt)from traceback_with_variables import Format, ColorSchemes, supports_ansi, print_exc
import sys
def create_format_for_output(output_file):
"""Create appropriate format based on output destination."""
if supports_ansi(output_file):
return Format(color_scheme=ColorSchemes.common)
else:
return Format(color_scheme=ColorSchemes.none)
# Different outputs get appropriate formatting
try:
api_data = {"users": [{"id": 1, "name": "Alice"}], "total": 1}
user = api_data["users"][5] # Index error
except Exception as e:
# Terminal output with colors
terminal_fmt = create_format_for_output(sys.stderr)
print("=== Terminal Output (with colors if supported) ===")
print_exc(e, fmt=terminal_fmt)
# File output without colors
with open('/tmp/error.log', 'w') as log_file:
file_fmt = create_format_for_output(log_file)
print("\n=== File Output (no colors) ===")
print_exc(e, fmt=file_fmt, file_=log_file)from traceback_with_variables import ColorScheme, Format, print_exc
def test_color_scheme(scheme: ColorScheme, name: str):
"""Test a color scheme with sample traceback."""
print(f"\n{'='*50}")
print(f"Testing {name} Color Scheme")
print('='*50)
fmt = Format(color_scheme=scheme, before=1, after=1)
def sample_function():
sample_dict = {"key1": "value1", "key2": [1, 2, 3]}
sample_list = ["item1", "item2", "item3"]
sample_number = 42
sample_string = "Hello, World!"
# Trigger error to show all variables
return sample_dict["nonexistent_key"]
try:
sample_function()
except Exception as e:
print_exc(e, fmt=fmt)
# Test all built-in schemes
from traceback_with_variables import ColorSchemes
test_color_scheme(ColorSchemes.none, "None (No Colors)")
test_color_scheme(ColorSchemes.common, "Common")
test_color_scheme(ColorSchemes.synthwave, "Synthwave")
test_color_scheme(ColorSchemes.nice, "Nice")from traceback_with_variables.color import to_ansi
# Create ANSI color codes manually
def create_gradient_scheme():
"""Create a color scheme with gradient-like colors."""
return ColorScheme(
common=to_ansi('38;2;200;200;200'), # Light gray
file_=to_ansi('38;2;100;150;255'), # Light blue
line_num=to_ansi('38;2;255;200;100'), # Light orange
func_name=to_ansi('38;2;255;100;150'), # Pink
func_snippet=to_ansi('38;2;150;255;150'), # Light green
name=to_ansi('38;2;200;100;255'), # Purple
value=to_ansi('38;2;100;255;200'), # Cyan
exc_class=to_ansi('38;2;255;100;100'), # Light red
exc_text=to_ansi('38;2;255;150;150'), # Lighter red
end=to_ansi('0') # Reset
)
# Use custom gradient scheme
gradient_fmt = Format(color_scheme=create_gradient_scheme())
try:
rgb_data = {"colors": {"red": 255, "green": 128, "blue": 64}}
alpha_value = rgb_data["colors"]["alpha"]
except Exception as e:
print_exc(e, fmt=gradient_fmt)import sys
import os
from traceback_with_variables import Format, ColorSchemes
def get_platform_optimized_format():
"""Get color format optimized for current platform."""
if sys.platform == 'win32':
# Windows-specific optimizations
if 'WT_SESSION' in os.environ:
# Windows Terminal supports full colors
return Format(color_scheme=ColorSchemes.synthwave)
elif os.environ.get('TERM_PROGRAM') == 'vscode':
# VS Code on Windows
return Format(color_scheme=ColorSchemes.nice)
else:
# Legacy Windows console
return Format(color_scheme=ColorSchemes.common)
elif sys.platform == 'darwin':
# macOS optimizations
if os.environ.get('TERM_PROGRAM') == 'Apple_Terminal':
return Format(color_scheme=ColorSchemes.nice)
elif os.environ.get('TERM_PROGRAM') == 'iTerm.app':
return Format(color_scheme=ColorSchemes.synthwave)
else:
return Format(color_scheme=ColorSchemes.common)
else:
# Linux and other Unix-like systems
term = os.environ.get('TERM', '')
if 'xterm-256color' in term or 'screen-256color' in term:
return Format(color_scheme=ColorSchemes.synthwave)
else:
return Format(color_scheme=ColorSchemes.common)
# Use platform-optimized formatting
platform_fmt = get_platform_optimized_format()
try:
system_info = {
"platform": sys.platform,
"terminal": os.environ.get('TERM', 'unknown')
}
feature = system_info["graphics"]["acceleration"]
except Exception as e:
print_exc(e, fmt=platform_fmt)Install with Tessl CLI
npx tessl i tessl/pypi-traceback-with-variables