CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pylama

Code audit tool for python

Pending
Overview
Eval results
Files

error-processing.mddocs/

Error Processing

Error representation, deduplication, and formatting capabilities for managing linting results across multiple tools and output formats. Pylama provides comprehensive error handling with intelligent deduplication and flexible formatting options.

Type Imports

from typing import Any, Dict, Generator, List, Optional, Set, Tuple
from argparse import Namespace

Capabilities

Error Representation

Core error class that represents individual linting issues with comprehensive metadata.

class Error:
    """
    Represents a single linting error with source information.
    
    Attributes:
        filename: str - File path where error occurred
        lnum: int - Line number (1-based)
        col: int - Column number (1-based)  
        message: str - Error message text
        etype: str - Error type (E=error, W=warning, etc.)
        source: str - Linter that generated the error
        number: str - Error code (extracted from text)
    """
    
    def __init__(
        self,
        source: str = "pylama",
        col: int = 1,
        lnum: int = 1,
        type: Optional[str] = None,
        text: str = "unknown error",
        filename: str = "",
        number: str = "",
        **_
    ):
        """
        Initialize error with position and message information.
        
        Args:
            source: Name of linter that found the error
            col: Column number (1-based)
            lnum: Line number (1-based)
            type: Error type/severity (stored as etype attribute)
            text: Error message text (stored as message attribute)
            filename: File path where error occurred
            number: Error code number
            **_: Additional unused parameters
        """

    def to_dict(self) -> Dict[str, Any]:
        """
        Convert error to dictionary representation.
        
        Returns:
            Dict[str, Any]: Error data as dictionary with keys:
                - filename, lnum, col, message, etype, source, number
        """

    def format(self, template: str) -> str:
        """
        Format error using template string.
        
        Args:
            template: Format string with placeholders like {filename}, {lnum}, etc.
            
        Returns:
            str: Formatted error message
            
        Available template variables:
        - {filename}: File path
        - {lnum}: Line number
        - {col}: Column number
        - {message}: Error message text
        - {etype}: Error type
        - {source}: Linter name
        - {number}: Error code
        """

Error Deduplication

Remove duplicate errors that are reported by multiple linters for the same issue.

def remove_duplicates(errors: List[Error]) -> Generator[Error, None, None]:
    """
    Remove duplicate errors from different linters.
    
    Args:
        errors: List of Error objects potentially containing duplicates
        
    Yields:
        Error: Unique errors with duplicates removed
        
    Deduplication rules:
    - Errors at same location with equivalent meanings are deduplicated
    - Priority given to more specific linters (e.g., pycodestyle over pylint for style)
    - Common duplicate patterns handled automatically (see DUPLICATES mapping)
    """

Error Sorting

Sort errors according to configurable criteria.

def default_sorter(err: Error) -> Any:
    """
    Default error sorting function.
    
    Args:
        err: Error object to generate sort key for
        
    Returns:
        Any: Sort key (typically line number for default sorter)
        
    Default sort order:
    - Line number (ascending)
    """

Error Display

Format and output errors using various output formats.

def display_errors(errors: List[Error], options: Namespace):
    """
    Format and display errors using specified format.
    
    Args:
        errors: List of Error objects to display
        options: Configuration options containing format settings
        
    Supported formats:
    - 'json': JSON array of error dictionaries
    - 'pylint': Pylint-compatible format  
    - 'pycodestyle': pycodestyle-compatible format
    - 'parsable': Default parsable format (same as default)
    - Custom format strings
    
    Output is sent to the configured logger at WARNING level.
    """

Duplicate Error Mappings

Pylama automatically deduplicates common errors reported by multiple linters:

DUPLICATES: Dict[Tuple[str, str], Set] = {
    # Multiple statements on one line
    ("pycodestyle", "E701"): {("pylint", "C0321")},
    
    # Unused variable
    ("pylint", "W0612"): {("pyflakes", "W0612")},
    
    # Undefined variable  
    ("pylint", "E0602"): {("pyflakes", "E0602")},
    
    # Unused import
    ("pylint", "W0611"): {("pyflakes", "W0611")},
    
    # Whitespace issues
    ("pylint", "C0326"): {
        ("pycodestyle", "E202"),  # whitespace before ')'
        ("pycodestyle", "E211"),  # whitespace before '('
        ("pycodestyle", "E222"),  # multiple spaces after operator
        ("pycodestyle", "E225"),  # missing whitespace around operator
        ("pycodestyle", "E251"),  # unexpected spaces
    },
    
    # Long lines
    ("pylint", "C0301"): {("pycodestyle", "E501")},
    
    # Other common duplicates...
}

Usage Examples

Basic Error Processing

from pylama.main import check_paths
from pylama.config import parse_options
from pylama.errors import remove_duplicates

# Get errors from checking
options = parse_options(['--linters=pycodestyle,pylint', 'myfile.py'])
errors = check_paths(['myfile.py'], options)

# Remove duplicates
unique_errors = list(remove_duplicates(errors))
print(f"Found {len(errors)} total, {len(unique_errors)} unique errors")

Custom Error Formatting

from pylama.errors import Error

# Create error object
error = Error(
    source="pycodestyle",
    col=10,
    lnum=42,
    type="E",
    text="E501 line too long (82 > 79 characters)",
    filename="example.py"
)

# Format with different templates
default_format = "{filename}:{lnum}:{col} [{etype}] {number} {message} [{source}]"
pylint_format = "{filename}:{lnum}: [{etype}] {number} {message} [{source}]"

print(error.format(default_format))
print(error.format(pylint_format))

# Convert to dictionary
error_dict = error.to_dict()
print(error_dict)

# Access error message
print(f"Error message: {error.message}")

JSON Output Processing

import json
from pylama.main import check_paths
from pylama.config import parse_options

# Configure for JSON output
options = parse_options(['--format=json', '--linters=pyflakes', 'myfile.py'])
errors = check_paths(['myfile.py'], options)

# Process as JSON data
error_data = [error.to_dict() for error in errors]
json_output = json.dumps(error_data, indent=2)
print(json_output)

# Filter by error type
warnings = [e for e in errors if e.etype == 'W']
errors_only = [e for e in errors if e.etype == 'E']

# Access error messages
for error in errors:
    print(f"File: {error.filename}, Message: {error.message}")

Custom Error Sorting

from pylama.errors import Error

errors = [
    Error(source="pycodestyle", col=5, lnum=10, type="E", text="E501 line too long", filename="file1.py"),
    Error(source="pylint", col=1, lnum=5, type="W", text="W0612 unused variable", filename="file1.py"),
    Error(source="pyflakes", col=1, lnum=1, type="F", text="F401 unused import", filename="file2.py"),
]

# Sort by severity (errors first, then warnings)
def severity_sorter(err):
    severity_order = {'E': 0, 'F': 1, 'W': 2}
    return (severity_order.get(err.etype, 999), err.filename, err.lnum)

sorted_errors = sorted(errors, key=severity_sorter)

# Sort by error source (linter)
def source_sorter(err):
    return (err.source, err.filename, err.lnum)

sorted_by_source = sorted(errors, key=source_sorter)

Error Analysis

from collections import defaultdict
from pylama.main import check_paths
from pylama.config import parse_options

# Analyze error patterns
options = parse_options(['src/'])
errors = check_paths(['src/'], options)

# Group by error type
by_type = defaultdict(list)
for error in errors:
    by_type[error.etype].append(error)

# Group by source linter
by_source = defaultdict(list)
for error in errors:
    by_source[error.source].append(error)

# Group by file
by_file = defaultdict(list)
for error in errors:
    by_file[error.filename].append(error)

# Print summary
print("Error Summary:")
print(f"Total errors: {len(errors)}")
print(f"Files with issues: {len(by_file)}")
print(f"Error types: {list(by_type.keys())}")
print(f"Linters used: {list(by_source.keys())}")

# Print messages for each error
for error in errors:
    print(f"{error.filename}:{error.lnum} - {error.message}")

Format Templates

DEFAULT_FORMAT: str = "{filename}:{lnum}:{col} [{etype}] {number} {message} [{source}]"

MESSAGE_FORMATS: Dict[str, str] = {
    "pylint": "{filename}:{lnum}: [{etype}] {number} {message} [{source}]",
    "pycodestyle": "{filename}:{lnum}:{col} {number} {message} [{source}]", 
    "parsable": DEFAULT_FORMAT,
}

Install with Tessl CLI

npx tessl i tessl/pypi-pylama

docs

async-processing.md

configuration.md

error-processing.md

index.md

main-interface.md

plugin-development.md

pytest-integration.md

vcs-hooks.md

tile.json