CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-prospector

Prospector is a tool to analyse Python code by aggregating the result of other tools.

Pending
Overview
Eval results
Files

formatters.mddocs/

Formatters

Output formatting system supporting multiple formats including JSON, text, XML, and IDE integrations. Formatters convert analysis results into various output formats for different use cases.

Capabilities

Formatter Base Class

class Formatter(ABC):
    def __init__(self, summary: dict[str, Any], messages: list[Message], profile: ProspectorProfile, relative_to: Optional[Path]) -> None

Base class for all output formatters.

Parameters:

  • summary: dict[str, Any] - Analysis summary information
  • messages: list[Message] - List of analysis messages
  • profile: ProspectorProfile - Configuration profile used
  • relative_to: Optional[Path] - Base path for relativizing file paths in output
@abstractmethod
def render(self, summary: bool = True, messages: bool = True, profile: bool = False) -> str

Renders the analysis results in the formatter's specific format.

Parameters:

  • summary: bool - Whether to include summary information in output
  • messages: bool - Whether to include individual messages in output
  • profile: bool - Whether to include profile information in output

Returns:

  • str - Formatted output string

Available Formatters

FORMATTERS: dict[str, type[Formatter]]

Registry of all available output formatters.

Available Formatters:

Text-Based Formatters

class TextFormatter(Formatter):
    pass

Human-readable text output format. Default formatter that provides clean, readable output for console display.

class GroupedFormatter(Formatter):
    pass

Groups messages by file and displays them in a hierarchical format. Good for understanding issues per file.

class EmacsFormatter(Formatter):
    pass

Output format compatible with Emacs compilation mode. Allows Emacs users to jump directly to issue locations.

Machine-Readable Formatters

class JsonFormatter(Formatter):
    pass

JSON output format for programmatic consumption and API integration. Includes complete message and summary information.

class YamlFormatter(Formatter):
    pass

YAML output format for human-readable structured data. Alternative to JSON with better readability.

class XunitFormatter(Formatter):
    pass

XML output in xUnit/JUnit format for CI/CD integration. Compatible with test reporting systems.

IDE and Tool Integration

class VSCodeFormatter(Formatter):  
    pass

Output format optimized for Visual Studio Code integration. Compatible with VS Code problem matcher patterns.

class GitlabFormatter(Formatter):
    pass

GitLab CI/CD compatible output format for merge request integration and code quality reporting.

Pylint Compatibility

class PylintFormatter(Formatter):
    pass

Output format that mimics Pylint's default output. Useful for tools expecting Pylint-style output.

class PylintParseableFormatter(Formatter):
    pass

Pylint-compatible parseable output format. Machine-readable format following Pylint conventions.

Usage Examples

Using Formatters Directly

from prospector.formatters import FORMATTERS
from prospector.config import ProspectorConfig
from prospector.run import Prospector

# Run analysis
config = ProspectorConfig()
prospector = Prospector(config)
prospector.execute()

# Get results
messages = prospector.get_messages()
summary = prospector.get_summary()

# Create formatter
formatter_class = FORMATTERS["json"]
formatter = formatter_class(summary, messages, config.profile, None)

# Render output
output = formatter.render(summary=True, messages=True, profile=False)
print(output)

Multiple Output Formats

from prospector.formatters import FORMATTERS
from prospector.config import ProspectorConfig
from prospector.run import Prospector

# Run analysis once
config = ProspectorConfig()
prospector = Prospector(config)
prospector.execute()

messages = prospector.get_messages()
summary = prospector.get_summary()

# Generate multiple output formats
formats_to_generate = ["json", "text", "yaml"]

for format_name in formats_to_generate:
    formatter_class = FORMATTERS[format_name]
    formatter = formatter_class(summary, messages, config.profile, None)
    
    output = formatter.render()
    
    # Save to file
    with open(f"analysis_results.{format_name}", "w") as f:
        f.write(output)
    
    print(f"Generated {format_name} output")

Formatter Configuration Examples

from prospector.formatters import FORMATTERS
from prospector.config import ProspectorConfig
from prospector.run import Prospector
from pathlib import Path

config = ProspectorConfig()
prospector = Prospector(config)
prospector.execute()

messages = prospector.get_messages()
summary = prospector.get_summary()

# Text formatter with relative paths
base_path = Path("/home/user/project")
text_formatter = FORMATTERS["text"](summary, messages, config.profile, base_path)
print("=== Text Output (with relative paths) ===")
print(text_formatter.render())

# JSON formatter with full information
json_formatter = FORMATTERS["json"](summary, messages, config.profile, None)
print("\n=== JSON Output (full info) ===")
print(json_formatter.render(summary=True, messages=True, profile=True))

# Messages only (no summary)
text_messages_only = FORMATTERS["text"](summary, messages, config.profile, None)
print("\n=== Messages Only ===")
print(text_messages_only.render(summary=False, messages=True, profile=False))

CI/CD Integration

from prospector.formatters import FORMATTERS
from prospector.config import ProspectorConfig
from prospector.run import Prospector
import json

