You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This means that a == b doesn't imply hash(a) == hash(b), breaking how dicts and sets work.
It might also be worth noting that __eq__ looks at __pydantic_private__ and __pydantic_extra__ while __hash__ doesn't. This isn't a contract violation in the same way, since non-equal instances are allowed to have equal hashes, but it makes hash collisions more likely. Hypothetically you could have a large set/dict of model instances where all the public fields are the same (so all the hashes are equal) but the private attributes differ (so the instances are non-equal) and then operations which are usually O(1)ish become O(n). On the other hand, adding more logic to __hash__ would of course reduce performance slightly in the vast majority of cases, so it's not obvious what to do.
EDIT: there's a good reason not to hash private attributes: #7800 (comment)
Initial Checks
Description
This special handling for generic classes:
pydantic/pydantic/main.py
Lines 855 to 864 in dbbd776
has no equivalent for
__hash__
:pydantic/pydantic/_internal/_model_construction.py
Line 401 in dbbd776
This means that
a == b
doesn't implyhash(a) == hash(b)
, breaking how dicts and sets work.It might also be worth noting that__eq__
looks at__pydantic_private__
and__pydantic_extra__
while__hash__
doesn't. This isn't a contract violation in the same way, since non-equal instances are allowed to have equal hashes, but it makes hash collisions more likely. Hypothetically you could have a large set/dict of model instances where all the public fields are the same (so all the hashes are equal) but the private attributes differ (so the instances are non-equal) and then operations which are usually O(1)ish become O(n). On the other hand, adding more logic to__hash__
would of course reduce performance slightly in the vast majority of cases, so it's not obvious what to do.EDIT: there's a good reason not to hash private attributes: #7800 (comment)
Example Code
Python, Pydantic & OS Version
The text was updated successfully, but these errors were encountered: