-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
__hash__() is squashed on subclass #2422
Comments
Hello @khaeru and thanks for reporting with a code snippet 🙏 I made a quick fix. Feedback welcome :) |
Thanks for the quick response! I checked out the branch but was unable to compile and install it; but the added test case matches what I reported, so it looks fine to me. |
Here's a variation of this that still does not work with 1.8.1: from pydantic import BaseModel
class Foo(BaseModel):
x: int
def __hash__(self):
return self.x ** 2
f = Foo(x=2)
assert hash(f) == 4
class Bar(Foo):
y: float
class Bar2(BaseModel):
z: float
class Baz(Bar2, Bar):
pass
b = Bar(x=2, y=1.1)
c = Baz(x=2, y=1.1, z=3.1)
# This works now thanks to #2423
assert hash(b) == 4
# But not this
try:
assert hash(c) == 4
except TypeError as e:
# TypeError: unhashable type: 'Baz'
print(e) Whether or not the current behaviour is desired, it is at least different from the one in 1.7. To recover the 1.7 behaviour, this seems to work for me: Changing this line if base.__hash__ is not None:
hash_func = base.__hash__ |
@alcrene Try with |
@PrettyWood khaeru's original example also fails with
The reasoning seems clear enough: the assumptions underlying the To be clear, I have no strong opinion here – I'm just noting a change in behaviour that I had forgotten I was relying upon. IMO this is a corner case, and if people want reliable |
Thanks for that tip. We encountered the same issue, and this is indeed the way to make it work now. |
Checks
Bug
The following code worked in pydantic 1.7.3 (version info shown below), but fails with pydantic 1.8:
It seems like this code prevents the use of
Foo.__hash__
onBar
instances:https://github.com/samuelcolvin/pydantic/blob/master/pydantic/main.py#L347
I tried to experiment with adding
"__hash__"
to__slots__
, but an error is triggered inModelMetaclass.__new__
:I would expect that this continues to work as in 1.7.3, or that the documentation suggests how to avoid having these methods squashed.
Output of
python -c "import pydantic.utils; print(pydantic.utils.version_info())"
:Passing version:
Failing version:
The text was updated successfully, but these errors were encountered: