您可以忽略 mypy 对单行的检查,如此处的回答。有没有办法忽略 mypy 以获得完整功能?
我正在开发一个代码库,其中有很多由以前的开发人员编写的类型提示。在某些时候,我注意到这些提示没有进行类型检查,如果我想检查它们,我需要在构建中添加一个步骤。我对 python 很熟悉,但从未使用过类型提示,所以我读了很多关于它们的文章,但我仍然有很多东西需要理解。最终我得出结论,mypy 是用于对这些类型提示进行类型检查的主程序。所以我 pip 安装了 mypy 并运行mypy .
。我遇到了很多这样的错误;
error: Skipping analyzing 'setuptools': found module but no type hints or library stubs
error: Skipping analyzing 'numpy': found module but no type hints or library stubs
error: Skipping analyzing 'tensorflow.compat.v1': found module but no type hints or library stubs
error: Skipping analyzing 'tensorflow': found module but no type hints or library stubs
Run Code Online (Sandbox Code Playgroud)
我很惊讶这些默认情况下被视为错误,因为我读到的有关类型提示的所有内容都强调它们是可选的。所以我的第一个问题是,为什么 mypy 将上述内容视为显示停止错误而不是简单的警告?
然后我用谷歌搜索错误消息并找到mypy 文档的此页面。这可以说是非常清楚的,但令我困惑的是,它似乎表明这个错误是一个应该解决的大问题。它提供了多个选项来解决它,增加工作量,然后它们最终告诉您 CLI 标志将消除所有错误。当然,大多数项目都会导入不使用类型提示的库,并且需要使用此标志?
由于这些线索,我决定我应该继续尝试,寻找包裹。接下来让我困惑的是,它似乎无法找到我所有导入的类型提示。我不希望更多晦涩的库有书面类型提示,但肯定有人为 numpy 或 pytest 编写了它们?types- …
我遇到了一个可以通过交叉类型轻松解决的问题(目前正在讨论但尚未实施),并且想知道最干净的解决方法是什么。
我当前的设置大致对应于以下动物的 ABC 层次结构。有许多动物“特征”(CanFly
、CanSwim
等)被定义为抽象子类(尽管它们也可以被定义为 mixin)。
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def name(self) -> str: ...
class CanFly(Animal):
@abstractmethod
def fly(self) -> None: ...
class CanSwim(Animal):
@abstractmethod
def swim(self) -> None: ...
Run Code Online (Sandbox Code Playgroud)
以此我定义了特定的动物类别,包括抽象的和具体的:
class Bird(CanFly):
def fly(self) -> None:
print("flap wings")
class Penguin(Bird, CanSwim):
def name(self) -> str:
return "penguin"
def swim(self) -> None:
print("paddle flippers")
Run Code Online (Sandbox Code Playgroud)
我还定义了一个通用类来抚摸特定类型的动物:
from typing import Generic, TypeVar
T = TypeVar("T", bound=Animal, contravariant=True)
class Petter(Generic[T], ABC):
@abstractmethod …
Run Code Online (Sandbox Code Playgroud) 我如何具体的函数可以采用可以是整数或浮点数的列表?
我尝试使用Union这样的新类型:
num = Union[int, float]
def quick_sort(arr: List[num]) -> List[num]:
...
Run Code Online (Sandbox Code Playgroud)
但是,mypy并不喜欢这样:
quickSortLomutoFirst.py:32: error: Argument 1 to "quickSortOuter" has
incompatible type List[int]; expected List[Union[int, float]]
Run Code Online (Sandbox Code Playgroud)
是否有包含整数和浮点数的类型?
当我运行 mypy 时,它抱怨找不到模块:
sal@ahfang:~/workspace/ecs/cx-project-skeleton-repo/src/cx-example-function$ pipenv run python -m mypy .
example_lambda.py:3: error: Cannot find module named 'aws_xray_sdk.core'
Run Code Online (Sandbox Code Playgroud)
但是当尝试使用完全相同的 Python 解释器导入完全相同的模块时,似乎该模块确实存在并且是可导入的。
python
Python 3.7.3 (default, Apr 3 2019, 05:39:12)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import aws_xray_sdk.core
>>>
Run Code Online (Sandbox Code Playgroud)
除了强制忽略 mypy.ini 文件中的导入之外,我还应该做些什么来帮助 mypy 查看确实存在的可导入模块?
我正在尝试为项目设置 mypy 类型检查。我想从一开始就排除一堆文件/目录,这样我们至少可以强制对新代码进行类型检查,然后我们可以随着时间的推移烧掉排除列表。不幸的是 mypy 忽略了我的排除配置,我不明白为什么。
我创建了一个mypy.ini
包含以下内容的配置文件:
[mypy]
python_version = 3.8
exclude = /examples/
Run Code Online (Sandbox Code Playgroud)
但是当我运行时mypy --verbose .
,它仍然发现该目录中的文件存在错误。日志消息告诉我它看到了我的排除配置,但显然忽略了它:
LOG: Mypy Version: 0.812
LOG: Config File: mypy.ini
LOG: Configured Executable: /Library/Developer/CommandLineTools/usr/bin/python
3
LOG: Current Executable: /Library/Developer/CommandLineTools/usr/bin/python
3
LOG: Cache Dir: .mypy_cache
LOG: Compiled: True
LOG: Exclude: /examples/
<snipped>
LOG: Found source: BuildSource(path='./examples/fib.py', module='fib', has_text=False, base_dir='/Users/user/a/examples')
LOG: Found source: BuildSource(path='./examples/fib_iter.py', module='fib_iter', has_text=False, base_dir='/Users/user/a/examples')
<snipped>
examples/fib.py: error: Duplicate module named 'fib' (also at './examples/a/fib.py')
examples/fib.py: note: Are you missing an __init__.py? …
Run Code Online (Sandbox Code Playgroud) 我希望仅对某些特定模块使用这些选项disable_error_code = ["name-defined"]
,ignore_missing_imports = true
但我正在努力使其工作。以下是我的非工作pyproject.toml
文件的摘录:
[tool.mypy]
python_version = "3.9"
disallow_untyped_defs = true
show_error_codes = true
no_implicit_optional = true
warn_return_any = true
warn_unused_ignores = true
exclude = ["scripts", "docs", "test"]
[[tool.mypy.overrides]]
module = [
"firstmodule",
"secondmodule",
"utils",
"config",
]
disable_error_code = ["name-defined"]
ignore_missing_imports = true
Run Code Online (Sandbox Code Playgroud)
更具体地说,如果我disable_error_code = ["name-defined"]
按照上面的指示进行操作,那么我会收到以下错误:
pyproject.toml:[module =“utils”]:每个模块部分应该只指定每个模块标志(disable_error_code)
如果我ignore_missing_imports = true
按照上面的指示保留,那么它会被忽略,并且会发出由于缺少导入而导致的错误。
相反,如果我将上述两个选项移至[tool.mypy]
一切正常下方。
我知道用于类型检查和静态分析的内置 Python 库的存根文件随附mypy
或 PyCharm 安装。我怎样才能获得存根文件matplotlib
,numpy
,scipy
,pandas
,等?
在阅读了Eli Bendersky 关于通过Python协同程序实现状态机的文章后,我想......
我成功完成了第一部分(但是没有使用async def
s或yield from
s,我基本上只是移植了代码 - 所以任何改进都是最受欢迎的).
但是我需要一些关于协同程序类型注释的帮助:
#!/usr/bin/env python3
from typing import Callable, Generator
def unwrap_protocol(header: int=0x61,
footer: int=0x62,
dle: int=0xAB,
after_dle_func: Callable[[int], int]=lambda x: x,
target: Generator=None) -> Generator:
""" Simplified protocol unwrapping co-routine."""
#
# Outer loop looking for a frame header
#
while True:
byte = (yield)
frame = [] # type: List[int]
if byte == header:
#
# Capture the full frame
# …
Run Code Online (Sandbox Code Playgroud) 我正在 Python 3.8+ Django/Rest-Framework 环境中工作,在新代码中强制执行类型,但建立在许多无类型的遗留代码和数据之上。我们广泛使用 TypedDicts 来确保我们生成的数据以正确的数据类型传递到 TypeScript 前端。
MyPy/PyCharm/等。在检查我们的新代码是否输出符合要求的数据方面做得很好,但我们想测试我们的许多 RestSerializers/ModelSerializers 的输出是否符合 TypeDict。如果我有一个序列化器并输入如下字典:
class PersonSerializer(ModelSerializer):
class Meta:
model = Person
fields = ['first', 'last']
class PersonData(TypedDict):
first: str
last: str
email: str
Run Code Online (Sandbox Code Playgroud)
然后运行如下代码:
person_dict: PersonData = PersonSerializer(Person.objects.first()).data
Run Code Online (Sandbox Code Playgroud)
静态类型检查器无法发现person_dict
缺少所需email
密钥,因为(根据 PEP-589 的设计)它只是一个普通的dict
. 但我可以写这样的东西:
annotations = PersonData.__annotations__
for k in annotations:
assert k in person_dict # or something more complex.
assert isinstance(person_dict[k], annotations[k])
Run Code Online (Sandbox Code Playgroud)
它会发现email
序列化器的数据丢失了。在这种情况下,这很好,我没有引入任何更改from __future__ import annotations
(不确定这是否会破坏它),并且我的所有类型注释都是裸类型。但如果PersonData
定义如下:
class PersonData(TypedDict):
email: Optional[str] …
Run Code Online (Sandbox Code Playgroud) mypy ×10
python ×8
type-hinting ×2
abc ×1
coroutine ×1
generator ×1
python-3.x ×1
stub ×1
typechecking ×1
typeddict ×1
types ×1