PyJWT 2.12.0 在 Python 3.10 导入时报缺少 typing_extensions
PyJWT 2.12.0 漏掉 Python 3.11 以下的类型依赖,未安装 cryptography 时可能连 import jwt 都失败。2.12.1 已修正依赖声明;临时补包也要进入锁文件。
安装 PyJWT 2.12.0 后,Python 3.10 程序可能在 import jwt 时就报:
ModuleNotFoundError: No module named 'typing_extensions'
完整堆栈里还可能先出现 No module named 'cryptography',随后才在 jwt/algorithms.py 导入 Never 时终止。后一个异常才是这条路径无法完成导入的直接原因。它发生在处理令牌之前,修改签名密钥、关闭签名校验都不能解决。
为什么没使用 RSA,也会走到这里
PyJWT 的 cryptography 是可选依赖。2.12.0 在无法导入它时,会给相关类型设置占位类型;Python 3.11 可以从标准库 typing 取得 Never,Python 3.9、3.10 则需要 typing_extensions。
2.12.0 的安装依赖漏了这个条件。只装基础 PyJWT、环境里又没有碰巧被别的包带入 typing_extensions 时,导入便会失败。这不表示所有 PyJWT 用户都缺少加密后端,也不表示必须为了 HS256 安装整套 cryptography。
先在发生故障的环境中检查安装元数据。这一步不需要成功导入 jwt:
import sys
from importlib.metadata import version, requires
print(sys.executable)
print(sys.version)
print(version("PyJWT"))
print(requires("PyJWT"))
如果实际版本不是 2.12.0,或堆栈没有落到这条导入链,继续按实际缺失模块排查。编辑器和 CI 使用不同解释器时,单在另一个终端补包不会改变失败的运行环境。
补齐依赖,并让重建环境也能恢复
PyJWT 2.12.1 已补上 typing_extensions >= 4.0; python_version < '3.11'。当前正式 2.15.1 也保留了这个声明。优先在项目依赖约束内采用已包含修正的版本,更新锁文件,再从锁文件重建环境;不要只改开发机上的一份 site-packages。
暂时必须留在 2.12.0 时,可以在项目管理的同一虚拟环境补齐依赖:
python -m pip install "typing_extensions>=4.0"
这条命令会改变环境。项目由 uv、Poetry 或其他锁文件工具管理时,应把同样的依赖要求纳入它的正常声明与锁定流程,避免下一次部署再次丢失。不要通过复制 typing_extensions.py、改库里的 Never 导入或忽略异常来绕过安装问题。
若业务实际使用 RS256、ES256 等需要加密后端的算法,还要按项目约束安装 PyJWT 的 crypto 扩展依赖。补齐类型依赖只能恢复这条导入链,不能为缺少后端的算法提供实现。
从原来失败的应用或 CI 入口复查 import jwt,再使用已有测试令牌执行正常的编码、验签与过期检查;验签算法和密钥配置保持原有约束。最后用干净环境重建一次,确认修复来自依赖声明,而不是机器上残留的包。


