python-attrs / python-attrs/attrs
Inheriting from a frozen class causes instantiated child hashes to collide
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 5.8k
- Forks
- 480
- Avg merge
- 2h 15m
- Merged PRs (30d)
- 2
Description
This works as expected:
class A:
pass
class B(A):
pass
class C(A):
pass
assert hash(B) != hash(C)
assert hash(B()) != hash(C())
=========================== 1 passed in 3.39 seconds ===========================
This errors:
import attr
@attr.s(frozen=True)
class A:
pass
class B(A):
pass
class C(A):
pass
assert hash(B) != hash(C)
assert hash(B()) != hash(C())
> assert hash(B()) != hash(C())
E AssertionError: assert 7618298384354620882 != 7618298384354620882
E + where 7618298384354620882 = hash(B())
E + where B() = <class 'test_attr_bug.<locals>.B'>()
E + and 7618298384354620882 = hash(C())
E + where C() = <class 'test_attr_bug.<locals>.C'>()
So these two instantiated classes hash to the same value despite a) being instances of different classes and b) being of classes which, when uninstantiated, have differing hashes.
This seems very wrong to me!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the Python examples from the issue and confirm that instances of the two frozen subclasses produce the same hash. Then trace attrs' generated hashing for frozen classes and add a regression test covering distinct subclasses; done means the instantiated B and C hashes differ without breaking the existing frozen-class behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- developer-experience
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100