A strict CLI + library API to report untyped variables, arguments, and function returns in Python code
Project description
๐ Typecoverage - Python Type Annotation Analyzer
A strict CLI + library API to report untyped variables, arguments, and function returns in Python code
๐ฏ 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: ignoreand# noqasupport - ๐ 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:
- Fork the repository and clone your fork
- Install development dependencies:
pip install -r requirements.txt - Run tests:
pytest tests/ -v - Check code style:
ruff check . && black . --check - Make your changes and add tests
- Run the full test suite:
pytest tests/ --cov=typecoverage - 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
astmodule 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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file typecoverage-1.0.1.tar.gz.
File metadata
- Download URL: typecoverage-1.0.1.tar.gz
- Upload date:
- Size: 47.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5aaaf7157f4b3c34d149bf42cf53ae7623bcc133ab55af98b643188a91ed1d6a
|
|
| MD5 |
8d2795a0fcb85438d609b796a4cabbe4
|
|
| BLAKE2b-256 |
ab7435e69504a7f4d861e7cec0cc8d27949b32a4e9642a38b3f59bc5b05974ca
|
Provenance
The following attestation bundles were made for typecoverage-1.0.1.tar.gz:
Publisher:
python-publish.yml on kairos-xx/typecoverage
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
typecoverage-1.0.1.tar.gz -
Subject digest:
5aaaf7157f4b3c34d149bf42cf53ae7623bcc133ab55af98b643188a91ed1d6a - Sigstore transparency entry: 405442393
- Sigstore integration time:
-
Permalink:
kairos-xx/typecoverage@839438f046b527a46ed146ae46eed50f7266d4b2 -
Branch / Tag:
refs/tags/end - Owner: https://github.com/kairos-xx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@839438f046b527a46ed146ae46eed50f7266d4b2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file typecoverage-1.0.1-py3-none-any.whl.
File metadata
- Download URL: typecoverage-1.0.1-py3-none-any.whl
- Upload date:
- Size: 26.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d87df4d681c694b6fcd73987a3d3857c3bc876fdc7eff1610c84b370b6c91d3
|
|
| MD5 |
a082cb586002e61b56338a33d42265aa
|
|
| BLAKE2b-256 |
8cbf51d924d317b8d568d440808c0b78efa4d6cd2caf9ea63c85d3f39c204870
|
Provenance
The following attestation bundles were made for typecoverage-1.0.1-py3-none-any.whl:
Publisher:
python-publish.yml on kairos-xx/typecoverage
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
typecoverage-1.0.1-py3-none-any.whl -
Subject digest:
1d87df4d681c694b6fcd73987a3d3857c3bc876fdc7eff1610c84b370b6c91d3 - Sigstore transparency entry: 405442407
- Sigstore integration time:
-
Permalink:
kairos-xx/typecoverage@839438f046b527a46ed146ae46eed50f7266d4b2 -
Branch / Tag:
refs/tags/end - Owner: https://github.com/kairos-xx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@839438f046b527a46ed146ae46eed50f7266d4b2 -
Trigger Event:
release
-
Statement type: