Type Checking Best Practices¶
Overview¶
This project uses mypy for static type checking to catch bugs early and improve code quality.
Running Type Checks¶
# Check all source code
mypy src/
# Check specific module
mypy src/portfolio_management/portfolio/
# Check with verbose output
mypy src/ --show-error-codes --pretty
Type Aliases¶
Use type aliases from portfolio_management.core.types:
from portfolio_management.core.types import WeightDict, ReturnFrame
def construct_portfolio(returns: ReturnFrame) -> WeightDict:
# Type-safe function
pass
Common Patterns¶
DataFrame with specific columns¶
def process_prices(df: PriceFrame) -> ReturnFrame:
"""Process price data to returns.
Args:
df: Price DataFrame with Date, Symbol, Close columns
Returns:
Return DataFrame with Date index and asset columns
"""
pass
Series with specific dtype¶
from portfolio_management.core.types import ReturnSeries
def calculate_metric(returns: ReturnSeries) -> float:
"""Calculate metric from returns series."""
pass
Pandas-stubs limitations¶
Some pandas operations have strict type stubs that may not match all use cases:
# If legitimate pandas-stubs limitation, use type ignore with comment
df = pd.read_csv(path, **kwargs) # type: ignore[call-overload] # Complex kwargs
# Better: Specify parameters explicitly
df = pd.read_csv(path, parse_dates=["Date"], index_col=0) # No type ignore needed
Configuration¶
Type checking is configured in mypy.ini:
- Source code: Strict typing
- Tests: Relaxed (don't need full type annotations)
- Scripts: Relaxed (will be refactored to use services)
CI/CD¶
Type checking runs automatically on:
- Every commit (via pre-commit hook)
- Every pull request (via GitHub Actions)
Troubleshooting¶
False positives¶
If mypy reports an error but code is correct:
- Check if pandas-stubs is up to date
- Consider if type can be more specific
- Use
type: ignorewith detailed comment as last resort
Missing type stubs¶
If mypy complains about missing stubs:
Or add to mypy.ini: