Closed
Description
To Reproduce
- Create a new environment with
pydantic==2.9.2
installed. - Create a file
t.py
:
from typing import Any
from typing_extensions import Self
from pydantic import BaseModel, model_validator
from pydantic.functional_validators import ModelWrapValidatorHandler
class WrapModelValidator(BaseModel):
@model_validator(mode='wrap') # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
def no_classmethod(cls, value: Any, handler: ModelWrapValidatorHandler[Self]) -> Self: ...
- Run
mypy --cache-dir=/dev/null --python-version 3.10 --disable-error-code empty-body --warn-unused-ignores t.py
Mypy will randomly raise:
t.py:10: error: Unused "type: ignore" comment [unused-ignore]
And sometimes suceed.
Sorry I couldn't provide more details, the issue is really weird and it seems like mypy doesn't produce fully reproducible results in this case.
Your Environment
- Mypy version used: 1.13.0
- Mypy command-line flags:
--cache-dir=/dev/null --python-version 3.10 --disable-error-code empty-body --warn-unused-ignores
- Mypy configuration options from
mypy.ini
(and other config files): - Python version used:
3.12
Activity
brianschubert commentedon Nov 9, 2024
Thanks! I can reproduce this locally. This is certainly a weird one!
So far I've narrowed this down to some non-deterministic behavior of
is_subtype
(specifically during this invocation).What's quite interesting is that the nondeterministic behavior isn't just between mypy runs, but also between invocations of
is_subtype
with the same arguments during the same run (here's a video demo in my debugger).sterliakov commentedon Apr 22, 2025
Okay, this is really indeterminate.
mypy.solve.solve_one
is order-sensitive and iterates over sets. The following patch (not a fix, but only a proof) makesmypy
output on this snippet completely reproducible.The problematic case is solving the following set of constraints:
for
Self`1667
whereSelf`0
hasdefault=Any, upper_bound=p.WrapModelValidator
. If the iteration starts withSelf`0
, we solve 1677 toAny
, otherwise we conclude that deps can't be satisfied (None
).This problem stems from non-commutative join and meet implementation.
hauntsaninja commentedon Apr 22, 2025
Ah I ran into that in #16979 (comment) as well
Fix commutativity of join between TypeType and TypeVar
hauntsaninja commentedon May 26, 2025
Spent some time today looking at a few of these nondeterminism issues.
#19149 is a fix for this (it makes mypy consistently emit the error)
Fix nondeterministic type checking by making join between TypeType an…