Deep analysis of type annotation coverage and quality across Python codebases. Finds untyped functions, incorrect annotations, missing generics, improper Protocol usage, and patterns that break type checker inference.
Use when: auditing type safety, preparing to enable strict mypy, reviewing annotation quality, or migrating from untyped to typed Python.
cat pyproject.toml 2>/dev/null | head -30
python3 --version 2>/dev/null
# Mypy config
cat pyproject.toml 2>/dev/null | grep -A30 '\[tool.mypy\]'
cat mypy.ini 2>/dev/null || cat setup.cfg 2>/dev/null | grep -A20 '\[mypy\]'
# py.typed marker (PEP 561)
find . -name "py.typed" -not -path '*/venv/*' 2>/dev/null
find . -name "*.pyi" -not -path '*/venv/*' 2>/dev/null | head -10
find . -name "*.py" -not -path '*/venv/*' -not -path '*/__pycache__/*' | wc -l
Determine: Python version, type checker config and strictness, whether package ships types (py.typed), project size.
# Functions without return type annotation
grep -rn 'def [a-zA-Z_]\+(' --include="*.py" . 2>/dev/null \
| grep -v 'venv/\|__pycache__\|_test\.py\|test_' | grep -v '\-> ' | head -30
# Completely untyped files
for f in $(find . -name "*.py" -not -path '*/venv/*' -not -path '*/__pycache__/*' \
-not -name '*_test.py' 2>/dev/null); do
if ! grep -q ':\s*[A-Z]\|-> \|: str\|: int\|: float\|: bool\|: list\|: dict' "$f" 2>/dev/null; then
echo "UNTYPED: $f"
fi
done | head -15
# Coverage estimate
total=$(grep -rc 'def ' --include="*.py" . 2>/dev/null | grep -v 'venv/' | awk -F: '{s+=$2} END {print s}')
typed=$(grep -rc '\-> ' --include="*.py" . 2>/dev/null | grep -v 'venv/' | awk -F: '{s+=$2} END {print s}')
echo "Coverage: $typed / $total functions have return type annotations"
# Deprecated typing imports (use builtins in 3.9+)
grep -rn 'from typing import List\|from typing import Dict\|from typing import Tuple\|from typing import Set' \
--include="*.py" . 2>/dev/null | grep -v 'venv/' | head -15
# from __future__ import annotations (PEP 563)
grep -rn 'from __future__ import annotations' --include="*.py" . 2>/dev/null | grep -v 'venv/' | head -10
# TYPE_CHECKING guard
grep -rn 'TYPE_CHECKING' --include="*.py" . 2>/dev/null | grep -v 'venv/' | head -10
Flag:
typing.List/Dict/Tuple/Set deprecated since 3.9 — use list/dict/tuple/setif TYPE_CHECKING: to avoid runtime overhead and circular importsList[int] and list[int] in same codebase# Any usage (excluding imports)
grep -rn '\bAny\b' --include="*.py" . 2>/dev/null | grep -v 'venv/\|_test\.py\|from typing' | head -20
# type: ignore comments
grep -rn 'type:\s*ignore' --include="*.py" . 2>/dev/null | grep -v 'venv/' | head -15
# cast() usage
grep -rn 'cast(' --include="*.py" . 2>/dev/null | grep -v 'venv/' | head -10
# Optional without None check patterns
grep -rn 'Optional\[' --include="*.py" . 2>/dev/null | grep -v 'venv/' | head -10
Flag:
Any is a hole in type safety — each usage should be justifiedtype: ignore without error code: should specify like # type: ignore[assignment] for maintainabilitycast() overuse: runtime no-op that lies to the type checker — prefer isinstance narrowingOptional[X] but never checking for None7w4.net提供免费和付费技能下载。
# TypeVar definitions
grep -rn 'TypeVar(' --include="*.py" . 2>/dev/null | grep -v 'venv/' | head -10
# ParamSpec (decorator typing, 3.10+)
grep -rn 'ParamSpec' --include="*.py" . 2>/dev/null | grep -v 'venv/' | head -5
# Protocol definitions
grep -rn 'class.*Protocol' --include="*.py" . 2>/dev/null | grep -v 'venv/\|from typing' | head -10
# ABC vs Protocol
grep -rn '@abstractmethod\|class.*ABC' --include="*.py" . 2>/dev/null | grep -v 'venv/' | head -10
# Complex Callable types
grep -rn 'Callable\[' --include="*.py" . 2>/dev/null | grep -v 'venv/' | head -10
# dict[str, Any] (could be TypedDict)
grep -rn 'dict\[str,\s*Any\]\|Dict\[str,\s*Any\]' --include="*.py" . 2>/dev/null | grep -v 'venv/' | head -10
Flag:
T = TypeVar('T') accepts anything — add bound= if function needs specific capabilitiesParamSpec lose the decorated function's signatureCallable[[str, int, Optional[dict]], Awaitable[list[str]]] — use Protocol with __call__ insteaddict[str, Any] for structured data: use TypedDict for type-safe key access# Dataclass issues
grep -A20 '@dataclass' --include="*.py" . 2>/dev/null | grep '^\s\+[a-z_]\+ =' | grep -v ':' | head -10
# TypedDict
grep -rn 'TypedDict' --include="*.py" . 2>/dev/null | grep -v 'venv/\|from typing' | head -10
# Async functions without return type
grep -rn 'async def' --include="*.py" . 2>/dev/null | grep -v 'venv/\|_test\.py' | grep -v '\->' | head -10
Flag:
field: list = [] shared across instances — use field(default_factory=list)Coroutine[Any, Any, Any]grep -i 'strict\|disallow_untyped_defs\|disallow_any_generics\|warn_return_any\|check_untyped_defs' \
pyproject.toml mypy.ini setup.cfg 2>/dev/null | head -15
Recommended strictness progression:
check_untyped_defs = true — type-check bodies even without annotationsno_implicit_optional = true — require explicit Optional[X] for = Nonewarn_return_any = true — flag functions returning Any via untyped callsdisallow_untyped_defs = true — require annotations on all functionsdisallow_any_generics = true — require type params (list[int] not list)strict = true — all strict flags (goal state)# Python Typing Analysis — [Project Name]
## Summary
- Files: N | Python: 3.XX | Type checker: mypy/pyright/none
- Functions with return types: N/M (XX%) | Any usages: N | type:ignore: N
## Coverage by Package
| Package | Functions | Typed | Coverage |
|---------|-----------|-------|----------|
| src/core/ | 30 | 12 | 40% |
| src/api/ | 45 | 40 | 89% |
## Critical Findings
### [C1] Function Returns Any, Callers Assume str
- **File**: src/utils/parser.py:34 — Fix: `def parse(data: bytes) -> ParseResult:`
### [C2] Optional Without None Check
- **File**: src/api/handlers.py:56 — Fix: add None guard before access
## Recommendations
1. Enable `check_untyped_defs = true` in mypy config
2. Add return types to N functions in highest-priority packages
3. Replace N deprecated `typing.List/Dict` imports with builtins
4. Add error codes to N `type: ignore` comments
5. Replace N `dict[str, Any]` with TypedDict, add `ParamSpec` to N decorators
6. Add `py.typed` marker if package is distributed as library
mypy --strict --show-error-codes . to see all strict violationsreveal_type(expr) to debug inference, typing.assert_type() (3.11+) for testspyright --verifytypes <package> to check exported API completenessstubgen for .pyi stubs, monkeytype for runtime-traced annotationsdatamodel-code-generator to generate TypedDict from JSON这个 Skill 质量中等偏上,结构清晰、分析维度全面,能够有效识别类型注解的覆盖率问题和常见反模式。优势是提供了可直接使用的命令行脚本和格式化报告模板,适合开发团队进行类型安全审计。不足之处是分析方法相对简单(主要基于 grep),对复杂代码结构的检测能力有限,且未涵盖其他主流类型检查工具的对比。建议作为初始审计工具使用,但不要完全依赖其结果。