Skip to content

kairos-xx/typecoverage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Typecoverage Logo

πŸ” Typecoverage - Python Type Annotation Analyzer

A strict CLI + library API to report untyped variables, arguments, and function returns in Python code

Python 3.11+ MIT License Code Style: Black

🎯 What is Typecoverage?

Typecoverage is a comprehensive Python static analysis tool that identifies missing type annotations in your codebase. Unlike other type checkers that focus on type correctness, Typecoverage specifically targets type annotation coverage - ensuring your code has complete type hints for maintainability and clarity.

✨ Key Features

  • πŸ” Comprehensive Detection - Finds missing annotations in functions, methods, variables, and returns
  • 🎯 Multiple Input Types - Analyze files, directories, code strings, live Python objects, and more
  • πŸ“Š Rich Output Formats - Human-readable text with colors or machine-readable JSON
  • βš™οΈ Flexible Filtering - Smart defaults with configurable rules for different coding patterns
  • 🚫 Comment Suppression - Standard # type: ignore and # noqa support
  • πŸš€ High Performance - Parallel processing for large codebases
  • πŸ› οΈ CI/CD Ready - Exit codes and JSON output for continuous integration
  • πŸ“ Detailed Context - Source code snippets around issues for easy fixing

πŸš€ Quick Example

from typecoverage import detect_untyped

# Analyze code string
code = """
def calculate_total(items, tax_rate):
    subtotal = sum(item.price for item in items)
    return subtotal * (1 + tax_rate)
"""

result = detect_untyped(code, statistics=True)
print(result)

Output:

Found 3 type annotation issues

πŸ“ <string>
  <string>:2:20 - Missing type annotation for argument "items"
    1 β”‚ 
  β–Ί 2 β”‚ def calculate_total(items, tax_rate):
    3 β”‚     subtotal = sum(item.price for item in items)

  <string>:2:27 - Missing type annotation for argument "tax_rate"
    1 β”‚ 
  β–Ί 2 β”‚ def calculate_total(items, tax_rate):
    3 β”‚     subtotal = sum(item.price for item in items)

  <string>:2:1 - Missing return type annotation "calculate_total"
    1 β”‚ 
  β–Ί 2 β”‚ def calculate_total(items, tax_rate):
    3 β”‚     subtotal = sum(item.price for item in items)

πŸ“Š Summary
  Total issues: 3
  πŸ”΄ Missing argument types: 2
  🟑 Missing return types: 1

πŸ“¦ Installation

From Source (Current)

git clone <repository-url>
cd typecoverage-project
pip install -r requirements.txt

Using the Package

# Install in development mode
pip install -e .

# Or install directly
python setup.py install

🏁 Quick Start

Command Line Usage

# Using the module
python -m typecoverage myfile.py

# Using the installed command
typecoverage myfile.py

# Analyze entire project with statistics
typecoverage --recursive --statistics src/

# JSON output for CI/CD
typecoverage --format json --exit-nonzero-on-issues src/ > report.json

# Include context lines for easier fixing
typecoverage --context-lines 3 src/main.py

Python API Usage

from typecoverage import TypeCoverage, detect_untyped

# Simple analysis
result = detect_untyped("def func(x): return x", statistics=True)
print(result)

# Advanced analysis
checker = TypeCoverage()
issues, errors = checker.analyze_targets(
    "src/",
    recursive=True,
    context_lines=2,
    exclude=["__pycache__", "tests"],
)

stats = checker.compute_stats(issues)
print(f"Found {stats.total} issues across {len(set(i.file for i in issues))} files")

🎯 Supported Input Types

Typecoverage can analyze various types of targets:

