diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 46ad906..87de2eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -100,6 +100,18 @@ jobs: uvx ty check test_types.py rm test_types.py echo "✅ Type checker integration working" + + - name: Smoke test the wheel in an empty environment + # The dev environment carries packages the wheel does not declare (mypy pulls + # in typing_extensions, for example), so an undeclared runtime import only + # shows up in an install that has nothing but the wheel and its dependencies. + run: | + uv run maturin build --release --out smoke-dist + uv venv --no-project --python "$(uv run python -c 'import sys; print(sys.executable)')" smoke-venv + uv pip install --python smoke-venv/bin/python smoke-dist/*.whl + smoke-venv/bin/python -c "import cel; assert cel.evaluate('1 + 1') == 2" + smoke-venv/bin/cel '1 + 2' + smoke-venv/bin/cel --version linux: runs-on: ${{ matrix.platform.runner }} needs: [test, lint] diff --git a/CHANGELOG.md b/CHANGELOG.md index b2f1696..8f83829 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- **`import cel` failed in a clean install.** `cel.cli` imported `Annotated` from + `typing_extensions`, which is not one of this package's declared dependencies. It + used to arrive transitively through Typer, but Typer 0.21.2 (February 2026) dropped + that dependency, so `pip install common-expression-language` into an environment + with nothing else in it left `import cel` raising `ModuleNotFoundError`. The + development lockfile masked this because mypy still pulls `typing_extensions` in. + `Annotated` now comes from the standard library (`typing`), which has provided it + since Python 3.9. CI now installs the built wheel into an empty virtual environment + and imports the package and runs the `cel` command, so an undeclared runtime + dependency fails the build. - The type stubs (`cel.pyi`) now use the parameter names the runtime actually accepts: `evaluate(src, evaluation_context)` rather than `(expression, context)`, and `Context.add_function(name, function)` rather than `func`. A keyword call diff --git a/python/cel/cli.py b/python/cel/cli.py index 22ea1e1..216cc38 100644 --- a/python/cel/cli.py +++ b/python/cel/cli.py @@ -16,7 +16,7 @@ import time from importlib.metadata import PackageNotFoundError, version from pathlib import Path -from typing import Any, Dict, Optional, Tuple +from typing import Annotated, Any, Dict, Optional, Tuple import typer @@ -35,7 +35,6 @@ from rich.panel import Panel from rich.syntax import Syntax from rich.table import Table -from typing_extensions import Annotated # Import directly from relative modules to avoid circular imports from .cel import Context, evaluate