CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-coveralls

Python interface to coveralls.io API for uploading code coverage results

Pending
Overview
Eval results
Files

coverage-processing.mddocs/

Coverage Processing

The coverage processing module extends coverage.py functionality to generate coveralls-specific reports with line-by-line coverage data and source file information. It handles data transformation, source file reading, and optional merging of JavaScript coverage results.

Capabilities

Extended Coverage Control

Extends the standard coverage.py Coverage class with coveralls-specific report generation functionality.

class coveralls(Coverage):
    """
    Extended Coverage class with coveralls report generation.
    
    Inherits all standard coverage.py functionality and adds:
    - coveralls() method for generating coveralls-formatted reports
    - Integration with CoverallsReporter for data formatting
    """
    
    def coveralls(self, base_dir, ignore_errors=False, merge_file=None):
        """
        Generate coveralls-formatted coverage report.
        
        Args:
            base_dir (str): Project root directory for relative path calculation
            ignore_errors (bool): If True, skip files that cannot be read or analyzed
            merge_file (str, optional): Path to JSON file containing additional coverage data
        
        Returns:
            list[SourceFile]: List of source files with coverage information
        """

Coverage Reporter

Specialized reporter that transforms coverage.py data into the coveralls.io format with line-by-line coverage arrays and source content.

class CoverallsReporter(Reporter):
    """
    Coverage reporter that generates coveralls.io compatible format.
    
    Extends coverage.py Reporter to produce JSON-compatible data structure
    with source content and line-by-line coverage arrays.
    """
    
    def report(self, base_dir, ignore_errors=False, merge_file=None):
        """
        Generate detailed coverage report for coveralls.io.
        
        Args:
            base_dir (str): Project root directory for relative paths
            ignore_errors (bool): Skip files with read/analysis errors
            merge_file (str, optional): JSON file with additional coverage data to merge
        
        Returns:
            list[dict]: List of source file dictionaries with:
                - name: str - relative file path
                - source: str - complete file content  
                - coverage: list[int|None] - line coverage (None=non-executable, 0=missed, 1=hit)
        
        Raises:
            IOError: If source files cannot be read and ignore_errors=False
            NotPython: If files cannot be analyzed and ignore_errors=False
        """

Data Processing Pipeline

Coverage Analysis Flow

  1. File Discovery: Uses coverage.py file reporters to identify measured files
  2. Source Reading: Reads complete source content for each file
  3. Analysis: Analyzes coverage data to identify statements and missing lines
  4. Transformation: Converts to line-by-line coverage arrays
  5. Merging: Optionally merges additional coverage data from JSON files

Coverage Array Format

# Line-by-line coverage representation
coverage_array: list[int | None]
    # None: Line is not executable (comments, blank lines, etc.)
    # 0: Line is executable but was not executed (missed)  
    # 1: Line is executable and was executed (hit)

# Example for a 5-line file:
coverage_example = [None, 1, 1, 0, None]
    # Line 1: Non-executable (None)
    # Line 2: Hit (1) 
    # Line 3: Hit (1)
    # Line 4: Missed (0)
    # Line 5: Non-executable (None)

Usage Examples

Basic Coverage Processing

from coveralls.control import coveralls

# Create coverage instance
cov = coveralls()
cov.load()

# Generate coveralls report
source_files = cov.coveralls(
    base_dir='/path/to/project',
    ignore_errors=False
)

# Each source file contains:
for file_info in source_files:
    print(f"File: {file_info['name']}")
    print(f"Lines: {len(file_info['coverage'])}")
    print(f"Source length: {len(file_info['source'])}")

Error Handling Options

# Ignore files that cannot be read or analyzed
source_files = cov.coveralls(
    base_dir='/path/to/project',
    ignore_errors=True  # Skip problematic files
)

# Strict mode (default) - raise exceptions
try:
    source_files = cov.coveralls(base_dir='/path/to/project')
except IOError as e:
    print(f"Source file read error: {e}")
except NotPython as e:
    print(f"File analysis error: {e}")

Merging JavaScript Coverage

# Merge JavaScript coverage data
source_files = cov.coveralls(
    base_dir='/path/to/project',
    merge_file='coverage/js-coverage.json'
)

# The merge file should contain JSON in format:
merge_format = {
    "source_files": [
        {
            "name": "src/app.js",
            "source": "function hello() { return 'world'; }",
            "coverage": [1, 1, 1]
        }
    ]
}

Direct Reporter Usage

from coverage.control import Coverage
from coveralls.report import CoverallsReporter

# Standard coverage.py setup
cov = Coverage()
cov.load()

# Create coveralls reporter
reporter = CoverallsReporter(cov, cov.config)
reporter.find_file_reporters(None)

# Generate report directly
source_files = reporter.report(
    base_dir='/path/to/project',
    ignore_errors=False,
    merge_file=None
)

Integration with Coverage Tools

Coverage.py Integration

The module integrates seamlessly with coverage.py configuration:

# .coveragerc
[run]
source = mypackage
omit = 
    */tests/*
    */venv/*
    setup.py

[report]
exclude_lines =
    pragma: no cover
    def __repr__
    raise AssertionError

Supported Coverage Workflows

# Standard coverage.py
coverage run -m pytest
coverage report
coveralls

# pytest-cov 
pytest --cov=mypackage
coveralls

# nose with nosexcover
nosetests --with-xcoverage --cover-package=mypackage
coveralls

Error Conditions and Handling

File Access Errors

  • IOError: Source files cannot be read (permissions, missing files)
  • NotPython: Files cannot be analyzed by coverage.py (binary files, etc.)
  • Handling: Use ignore_errors=True to skip problematic files

Data Quality Issues

  • Empty coverage data: No measured files found
  • Malformed merge files: Invalid JSON format in merge_file
  • Path resolution: Incorrect base_dir causing path calculation errors

Best Practices

# Robust coverage processing
try:
    cov = coveralls()
    cov.load()
    
    source_files = cov.coveralls(
        base_dir=os.path.abspath('.'),
        ignore_errors=True,  # Skip problematic files
        merge_file='coverage.json' if os.path.exists('coverage.json') else None
    )
    
    if not source_files:
        print("Warning: No coverage data found")
        
except Exception as e:
    print(f"Coverage processing failed: {e}")

Install with Tessl CLI

npx tessl i tessl/pypi-python-coveralls

docs

api-communication.md

coverage-processing.md

index.md

main-workflow.md

repository-integration.md

tile.json