Input Type Example Description
Files main.py Individual Python files
Directories src/ Directory trees (with --recursive)
Glob Patterns **/*.py Wildcard file matching
Code Strings "def func(x): pass" Direct Python code
Live Functions my_function Runtime function objects
Classes MyClass Class objects
Modules import mymodule; mymodule Module objects
Paths Path("src/main.py") pathlib.Path objects

βš™οΈ Configuration

Command Line Options

# Analysis options
--recursive              # Recurse into subdirectories
--context-lines N        # Show N lines of context around issues
--statistics             # Include summary statistics

# Output options  
--format json            # JSON output instead of text
--output FILE            # Write to file instead of stdout
--force-color            # Force ANSI colors even when piped

# File filtering
--extensions .py,.pyx    # File extensions to analyze
--exclude tests,docs     # Exclude paths containing substrings

# Variable filtering (default: ignore these)
--no-ignore-underscore-vars    # Include _private variables
--no-ignore-for-targets        # Include for loop variables
--no-ignore-except-vars        # Include exception variables  
--no-ignore-context-vars       # Include with statement variables
--no-ignore-comprehensions     # Include list/dict comprehension vars

# Exit behavior
--exit-nonzero-on-issues       # Exit 1 if any issues found
--fail-under N                 # Exit 1 if >= N issues found

Configuration File

Create pyproject.toml configuration:

[tool.typecoverage]
recursive = true
statistics = true
context-lines = 2
exclude = ["tests", "__pycache__", "build"]
ignore-underscore-vars = true
exit-nonzero-on-issues = true
fail-under = 50

🚫 Issue Suppression

Use standard Python suppression comments:

# Suppress all issues on this line
def my_function(x, y):  # type: ignore
    return x + y

# Suppress specific issue types
def another_function(x, y):  # noqa: ANN001,ANN201
    return x + y

# Suppress on previous line
# type: ignore
def third_function(x, y):
    return x + y

Supported patterns:

  • # type: ignore - Suppress all type checking issues
  • # type: ignore[code] - Suppress specific error codes
  • # noqa / # noqa: code - Flake8-style suppression
  • # mypy: ignore / # pyright: ignore - Tool-specific suppression

πŸ“Š Understanding the Output

Text Format

Found 5 type annotation issues

πŸ“ src/calculator.py
  src/calculator.py:15:8 - Missing type annotation for argument "value"
    14 β”‚     def process_value(self, value, multiplier=1):
  β–Ί 15 β”‚         result = value * multiplier
    16 β”‚         return result

πŸ“Š Summary
  Total issues: 5
  πŸ”΄ Missing argument types: 3
  🟑 Missing return types: 1  
  πŸ”΅ Missing variable types: 1

JSON Format

{
  "version": "0.1.8",
  "issues": [
    {
      "file": "src/calculator.py",
      "line": 15,
      "column": 8,
      "type": "untyped-argument", 
      "name": "value",
      "context": ["    def process_value(self, value, multiplier=1):", "        result = value * multiplier"]
    }
  ],
  "statistics": {
    "total": 5,
    "untyped-argument": 3,
    "untyped-return": 1,
    "untyped-variable": 1
  }
}

πŸ”§ Advanced Usage

Analyzing Live Objects

from typecoverage import TypeCoverage

def my_function(x, y):
    return x + y

class MyClass:
    def method(self, value):
        return value * 2

checker = TypeCoverage()

# Analyze function
issues, _ = checker.analyze_object(my_function, context_lines=1)
print(f"Function issues: {len(issues)}")

# Analyze class
issues, _ = checker.analyze_object(MyClass, context_lines=1)
print(f"Class issues: {len(issues)}")

Batch Analysis

from pathlib import Path
from typecoverage import analyze_targets

# Analyze multiple targets
issues, errors = analyze_targets(
    "src/main.py",           # Specific file
    Path("lib/"),            # Directory path
    "utils/**/*.py",         # Glob pattern
    my_function,             # Live object
    recursive=True,
    exclude=["test_", "__pycache__"],
    context_lines=1,
)

print(f"Total issues: {len(issues)}")
print(f"Errors: {len(errors)}")

πŸ—οΈ CI/CD Integration

GitHub Actions

name: Type Annotation Coverage
on: [push, pull_request]

jobs:
  typecoverage:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.11'
    
    - name: Install dependencies
      run: pip install -r requirements.txt
    
    - name: Run typecoverage
      run: |
        typecoverage \
          --format json \
          --exit-nonzero-on-issues \
          --recursive \
          --output typecoverage-report.json \
          src/
    
    - name: Upload results
      uses: actions/upload-artifact@v3
      if: always()
      with:
        name: typecoverage-report
        path: typecoverage-report.json

Pre-commit Hook

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: typecoverage
        name: typecoverage
        entry: typecoverage
        language: system
        args: [--exit-nonzero-on-issues, --recursive, src/]
        files: \.py$

πŸ“š Examples and Demos

Basic Usage Demo

python demos/basic_usage.py

