CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-stack-data

Extract data from python stack frames and tracebacks for informative displays

Overview
Eval results
Files

serialization.mddocs/

Data Serialization

Structured data export functionality for converting stack traces and frame information into dictionaries and lists suitable for JSON serialization, programmatic processing, and integration with external systems or APIs.

Capabilities

Serializer Configuration

Central serialization class that converts stack traces, exceptions, and frame information into structured data formats (dictionaries and lists) for programmatic processing.

class Serializer:
    def __init__(self, *,
                 options: Optional[Options] = None,
                 pygmented: bool = False,
                 show_executing_node: bool = True,
                 pygments_formatter_cls = None,
                 pygments_formatter_kwargs: Optional[dict] = None,
                 pygments_style: str = "monokai",
                 executing_node_modifier: str = "bg:#005080",
                 use_code_qualname: bool = True,
                 strip_leading_indent: bool = True,
                 html: bool = False,
                 chain: bool = True,
                 collapse_repeated_frames: bool = True,
                 show_variables: bool = False):
        """
        Create Serializer for structured data export.
        
        Args:
            options: Stack data options for frame analysis
            pygmented: Whether to include syntax highlighting in output
            show_executing_node: Whether to mark executing nodes in output
            pygments_formatter_cls: Custom Pygments formatter class
            pygments_formatter_kwargs: Arguments for Pygments formatter
            pygments_style: Pygments style name for syntax highlighting
            executing_node_modifier: CSS-like modifier for executing node marking
            use_code_qualname: Whether to use qualified names for code objects
            strip_leading_indent: Whether to strip leading indentation from source
            html: Whether to escape HTML characters in output
            chain: Whether to include exception causes and contexts
            collapse_repeated_frames: Whether to collapse repeated frames
            show_variables: Whether to include variable information
        """

Exception Serialization

Functions for converting exceptions and their tracebacks into structured dictionary format suitable for JSON serialization or API responses.

def format_exception(self, e: Optional[BaseException] = None) -> List[dict]:
    """
    Serialize exception to list of dictionaries.
    
    Args:
        e: Exception to serialize (uses sys.exc_info() if None)
        
    Returns:
        List of dictionaries containing exception information:
        - Exception message and type
        - Traceback frames with source code
        - Variable information if enabled
        - Chained exceptions if present
    """

def format_traceback_part(self, e: BaseException) -> dict:
    """
    Serialize single traceback part to dictionary.
    
    Args:
        e: Exception containing traceback to serialize
        
    Returns:
        Dictionary containing:
        - exception_type: Exception class name
        - exception_message: Exception message
        - frames: List of frame dictionaries
        - is_cause: Whether this is an exception cause
        - is_context: Whether this is an exception context
    """

Stack Serialization

Functions for converting stack traces and frame sequences into structured data format for programmatic analysis and processing.

def format_stack(self, frame_or_tb: Optional[Union[FrameType, TracebackType]] = None) -> List[dict]:
    """
    Serialize stack trace to list of dictionaries.
    
    Args:
        frame_or_tb: Frame or traceback to start from (uses current frame if None)
        
    Returns:
        List of dictionaries containing stack frame information:
        - Frame metadata (filename, function, line number)
        - Source code lines with context
        - Variable information if enabled
        - Repeated frame summaries if present
    """

def format_stack_data(self, stack: Iterable[Union[FrameInfo, RepeatedFrames]]) -> Iterable[dict]:
    """
    Serialize stack data objects to dictionaries.
    
    Args:
        stack: Iterable of FrameInfo and RepeatedFrames objects
        
    Yields:
        Dictionary for each stack element containing:
        - Frame type (frame or repeated_frames)
        - Frame information and source code
        - Variable data if enabled
    """

Frame Serialization

Functions for converting individual stack frames into structured dictionary format with complete metadata and source information.

def format_frame(self, frame: Union[FrameInfo, FrameType, TracebackType]) -> dict:
    """
    Serialize individual frame to dictionary.
    
    Args:
        frame: Frame object to serialize (FrameInfo, FrameType, or TracebackType)
        
    Returns:
        Dictionary containing:
        - filename: Absolute path to source file
        - function_name: Name of function or method
        - function_qualname: Qualified name if use_code_qualname is True
        - lineno: Current line number
        - lines: List of source line dictionaries
        - variables: List of variable dictionaries if show_variables is True
    """

def format_repeated_frames(self, repeated_frames: RepeatedFrames) -> dict:
    """
    Serialize repeated frames to dictionary.
    
    Args:
        repeated_frames: RepeatedFrames object
        
    Returns:
        Dictionary containing:
        - type: "repeated_frames"
        - count: Number of repeated frames
        - description: Brief description of repetition
        - frames: Sample frame information
    """

def should_include_frame(self, frame_info: FrameInfo) -> bool:
    """
    Determine whether to include frame in output.
    
    Args:
        frame_info: FrameInfo object to check
        
    Returns:
        Always True (all frames included by default)
    """

Line Serialization

Functions for converting source code lines into structured format with line numbers, content, and metadata.

def format_lines(self, lines: Iterable[Union[Line, Any]]) -> Iterable[dict]:
    """
    Serialize source lines to dictionaries.
    
    Args:
        lines: Iterable of Line objects and other line types
        
    Yields:
        Dictionary for each line containing:
        - line_type: Type of line (source, gap, blank_range)
        - lineno: Line number for source lines
        - text: Source code text
        - is_current: Whether this is the executing line
    """

def format_line(self, line: Line) -> dict:
    """
    Serialize individual source line to dictionary.
    
    Args:
        line: Line object to serialize
        
    Returns:
        Dictionary containing:
        - line_type: "source"
        - lineno: Line number
        - text: Source code text (processed according to settings)
        - is_current: Whether this is the currently executing line
    """

Variable Serialization

Functions for converting variable information into structured format with names, values, and type information.

def format_variables(self, frame_info: FrameInfo) -> Iterable[dict]:
    """
    Serialize variables in frame to dictionaries.
    
    Args:
        frame_info: FrameInfo object containing variables
        
    Yields:
        Dictionary for each variable containing:
        - name: Variable name or expression
        - value: Formatted string representation of value
        - type: Type name of the value
    """

def format_variable(self, var: Variable) -> dict:
    """
    Serialize individual variable to dictionary.
    
    Args:
        var: Variable object to serialize
        
    Returns:
        Dictionary containing:
        - name: Variable name or expression text
        - value: Formatted string representation
        - type: Type name of the variable value
    """

def format_variable_part(self, text: str) -> str:
    """
    Format text part of variable display.
    
    Args:
        text: Text to format
        
    Returns:
        Text with HTML escaping if html=True
    """

def format_variable_value(self, value: Any) -> str:
    """
    Format variable value for display.
    
    Args:
        value: Variable value to format
        
    Returns:
        String representation of the value
    """

Usage Examples

Basic Exception Serialization

from stack_data import Serializer
import json

# Create serializer
serializer = Serializer()

try:
    result = 1 / 0
except Exception as e:
    # Serialize exception to structured data
    exception_data = serializer.format_exception(e)
    
    # Convert to JSON
    json_output = json.dumps(exception_data, indent=2)
    print(json_output)
    
    # Access structured data
    for frame_dict in exception_data:
        if 'frames' in frame_dict:
            for frame in frame_dict['frames']:
                print(f"Function: {frame['function_name']}")
                print(f"File: {frame['filename']}:{frame['lineno']}")

Stack Serialization with Variables

from stack_data import Serializer, Options

# Create serializer with variable information
serializer = Serializer(
    show_variables=True,  # Include variable data
    use_code_qualname=True,  # Use qualified function names
    strip_leading_indent=True  # Clean up source code
)

import inspect

def example_function():
    local_var = "example"
    frame = inspect.currentframe()
    
    # Serialize current stack
    stack_data = serializer.format_stack(frame)
    
    return stack_data

# Get serialized stack data
data = example_function()

# Process structured data
for frame_dict in data:
    print(f"Frame: {frame_dict['function_name']}")
    
    # Access variables if present
    if 'variables' in frame_dict:
        for var in frame_dict['variables']:
            print(f"  {var['name']} = {var['value']} ({var['type']})")
    
    # Access source lines
    for line in frame_dict['lines']:
        if line['line_type'] == 'source':
            marker = ">>> " if line['is_current'] else "    "
            print(f"{marker}{line['lineno']}: {line['text']}")

API Response Format

from stack_data import Serializer
import json

def create_error_response(exception):
    """Create API error response with stack data."""
    
    serializer = Serializer(
        show_variables=False,  # Don't expose variables in API
        html=True,  # Escape HTML for safety
        chain=True,  # Include exception chains
        collapse_repeated_frames=True  # Compact output
    )
    
    # Serialize exception
    stack_data = serializer.format_exception(exception)
    
    # Create API response format
    response = {
        "error": True,
        "message": str(exception),
        "type": exception.__class__.__name__,
        "stack_trace": stack_data,
        "timestamp": "2023-01-01T00:00:00Z"
    }
    
    return response

# Usage
try:
    # Some operation that fails
    raise ValueError("Something went wrong")
except Exception as e:
    error_response = create_error_response(e)
    print(json.dumps(error_response, indent=2))

Custom Data Processing

from stack_data import Serializer, FrameInfo

class CustomAnalyzer:
    def __init__(self):
        self.serializer = Serializer(
            show_variables=True,
            pygmented=False,  # No highlighting for analysis
            use_code_qualname=True
        )
    
    def analyze_frame(self, frame):
        """Extract specific information from frame."""
        frame_data = self.serializer.format_frame(frame)
        
        analysis = {
            "file": frame_data["filename"],
            "function": frame_data["function_qualname"],
            "line_count": len([l for l in frame_data["lines"] 
                             if l["line_type"] == "source"]),
            "variable_count": len(frame_data.get("variables", [])),
            "current_line": frame_data["lineno"]
        }
        
        return analysis
    
    def analyze_exception(self, exception):
        """Analyze exception for metrics."""
        exception_data = self.serializer.format_exception(exception)
        
        metrics = {
            "exception_type": exception.__class__.__name__,
            "frame_count": 0,
            "unique_files": set(),
            "functions": []
        }
        
        for part in exception_data:
            if "frames" in part:
                for frame in part["frames"]:
                    metrics["frame_count"] += 1
                    metrics["unique_files"].add(frame["filename"])
                    metrics["functions"].append(frame["function_name"])
        
        metrics["unique_files"] = len(metrics["unique_files"])
        return metrics

# Usage
analyzer = CustomAnalyzer()

try:
    result = 1 / 0
except Exception as e:
    metrics = analyzer.analyze_exception(e)
    print(f"Exception analysis: {metrics}")

HTML-Safe Serialization

from stack_data import Serializer

# Create HTML-safe serializer
html_serializer = Serializer(
    html=True,  # Escape HTML characters
    pygmented=True,  # Include syntax highlighting data
    show_variables=True,  # Include variables (safely escaped)
    strip_leading_indent=True
)

# Serialize for web display
try:
    user_input = "<script>alert('xss')</script>"
    eval(user_input)  # Dangerous operation
except Exception as e:
    safe_data = html_serializer.format_exception(e)
    
    # Data is now safe for HTML display
    for frame_dict in safe_data:
        if 'frames' in frame_dict:
            for frame in frame_dict['frames']:
                # Variables and source code are HTML-escaped
                for line in frame['lines']:
                    if line['line_type'] == 'source':
                        print(f"Safe HTML: {line['text']}")

Minimal Data Export

from stack_data import Serializer

# Serializer for minimal data export
minimal_serializer = Serializer(
    show_variables=False,  # No variables
    pygmented=False,  # No highlighting
    show_executing_node=False,  # No execution markers
    strip_leading_indent=True,  # Clean source
    collapse_repeated_frames=True  # Compact recursive frames
)

import inspect

def get_call_stack():
    """Get minimal call stack information."""
    frame = inspect.currentframe()
    stack_data = minimal_serializer.format_stack(frame)
    
    # Extract just the essential information
    call_stack = []
    for frame_dict in stack_data:
        if frame_dict.get('type') == 'repeated_frames':
            call_stack.append({
                "type": "repeated",
                "count": frame_dict.get('count', 0),
                "description": frame_dict.get('description', '')
            })
        else:
            call_stack.append({
                "type": "frame",
                "function": frame_dict.get('function_name', ''),
                "file": frame_dict.get('filename', ''),
                "line": frame_dict.get('lineno', 0)
            })
    
    return call_stack

# Usage
stack = get_call_stack()
print(f"Call stack has {len(stack)} entries")

Install with Tessl CLI

npx tessl i tessl/pypi-stack-data

docs

formatting.md

frame-analysis.md

index.md

serialization.md

tile.json