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

How can mypy accept pydantic's constr() types?

我有这个代码:

from pydantic import BaseModel, constr

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

class MyStuff(BaseModel):
    dept: DeptNumber

ms = MyStuff(dept = "123456")

deptnr.py:6: error: Variable "deptnr.DeptNumber" is not valid as a type
deptnr.py:6: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases

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

不管有没有这个 mypy.ini:

[mypy]
plugins = pydantic.mypy

[pydantic-mypy]
init_typed = true

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

DIR = choice(["North", "East", "South", "West"])

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

您可以尝试使用 Pydantic 中的 Field :

from pydantic import BaseModel, Field

class MyStuff(BaseModel):
    dept: str = Field(..., min_length=6, max_length=6)

它似乎对我有用。

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

您可以子类化 pydantic 的 ConstrainedStr,而不是 constr,它提供与 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')

Constrained* 类 在 Strict Types section of the docs. It is defined in 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

    ...

验证工作相同:

Traceback (most recent call last):
  File "test-2.py", line 13, in <module>
    ms = MyStuff(dept='123456789')
  File "pydantic/main.py", line 406, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for MyStuff
dept
  ensure this value has at most 6 characters (type=value_error.any_str.max_length; limit_value=6)