CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-devtools

Python's missing debug print command and development tools with enhanced debugging, pretty printing, timing, and ANSI styling capabilities.

Pending
Overview
Eval results
Files

debug.mddocs/

Debug System

Enhanced debug printing system that automatically extracts variable names, displays types and metadata, shows source location, and provides syntax highlighting with intelligent pretty formatting. The debug system uses the executing library to inspect the call stack and extract variable names from the source code.

Capabilities

Debug Function

The main debug function automatically extracts variable names from source code and displays them with their values, types, and additional metadata.

def debug(*args, file_=None, flush_=True, frame_depth_=2, **kwargs):
    """
    Debug print with automatic variable name extraction and context.
    
    Parameters:
    - *args: Variables to debug print
    - file_: Output file (default: stdout)
    - flush_: Flush output buffer (default: True)
    - frame_depth_: Stack frame depth for inspection (default: 2)
    - **kwargs: Named variables to debug print
    
    Returns:
    Single arg: returns the argument itself
    Multiple args: returns tuple of arguments
    With kwargs: returns (*args, kwargs)
    """

Usage examples:

from devtools import debug

# Basic variable debugging
name = "Alice"
age = 30
debug(name, age)
# Output: example.py:5 <module>:
#     name: 'Alice' (str) len=5
#     age: 30 (int)

# Debug complex data structures
data = {'users': [1, 2, 3], 'config': {'debug': True}}
debug(data)
# Output: example.py:9 <module>:
#     data: {
#         'users': [1, 2, 3],
#         'config': {'debug': True},
#     } (dict) len=2

# Debug with expressions
numbers = [1, 2, 3, 4, 5]
debug(len(numbers), sum(numbers))
# Output: example.py:13 <module>:
#     len(numbers): 5 (int)
#     sum(numbers): 15 (int)

# Named keyword arguments
debug(total=sum(numbers), average=sum(numbers)/len(numbers))
# Output: example.py:15 <module>:
#     total: 15 (int)
#     average: 3.0 (float)

Debug Class

Configurable debug class that allows customization of warning display and syntax highlighting behavior.

class Debug:
    """
    Configurable debug print class.
    """
    def __init__(self, warnings=None, highlight=None):
        """
        Initialize Debug instance.
        
        Parameters:
        - warnings: Show warnings (None uses PY_DEVTOOLS_WARNINGS env var, default True)
        - highlight: Enable syntax highlighting (None uses auto-detection)
        """
    
    def __call__(self, *args, file_=None, flush_=True, frame_depth_=2, **kwargs):
        """
        Debug print with automatic variable name extraction.
        
        Parameters:
        - *args: Variables to debug print
        - file_: Output file (default: stdout)
        - flush_: Flush output buffer (default: True)
        - frame_depth_: Stack frame depth for inspection (default: 2)
        - **kwargs: Named variables to debug print
        
        Returns:
        Single arg: the arg itself
        Multiple args: tuple of args
        With kwargs: (*args, kwargs)
        """
    
    def format(self, *args, frame_depth_=2, **kwargs) -> DebugOutput:
        """
        Format debug output without printing.
        
        Parameters:
        - *args: Variables to format
        - frame_depth_: Stack frame depth for inspection (default: 2)
        - **kwargs: Named variables to format
        
        Returns:
        DebugOutput object containing formatted debug information
        """
    
    def breakpoint(self) -> None:
        """
        Set a breakpoint using pdb, skipping devtools frames.
        """
    
    def timer(self, name=None, verbose=True, file=None, dp=3) -> Timer:
        """
        Create and return a Timer instance.
        
        Parameters:
        - name: Timer name (optional)
        - verbose: Print timing results (default: True)
        - file: Output file (default: stdout)
        - dp: Decimal places for timing display (default: 3)
        
        Returns:
        Timer instance configured with the specified parameters
        """

Usage examples:

from devtools import Debug

# Create custom debug instance without warnings
quiet_debug = Debug(warnings=False)
quiet_debug(some_variable)

# Create debug instance with forced highlighting
colored_debug = Debug(highlight=True)
colored_debug(data_structure)

# Format without printing
debug_output = debug.format(variable_name)
formatted_string = debug_output.str(highlight=True)
print(f"Custom prefix: {formatted_string}")

# Use integrated timer
with debug.timer('operation'):
    # Some code to time
    pass

Debug Output Classes

Classes representing formatted debug output and individual arguments.

class DebugOutput:
    """
    Represents formatted debug output containing file context and arguments.
    """
    def __init__(self, filename: str, lineno: int, frame: str, arguments: list[DebugArgument], warning: str | bool | None = None):
        """
        Initialize DebugOutput.
        
        Parameters:
        - filename: Source file path
        - lineno: Line number in source file
        - frame: Function/method name
        - arguments: List of DebugArgument instances
        - warning: Warning message or None
        """
    
    def str(self, highlight: bool = False) -> str:
        """
        Format debug output as string.
        
        Parameters:
        - highlight: Apply syntax highlighting
        
        Returns:
        Formatted debug output string
        """
    
    def __str__(self) -> str:
        """String representation of debug output."""
    
    def __repr__(self) -> str:
        """Detailed representation for debugging."""

class DebugArgument:
    """
    Represents a single debug argument with name, value, and metadata.
    """
    def __init__(self, value, name: str | None = None, **extra):
        """
        Initialize DebugArgument.
        
        Parameters:
        - value: The argument value
        - name: Variable name (extracted from source)
        - **extra: Additional metadata (e.g., length for sequences)
        """
    
    def str(self, highlight: bool = False) -> str:
        """
        Format argument as string.
        
        Parameters:
        - highlight: Apply syntax highlighting
        
        Returns:
        Formatted argument string with name, value, type, and metadata
        """
    
    def __str__(self) -> str:
        """String representation of debug argument."""

Integration with Pretty Printing

The debug system integrates seamlessly with devtools' pretty printing capabilities:

# Debug automatically uses pretty printing for complex structures
nested_data = {
    'level1': {
        'level2': ['item1', 'item2', 'item3'],
        'numbers': list(range(10))
    }
}
debug(nested_data)
# Output shows nicely formatted nested structure with proper indentation

Error Handling

The debug system gracefully handles various error conditions:

  • Call stack too shallow: Falls back to basic argument display
  • Code inspection failure: Shows warning and displays values without names
  • Pretty printing errors: Shows repr() with error message
  • File access issues: Uses absolute paths when relative paths fail
# Debug works even when code inspection fails
debug(some_variable)  # May show warning but still displays the value

Environment Variables

Debug behavior can be customized via environment variables:

  • PY_DEVTOOLS_WARNINGS: Show/hide warnings (default: True)
  • PY_DEVTOOLS_HIGHLIGHT: Force highlighting on/off
  • PY_DEVTOOLS_INDENT: Indentation for pretty printing (default: 4)
  • PY_DEVTOOLS_WIDTH: Output width (default: 120)

Types

# Main debug instance - pre-configured Debug() instance
debug: Debug

# Type aliases used internally
StrType = str  # String type alias for type hinting

Install with Tessl CLI

npx tessl i tessl/pypi-devtools

docs

ansi-styling.md

debug.md

index.md

pretty-printing.md

pytest-plugin.md

timing.md

tile.json