-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Context
I'm trying to increase the strictness of types in pyJWT but have failed to find a way to express the optional dependency on cryptography. Below is a description of the bug and a minimized reproduction produced with the help of an LLM.
Describe the bug
In a typed package with an optional dependency, a public API parameter annotated with a package-local alias is reported as partially unknown:
Parameter type is "Unknown | str | bytes"
In this repro, the public function is annotated as AllowedPublicKeys | str | bytes, where AllowedPublicKeys is imported from another module in the same package.
Repro
pkg/algorithms.py
from __future__ import annotations
from typing_extensions import Never
AllowedPublicKeys = Never
try:
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
AllowedPublicKeys = RSAPublicKey
except ImportError:
AllowedPublicKeys = Neverpkg/api.py
from __future__ import annotations
from .algorithms import AllowedPublicKeys
def decode(key: AllowedPublicKeys | str | bytes) -> None:
return Nonepkg/__init__.py
from .api import decode as decodepkg/py.typed (empty file)
pyproject.toml
[build-system]
requires = ["setuptools>=69"]
build-backend = "setuptools.build_meta"
[project]
name = "pkg"
version = "0.0.1"
requires-python = ">=3.9"
[tool.setuptools]
packages = ["pkg"]
[tool.setuptools.package-data]
pkg = ["py.typed"]Commands
python3 -m venv .venv
. .venv/bin/activate
python -m ensurepip --upgrade
python -m pip install -U pip
python -m pip install pyright .
pyright --version
pyright --verifytypes pkg --ignoreexternalActual output
On pyright 1.1.408:
pkg.decode
.../pkg/api.py:1:28 - error: Type of parameter "key" is partially unknown
Parameter type is "Unknown | str | bytes"
pkg.algorithms.AllowedPublicKeys is also reported as unknown/ambiguous.
Question / requested guidance
Could you clarify the recommended way to express this optional-dependency
pattern so --verifytypes --ignoreexternal can validate the public API
cleanly?
If this conditional alias approach is not the intended pattern, guidance on
the preferred alternative for typed libraries with optional dependencies would
be very helpful.
Environment
- pyright:
1.1.408 - Python:
3.12.12 - Platform: macOS (Darwin)