mypy 如何接受 pydantic 的 constr() 类型?

Rob*_*ert 19 python mypy pydantic

我有这个代码:

from pydantic import BaseModel, constr

DeptNumber = constr(min_length=6, max_length=6)

class MyStuff(BaseModel):
    dept: DeptNumber

ms = MyStuff(dept = "123456")
Run Code Online (Sandbox Code Playgroud)

deptnr.py:6:错误:变量“deptnr.DeptNumber”作为类型无效
deptnr.py:6:注意:请参阅https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs -类型别名

提供的链接似乎并没有真正解决我的问题(我没有使用Type)。

不管有没有这个都会发生这种情况mypy.ini

[mypy]
plugins = pydantic.mypy

[pydantic-mypy]
init_typed = true
Run Code Online (Sandbox Code Playgroud)

最初我在 Pydantic 中也遇到了choice如下错误,但我通过使用 Python 解决了这个问题Literal

DIR = choice(["North", "East", "South", "West"])
Run Code Online (Sandbox Code Playgroud)

我需要改变什么才能让 mypy 对 Pydantic 感到满意constr

Gin*_*pin 29

与 mypy 的不兼容性已在 Github 问题https://github.com/samuelcolvin/pydantic/issues/156中讨论。constr 遗憾的是,没有找到使用并让 mypy 满意的具体解决方案。

在 Pydantic v1 note 1constr上,您可以继承 pydantic 的子类,而不是 pydantic ConstrainedStr,它提供与 相同的配置和选项constr,但 mypy 不会抱怨类型别名。

from pydantic import BaseModel, ConstrainedStr

class DeptNumber(ConstrainedStr):
    min_length = 6
    max_length = 6

class MyStuff(BaseModel):
    dept: DeptNumber

ms = MyStuff(dept='123456')
Run Code Online (Sandbox Code Playgroud)

文档的严格类型Constrained*部分简要提到了这些类。它在pydantic/types.py中定义,如您所见,基本上与以下内容相同:constr

class ConstrainedStr(str):
    strip_whitespace = False
    to_lower = False
    min_length: OptionalInt = None
    max_length: OptionalInt = None
    curtail_length: OptionalInt = None
    regex: Optional[Pattern[str]] = None
    strict = False

    ...
Run Code Online (Sandbox Code Playgroud)

验证的工作原理相同:

class ConstrainedStr(str):
    strip_whitespace = False
    to_lower = False
    min_length: OptionalInt = None
    max_length: OptionalInt = None
    curtail_length: OptionalInt = None
    regex: Optional[Pattern[str]] = None
    strict = False

    ...
Run Code Online (Sandbox Code Playgroud)

注 1:
我还没有机会使用 Pydantic v2,所以我不知道它是否仍然适用于该版本。
我只能保证答案在 v1 上有效。

  • @Monkeyphant 这很不幸。我不使用 Pylance,并且 mypy != pylance,最初的问题是针对 mypy 的,没有提及 pylance。您可能想向 pylance 问一个单独的问题。 (2认同)
  • 这是我为这个问题找到的最好的解决方法,它非常干净:https://github.com/koxudaxi/datamodel-code-generator/issues/492#issue-965007077 (2认同)

小智 7

您可以尝试使用Fieldfrom Pydantic

from pydantic import BaseModel, Field

class MyStuff(BaseModel):
    dept: str = Field(..., min_length=6, max_length=6)
Run Code Online (Sandbox Code Playgroud)

这似乎对我有用。

  • 这不适用于“strip_whitespace=True”。 (6认同)

Nic*_*art 6

在 Pydantic V2 中,您可以将StringConstraints类型与 一起使用Annotated

from pydantic import stringConstraints
from typing import Annotated

DeptNumber = Annotated[
    str,
    StringConstraints(
        min_length=6,
        max_length=6,
    )
] 
Run Code Online (Sandbox Code Playgroud)

Annotated确保它DeptNumber是一种str类型,同时在其之上添加一些功能。