通过
typeguard
运行代码时遇到类型检查错误。
我的包中有以下文件:
from __future__ import annotations
import pandas as pd
def col_sum(x: pd.Series[float]) -> pd.Series[float]:
return x*(x.sum()-1)
最初,我使用
pd.Series
作为这些类型提示,但是当我通过 mypy
运行代码时,它要求我在泛型类型上显式下标一个类型,所以我将其更改为 pd.Series[float]
(这是有道理的)因为它更明确并且允许 mypy
确定 x.sum()
是一个浮点数)。
我还有一个测试脚本,可以对此函数执行一些单元测试。
但是,我的测试套件还包括运行
pytest --typeguard-packages={MyPackage}
,但由于此功能而失败。这是错误:
> def col_sum(x: pd.Series[float]) -> pd.Series[float]:
E TypeError: 'type' object is not subscriptable
根据我的理解,这是因为
mypy
正在从 pd.Series
包导入 pandas-stubs
,这是一个通用类型(因此需要下标)。但是 pytest
通过 install_import_hook()
中的 typeguard
函数传递我的代码,该函数从常规 pd.Series
包(无法下标)导入 pandas
作为类/类型。
为了清楚起见,我使用的是 hypermodern cookiecutter template 的精简版。我正在使用
nox
来管理我的测试套件,它运行以下会话:
* pre-commit -> Lint using pre-commit.
* safety -> Scan dependencies for insecure packages.
* mypy-3.10 -> Type-check using mypy.
* mypy-3.11 -> Type-check using mypy.
* tests-3.10 -> Run the test suite.
* tests-3.11 -> Run the test suite.
* coverage -> Produce the coverage report.
* typeguard -> Runtime type checking using Typeguard.
* xdoctest-3.10 -> Run examples with xdoctest.
* xdoctest-3.11 -> Run examples with xdoctest.
* docs-build -> Build the documentation.
除了
typeguard
之外,全部都通过了
相关软件包版本:
python = "3.10.11"
pandas = "2.1.4"
pandas-stubs = "2.1.4.231218"
typeguard = "4.1.5"
pytest = "7.4.3"
我对
pd.Series
也有类似的问题:mypy
给了我error: Missing type parameters for generic type "Series" [type-arg]
,但是当我在括号中添加类型参数时,pylint
会告诉我TypeError: 'type' object is not subscriptable
。我的结论是,像你一样,mypy 正在从 pd.Series
包中读取 pandas-stubs
的声明,而 pylint 正在从 pandas
中读取定义。
通过遵循 dsz 对相关问题的回答,错误消失了如何在类型提示中指定 pandas 系列元素的类型。通过添加:
from __future__ import annotations
在我的文件顶部,它更改了评估注释的时间(请参阅PEP 563),现在
pylint
似乎对pd.Series[Any]
语法感到满意。