-
-
Notifications
You must be signed in to change notification settings - Fork 374
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 function missing from subclass #483
Comments
As a note, it would also be nice if subclasses always inherited import attr
@attr.s
class Foo:
pass
@attr.s(cmp=False)
class Bar(Foo):
pass
## workaround from issue description
Bar.__hash__ = object.__hash__
@attr.s
class Baz(Bar):
pass
assert Baz.__hash__ is object.__hash__, "Baz is missing the identity hash method" Perhaps defaulting cmp/frozen to None and then doing a similar mro search as with attributes to determine if the hash method is needed. |
Hm the problem here is twofold:
Do you realize that you can write: @attr.s(cmp=False)
class Bar(Foo):
__hash__ = object.__hash__ ? That seems more idiomatic than doing implicit black magic behind the users’ back. |
Marked as @vitalbmcdonald Do you think the documentation is insufficiently clear here? I could see an argument that this text in the Hashing page:
…might imply that |
@hynek, good call on declaring the hash method in the class definition, I'm not sure why I had it separated out. @wsanchez, as far as the documentation, I did get the impression that setting cmp=False was the way to explicitly set the hash functionality to use the id when in reality it is whatever hash function is inherited. But the real root of my confusion is a misunderstanding on how python hash functions worked by default. For instances: class Foo:
def __eq__(self, other):
return super().__eq__(self, other)
class Bar(Foo):
pass
assert Bar.__hash__ is None I would have thought Thanks for the help! |
OK so it sounds like the docs could use a small tweak to say it's inheriting the method, since it sort of implies that |
When creating a subclass of an attr object, I would expect setting
cmp=False
to cause the subclass to be hashable. Right now it inherits the hash settings from its parent and ignores the cmp settings for hashing.The issue I believe is this elif block assumes that the class is inheriting from
object
and thereby getting its__hash__
method. Adding a line to explicitly add the__hash__
method would fix the problem.The workaround I am using is just adding the
__hash__
method after the class is defined, soThe text was updated successfully, but these errors were encountered: