diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b09551a..948f0e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,7 +53,7 @@ jobs: run: uv run pytest --verbose --tb=short lint: - name: Code Quality + name: Code Quality & Type Checking runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -87,6 +87,22 @@ jobs: - name: Run Python linting run: uv run ruff check . + + - name: Test type stub files exist + run: | + test -f python/cel/cel.pyi || (echo "❌ Type stub file missing" && exit 1) + test -f python/cel/py.typed || (echo "❌ PEP 561 marker missing" && exit 1) + echo "✅ Type stub files present" + + - name: Run type checking tests + run: uv run pytest tests/test_type_stubs.py -v + + - name: Test ty type checker integration + run: | + echo "from cel import evaluate, Context; evaluate('1+1')" > test_types.py + uvx ty check test_types.py + rm test_types.py + echo "✅ Type checker integration working" linux: runs-on: ${{ matrix.platform.runner }} needs: [test, lint] diff --git a/CHANGELOG.md b/CHANGELOG.md index 77d13f4..cd16b53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### ✨ Added + +- **Type checking support**: Added complete type stub files (`.pyi`) for PyO3 extension + + ## [0.5.0] - 2025-08-08 diff --git a/docs/contributing.md b/docs/contributing.md index eb022fb..30e0b81 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -246,6 +246,18 @@ def add_function(self, name: str, func: Callable) -> None: """ ``` +### Type Checking Support + +This package includes manual type stub files (`.pyi`) for the PyO3 Rust extension to support static type checking. + +**Type checker verification:** +```bash +uvx ty check your_file.py # ✅ Should pass without "no member" errors +uvx mypy your_file.py # ✅ Works with proper MYPYPATH setup +``` + +See https://pyo3.rs/main/type-stub to opt-in to the automated types when implemented in Maturin. + ## Debugging & Troubleshooting ### Common Issues diff --git a/python/cel/cel.pyi b/python/cel/cel.pyi new file mode 100644 index 0000000..789bb45 --- /dev/null +++ b/python/cel/cel.pyi @@ -0,0 +1,44 @@ +""" +Type stubs for the CEL Rust extension module. +""" + +from typing import Any, Callable, Dict, Optional, Union, overload + +class Context: + """CEL evaluation context for variables and functions.""" + + @overload + def __init__(self) -> None: ... + @overload + def __init__(self, variables: Dict[str, Any]) -> None: ... + @overload + def __init__( + self, + variables: Optional[Dict[str, Any]] = None, + *, + functions: Optional[Dict[str, Callable[..., Any]]] = None, + ) -> None: ... + def add_variable(self, name: str, value: Any) -> None: + """Add a variable to the context.""" + ... + + def add_function(self, name: str, func: Callable[..., Any]) -> None: + """Add a function to the context.""" + ... + + def update(self, variables: Dict[str, Any]) -> None: + """Update context with variables from a dictionary.""" + ... + +def evaluate(expression: str, context: Optional[Union[Dict[str, Any], Context]] = None) -> Any: + """ + Evaluate a CEL expression. + + Args: + expression: The CEL expression to evaluate + context: Optional context with variables and functions + + Returns: + The result of evaluating the expression + """ + ... diff --git a/python/cel/py.typed b/python/cel/py.typed new file mode 100644 index 0000000..e69de29