From f7232ebd66fc86c52c5e230c668ee4ae07675497 Mon Sep 17 00:00:00 2001 From: Brian Thorne Date: Sat, 9 Aug 2025 22:23:20 +1200 Subject: [PATCH 1/3] Add type stubs for CEL Rust extension module --- python/cel/cel.pyi | 47 +++++++++++++++++++++++++++++++++++++++++++++ python/cel/py.typed | 0 2 files changed, 47 insertions(+) create mode 100644 python/cel/cel.pyi create mode 100644 python/cel/py.typed diff --git a/python/cel/cel.pyi b/python/cel/cel.pyi new file mode 100644 index 0000000..db988eb --- /dev/null +++ b/python/cel/cel.pyi @@ -0,0 +1,47 @@ +""" +Type stubs for the CEL Rust extension module. +""" + +from typing import Any, Dict, Union, Optional, Callable, 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 + """ + ... \ No newline at end of file diff --git a/python/cel/py.typed b/python/cel/py.typed new file mode 100644 index 0000000..e69de29 From 421d96e10be887b7429d5ad6e3910aa593eb0ee2 Mon Sep 17 00:00:00 2001 From: Brian Thorne Date: Sat, 9 Aug 2025 22:27:45 +1200 Subject: [PATCH 2/3] Add type checking check in CI --- .github/workflows/ci.yml | 18 +++++++++++++++++- CHANGELOG.md | 5 +++++ docs/contributing.md | 12 ++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) 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 From a7359e18881eaae9cd28fa689b44def08fec9c64 Mon Sep 17 00:00:00 2001 From: Brian Thorne Date: Sun, 10 Aug 2025 06:27:03 +1200 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=A7=B9=20fmt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/cel/cel.pyi | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/python/cel/cel.pyi b/python/cel/cel.pyi index db988eb..789bb45 100644 --- a/python/cel/cel.pyi +++ b/python/cel/cel.pyi @@ -2,33 +2,30 @@ Type stubs for the CEL Rust extension module. """ -from typing import Any, Dict, Union, Optional, Callable, overload +from typing import Any, Callable, Dict, Optional, Union, overload class Context: """CEL evaluation context for variables and functions.""" - + @overload def __init__(self) -> None: ... - - @overload + @overload def __init__(self, variables: Dict[str, Any]) -> None: ... - @overload def __init__( - self, + self, variables: Optional[Dict[str, Any]] = None, *, - functions: Optional[Dict[str, Callable[..., 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.""" ... @@ -36,12 +33,12 @@ class Context: 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 """ - ... \ No newline at end of file + ...