pydantic: mypy: invalid type comment or annotation
Hi,
I think this issue related more to mypy, but maybe you know about any workaround or how to solve this.
Here is my code:
class Test(BaseModel):
k: constr(min_length=2)
And when I run mypy I got:
error: invalid type comment or annotation
note: Suggestion: use constr[...] instead of constr(...)
Any ideas?
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 61
- Comments: 40 (15 by maintainers)
Commits related to this issue
- Fix errors from CI - Linting - ISort - Workaround for https://github.com/samuelcolvin/pydantic/issues/156 — committed to trickeydan/monzo-webhook-schema by trickeydan 3 years ago
- Common: Ignore valid-type on con{int,float} mypy can't handle pydantic's conint and confloat. See https://github.com/pydantic/pydantic/issues/239 and https://github.com/pydantic/pydantic/issues/156 f... — committed to guardicore/monkey by mssalvatore 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
- (BSR)[API] fix: Fix usage of pydantic constrained fields to please mypy With the following pydantic model: class M(pydantic.BaseModel): name: pydantic.constr(max_length=200) ... mypy re... — committed to pass-culture/pass-culture-main by dbaty 2 years ago
Why is this issue closed? From my understanding the typing behavior with
mypyis still not fixed - or am I misunderstanding something?For me I found simple solution how to use
constrwithoutmypywarnings. Look at example below:Also using this approach you can share your validation types, for example, between engineers in your company.
The above is not quite right as well, because the first parameter to
Fieldis the default value. In this case the default would be the typestr, which is not astr.Another possible issue is that a default value was supplied, making this field optional.
Updated example:
If you want to make the field a Required field, use an ellipsis:
Something like
required=Truewould feel more natural, but that’s not an option as of v1.4. Please be aware that supplying a default ofNoneis not the same as supplying no default value.This should be mentioned in the documentation:
https://pydantic-docs.helpmanual.io/usage/types/#constrained-types
is incompatible with mypy at the moment
@Gr1N That did it, thanks!
The final line is simply
I believe the problem and the workaround should be explained in the docs.
sorry for the dumb question , shouldn’t the plugin handle this ?
@nandoflorestan @Gr1N that does not look correct, and in fact only works because you probably run
mypy --follow-imports=skip, if you runmypythis would be the outputthe best is explained by @samuelcolvin here: https://github.com/samuelcolvin/pydantic/issues/975#issuecomment-551147305
Another approach is to inherit from ConstrainedStr:
For future people who find this issue, in v1 you can use
Fieldfor this:EDIT: See comment below for an example https://github.com/samuelcolvin/pydantic/issues/156#issuecomment-614748288
Humans! Whoever thinks that Mypy does more evil than goodness by forcing developers to serve the code and not vice versa give it a thumbs up! May Mypy be eliminated from the entire history of the Universe…
Using Annotated for constraining decimals as
price: Annotated[Decimal, Field(gt=Decimal("0.00"), decimal_places=2)with fastapi on 0.75.2 , Python 3.9.* and pydantic on 1.9.0 -> works! Swagger shows correct doc and validation is happening on runtime. No bypass needed now. Thanks!This doesn’t work –
constrconstraints are not applied. max_length is neither in schema ofItemnor during runtime/parsing (eg.fieldcan be longer then 2).I’m using Python 3.9.* and pydantic 1.9.0.
Now that we have Annotated available, should this ticket be reopened? (I recognise it might not currently apply constraints correctly, but support could be implemented as part of this ticket)
This part of the Pydantic docs suggests the example should work “as is” and I would expect that to include type checking (I got this issue when trying it).
@nandoflorestan try this:
Sadly since pep 472 was never implemented and keyword arguments to
__getitem__are not permitted this is not possible.Even the works arounds suggested in pep472
foobar[{'min_length': 123}]orfoobar['min_length':123]are both syntax errors in mypy so they’re not an option.I’m closing this but happy to come back to it if anyone has a bright idea.
Even with
Annotated[]now supported, defining strict fields with validation inline (while keeping mypy happy) is still not possible:The workaround of:
…is not so great, as it’s so verbose.
…could be better (far from perfect, though) but it just doesn’t comply with
mypy.StrictStrnow inherits fromConstrainedStrwhich supports validators, and for that reasonfield: Constrained* = Field(...validators...)are not supported.However, what if
Strict*did not inherit fromConstrained*classes and were simply:In this case, you would need to define the validators via
Field()(but it could be supported as there wouldn’t be possibility for clashes):But I guess that would be too limited, as
Constrained*classes do more than duplicate JSON schema validators (likeconstr(strip_whitespace=True, curtail_length=10)) and you would lose those.I think now it should be better with
Annotatedthat ismypycompliant So with author examplebecomes
To anyone still running into this,
# type: ignorenow works. Its error code if you want to be pedantic (heh) isvalid-type. The specific usage would be# type: ignore["valid-type"].Quoting https://github.com/samuelcolvin/pydantic/issues/156#issuecomment-1073876877:
The following isn’t pretty, but I believe it works at runtime and typecheck-time:
Running the above in an interpreter yields
and mypy seems content:
Ah yes. Like PrettyWood said. Waiting on a PR 😄
Is there a reason why
Field(..., strict=True)is not supported? Wouldn’t that do it?I can attempt to work it, if that’s a viable solution.
Yes, it does work. But I just wanted to know if there was a more robust or appropriate way to do it. I am working on a rather large project and I didn’t want to use
# type: ignoreexcessively on several lines in different files.But exactly this one gives the mypy error.
That’s pretty verbose. Lots of “wasted” characters, surely there’s a more compact way?
Like, if you could
StrictStr(max_length=2)(but there’s no constructor, so you cannot directly do that). And, I guess it would fail with mypy the same way asconstr()et al. now do.Yeah, I’ve read those, but I think they miss this one. For example, there’s no similar example than what you just pasted (setting
max_lengthin sub-class).Field(..., max_length=2)is just useful for the schema. You should door create a custom class
For more info check out the doc Hope it helps