Advanced Features Demo

python demos/advanced_usage.py

CLI Examples

python demos/cli_examples.py

Test the Library

# Run comprehensive test suite
pytest tests/ -v --cov=typecoverage --cov-report=term-missing

# Test specific functionality
pytest tests/test_core.py::TestTypeCoverage -v

πŸ—οΈ Project Structure

β”œβ”€β”€ typecoverage/
β”‚   β”œβ”€β”€ __init__.py          # Public API exports
β”‚   β”œβ”€β”€ __main__.py          # CLI entry point
β”‚   └── core.py              # Main typecoverage implementation
β”œβ”€β”€ src/
β”‚   └── core.py              # Development version
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ test_core.py         # Comprehensive test suite  
β”‚   └── test_suppressions.py # Suppression functionality tests
β”œβ”€β”€ demos/
β”‚   β”œβ”€β”€ basic_usage.py       # Basic usage examples
β”‚   β”œβ”€β”€ advanced_usage.py    # Advanced features demo
β”‚   └── cli_examples.py      # CLI usage examples
β”œβ”€β”€ docs/
β”‚   └── wiki/               # Comprehensive documentation
β”‚       β”œβ”€β”€ Home.md         # Wiki home page
β”‚       β”œβ”€β”€ Quick-Start.md  # Getting started guide
β”‚       β”œβ”€β”€ API-Reference.md# Complete API docs
β”‚       └── CLI-Guide.md    # Command-line reference
β”œβ”€β”€ scripts/                # Development utilities
β”œβ”€β”€ logs/                   # Analysis logs
β”œβ”€β”€ setup.py               # Package setup
β”œβ”€β”€ pyproject.toml         # Project configuration
└── README.md              # This file

🀝 Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository and clone your fork
  2. Install development dependencies: pip install -r requirements.txt
  3. Run tests: pytest tests/ -v
  4. Check code style: ruff check . && black . --check
  5. Make your changes and add tests
  6. Run the full test suite: pytest tests/ --cov=typecoverage
  7. Submit a pull request with a clear description

Development Workflow

# Set up development environment
pip install -r requirements.txt

# Run code formatting
black . --line-length 79
isort . -l 79 -m 1
ruff format . --line-length 79

# Run linting
ruff check .
pyright

# Run tests with coverage
pytest tests/ --cov=typecoverage --cov-report=term-missing

πŸ“ˆ Roadmap

  • Core Analysis Engine - AST-based type annotation detection
  • CLI Interface - Full command-line interface
  • Python API - Programmatic access
  • Multiple Input Types - Files, directories, code strings, live objects
  • Output Formats - Text and JSON with statistics
  • Comment Suppression - Standard suppression patterns
  • Configuration Files - pyproject.toml support
  • IDE Extensions - VS Code, PyCharm plugin support
  • Type Hint Suggestions - Automated type annotation suggestions
  • Incremental Analysis - Only check changed files
  • Custom Rules - User-defined annotation requirements
  • HTML Reports - Rich web-based reporting

❓ FAQ

Q: How does this differ from mypy or pyright? A: Mypy and pyright focus on type correctness (catching type errors). Typecoverage focuses on type coverage (ensuring annotations exist). Use them together for comprehensive type safety.

Q: Can I use this with existing type checkers?
A: Absolutely! Typecoverage complements mypy, pyright, and other type checkers. Run typecoverage first to ensure annotations exist, then use other tools to verify type correctness.

Q: What about performance on large codebases? A: Typecoverage uses parallel processing and is optimized for speed. For very large projects, use --exclude to skip unnecessary directories and --extensions to limit file types.

Q: How do I handle legacy code with many issues? A: Start with --fail-under set to your current issue count, then gradually reduce it. Use suppression comments for intentionally untyped code.

πŸ“„ License

MIT License - see LICENSE file for details.

πŸ™ Acknowledgments

  • Built with Python's ast module for accurate source code analysis
  • Inspired by flake8, mypy, and other Python code quality tools
  • Uses parallel processing for performance on large codebases
  • Follows Google-style docstrings and modern Python practices

Made with ❀️ for the Python community

πŸ“š Documentation β€’ 🎯 Examples β€’ πŸ› Report Issues β€’ πŸ’¬ Discussions

About

A strict CLI + library API to report untyped variables, arguments, and function returns in Python code

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages