python-attrs / python-attrs/attrs

Inheriting from a frozen class causes instantiated child hashes to collide

Open
#528 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.