I have this code:
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
The provided link doesn't seem to really address my problem (I'm not using Type).
This happens with or without this mypy.ini:
[mypy]
plugins = pydantic.mypy
[pydantic-mypy]
init_typed = true
Initially I also had that error in a Pydantic choice as below, but I got around that by using Python's Literal instead.
DIR = choice(["North", "East", "South", "West"])
What do I need to change to make mypy happy with my Pydantic constr?
This incompatibility with mypy has been discussed in this Github issue https://github.com/samuelcolvin/pydantic/issues/156. Sadly, no concrete solution that uses constr and keeps mypy happy was found.
On Pydantic v1 note 1, instead of constr, you can subclass pydantic's ConstrainedStr, which offers the same configurations and options as constr, but without mypy complaining about type aliases.
from pydantic import BaseModel, ConstrainedStr
class DeptNumber(ConstrainedStr):
min_length = 6
max_length = 6
class MyStuff(BaseModel):
dept: DeptNumber
ms = MyStuff(dept='123456')
The Constrained* classes are briefly mentioned in the Strict Types section of the docs. It is defined in pydantic/types.py and as you can see is basically the same as 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
...
Validation works the same:
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)
note 1:
I haven't gotten a chance to work with Pydantic v2 yet, so I don't know if it still works on that version.
I can only guarantee that the answer works on v1.
In Pydantic V2, you can use the StringConstraints type along with Annotated:
from pydantic import stringConstraints
from typing import Annotated
DeptNumber = Annotated[
str,
StringConstraints(
min_length=6,
max_length=6,
)
]
Annotated makes sure that DeptNumber is a str type, while adding some functionality on top of it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With