def generate_ci_reports():
    """Generate reports for CI/CD pipeline"""
    config = ProspectorConfig()
    prospector = Prospector(config)
    prospector.execute()
    
    messages = prospector.get_messages()
    summary = prospector.get_summary()
    
    # GitLab CI format
    gitlab_formatter = FORMATTERS["gitlab"](summary, messages, config.profile, None)
    with open("gitlab-code-quality.json", "w") as f:
        f.write(gitlab_formatter.render())
    
    # JUnit XML format for test reporting
    xunit_formatter = FORMATTERS["xunit"](summary, messages, config.profile, None)
    with open("prospector-results.xml", "w") as f:
        f.write(xunit_formatter.render())
    
    # JSON for further processing
    json_formatter = FORMATTERS["json"](summary, messages, config.profile, None)
    with open("prospector-results.json", "w") as f:
        f.write(json_formatter.render())
    
    # Summary for build logs
    print(f"Analysis complete: {len(messages)} issues found")
    if summary:
        print(f"Time taken: {summary['time_taken']} seconds")
        print(f"Tools run: {', '.join(summary['tools'])}")

generate_ci_reports()

IDE Integration Examples

from prospector.formatters import FORMATTERS
from prospector.config import ProspectorConfig
from prospector.run import Prospector
import subprocess
import json

def vscode_integration():
    """Generate VS Code compatible output"""
    config = ProspectorConfig()
    prospector = Prospector(config)
    prospector.execute()
    
    messages = prospector.get_messages()
    summary = prospector.get_summary()
    
    # VS Code format
    vscode_formatter = FORMATTERS["vscode"](summary, messages, config.profile, None)
    output = vscode_formatter.render()
    
    # VS Code can parse this output when configured with appropriate problem matcher
    print(output)

def emacs_integration():
    """Generate Emacs compilation mode compatible output"""
    config = ProspectorConfig()
    prospector = Prospector(config)
    prospector.execute()
    
    messages = prospector.get_messages()
    summary = prospector.get_summary()
    
    # Emacs format
    emacs_formatter = FORMATTERS["emacs"](summary, messages, config.profile, None)
    output = emacs_formatter.render()
    
    # Emacs can jump to locations when this output is in compilation buffer
    print(output)

# Run based on environment
import os
if os.environ.get("INSIDE_EMACS"):
    emacs_integration()
elif os.environ.get("VSCODE_PID"):
    vscode_integration()

Custom Output Processing

from prospector.formatters import FORMATTERS
from prospector.config import ProspectorConfig
from prospector.run import Prospector
import json

def analyze_by_tool():
    """Analyze results grouped by tool"""
    config = ProspectorConfig()
    prospector = Prospector(config)
    prospector.execute()
    
    messages = prospector.get_messages()
    summary = prospector.get_summary()
    
    # Get raw JSON data
    json_formatter = FORMATTERS["json"](summary, messages, config.profile, None)
    json_output = json_formatter.render()
    data = json.loads(json_output)
    
    # Group messages by tool
    by_tool = {}
    for message in data.get("messages", []):
        tool = message["source"]
        if tool not in by_tool:
            by_tool[tool] = []
        by_tool[tool].append(message)
    
    # Report by tool
    print("Issues by tool:")
    for tool, tool_messages in by_tool.items():
        print(f"  {tool}: {len(tool_messages)} issues")
        
        # Show most common issue types
        codes = [msg["code"] for msg in tool_messages]
        from collections import Counter
        common_codes = Counter(codes).most_common(3)
        for code, count in common_codes:
            print(f"    {code}: {count} occurrences")

analyze_by_tool()

Custom Formatting

from prospector.formatters.base import Formatter
from prospector.message import Message
from prospector.profiles.profile import ProspectorProfile
from pathlib import Path
from typing import Any, Optional

class CustomFormatter(Formatter):
    """Example custom formatter"""
    
    def render(self, summary: bool = True, messages: bool = True, profile: bool = False) -> str:
        output_lines = []
        
        if summary and self.summary:
            output_lines.append("=== ANALYSIS SUMMARY ===")
            output_lines.append(f"Messages: {self.summary.get('message_count', 0)}")
            output_lines.append(f"Time: {self.summary.get('time_taken', 'unknown')}")
            output_lines.append("")
        
        if messages:
            output_lines.append("=== ISSUES ===")
            for message in self.messages:
                location = message.location
                if location.path:
                    file_path = location.path
                    if self.relative_to:
                        try:
                            file_path = location.path.relative_to(self.relative_to)
                        except ValueError:
                            pass
                    
                    line_info = f":{location.line}" if location.line else ""
                    output_lines.append(f"{file_path}{line_info} [{message.source}] {message.message}")
        
        return "\n".join(output_lines)

# Usage
config = ProspectorConfig()
prospector = Prospector(config)
prospector.execute()

custom_formatter = CustomFormatter(
    prospector.get_summary(),
    prospector.get_messages(),
    config.profile,
    Path(".")
)

print(custom_formatter.render())

Install with Tessl CLI

npx tessl i tessl/pypi-prospector

docs

analysis-runner.md

configuration.md

exceptions.md

file-finding.md

formatters.md

index.md

messages.md

profiles.md

tools.md

tile.json