-
-
Notifications
You must be signed in to change notification settings - Fork 2.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
Improve attrs hashability detection #16556
Conversation
This comment has been minimized.
This comment has been minimized.
5711b3a
to
6067f38
Compare
This comment has been minimized.
This comment has been minimized.
@sobolevn Does this look good to you? 🙏 |
This comment has been minimized.
This comment has been minimized.
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's wait a bit for more possible input. I will merge this in several days.
@Tinche are you sure about the inheritance behavior? I just upgraded to mypy 1.9 and encountered this. I have a In [1]: import attrs
In [2]: @attrs.define
...: class A:
...: a: int
...:
In [3]: @attrs.define(frozen=True)
...: class B(A):
...: b: int
...:
In [4]: hash(B(a=1, b=2))
Out[4]: -1340312973636267308
In [5]: hash(A(a=1))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[5], line 1
----> 1 hash(A(a=1))
TypeError: unhashable type: 'A' However mypy doesn't seem to think it is: import attrs
import functools
@attrs.define
class A:
a: int
@attrs.define(frozen=True)
class B(A):
b: int
b = B(a=1, b=2)
@functools.lru_cache()
def foo(b: B) -> int:
return b.b
foo(b)
This is using attrs 23.3.0, mypy 1.9.0. |
@brianmedigate I tested the other direction :/ I'll look into handling this case in a new PR. |
This commit fixes a couple regressions in 1.9.0 from 91be285. Attrs' logic for hashability is slightly complex: * https://www.attrs.org/en/stable/hashing.html * https://github.com/python-attrs/attrs/blob/9e443b18527dc96b194e92805fa751cbf8434ba9/src/attr/_make.py#L1660-L1689 Mypy now properly emulates attrs' logic so that custom `__hash__` implementations are preserved, `@frozen` subclasses are always hashable, and classes are only made unhashable based on the values of eq and `unsafe_hash`. Fixes python#17015 Fixes python#16556 (comment) Based on a patch in python#17012 Co-Authored-By: Tin Tvrtkovic <tinchester@gmail.com>
This commit fixes a couple regressions in 1.9.0 from 91be285. Attrs' logic for hashability is slightly complex: * https://www.attrs.org/en/stable/hashing.html * https://github.com/python-attrs/attrs/blob/9e443b18527dc96b194e92805fa751cbf8434ba9/src/attr/_make.py#L1660-L1689 Mypy now properly emulates attrs' logic so that custom `__hash__` implementations are preserved, `@frozen` subclasses are always hashable, and classes are only made unhashable based on the values of eq and `unsafe_hash`. Fixes python#17015 Fixes python#16556 (comment) Based on a patch in python#17012 Co-Authored-By: Tin Tvrtkovic <tinchester@gmail.com>
This commit fixes a couple regressions in 1.9.0 from 91be285. Attrs' logic for hashability is slightly complex: * https://www.attrs.org/en/stable/hashing.html * https://github.com/python-attrs/attrs/blob/9e443b18527dc96b194e92805fa751cbf8434ba9/src/attr/_make.py#L1660-L1689 Mypy now properly emulates attrs' logic so that custom `__hash__` implementations are preserved, `@frozen` subclasses are always hashable, and classes are only made unhashable based on the values of eq and `unsafe_hash`. Fixes python#17015 Fixes python#16556 (comment) Based on a patch in python#17012 Co-Authored-By: Tin Tvrtkovic <tinchester@gmail.com>
This commit fixes a couple regressions in 1.9.0 from 91be285. Attrs' logic for hashability is slightly complex: * https://www.attrs.org/en/stable/hashing.html * https://github.com/python-attrs/attrs/blob/9e443b18527dc96b194e92805fa751cbf8434ba9/src/attr/_make.py#L1660-L1689 Mypy now properly emulates attrs' logic so that custom `__hash__` implementations are preserved, `@frozen` subclasses are always hashable, and classes are only made unhashable based on the values of eq and `unsafe_hash`. Fixes python#17015 Fixes python#16556 (comment) Based on a patch in python#17012 Co-Authored-By: Tin Tvrtkovic <tinchester@gmail.com>
This commit fixes a couple regressions in 1.9.0 from 91be285. Attrs' logic for hashability is slightly complex: * https://www.attrs.org/en/stable/hashing.html * https://github.com/python-attrs/attrs/blob/9e443b18527dc96b194e92805fa751cbf8434ba9/src/attr/_make.py#L1660-L1689 Mypy now properly emulates attrs' logic so that custom `__hash__` implementations are preserved, `@frozen` subclasses are always hashable, and classes are only made unhashable based on the values of `eq` and `unsafe_hash`. Fixes python#17015 Fixes python#16556 (comment) Based on a patch in python#17012 Co-Authored-By: Tin Tvrtkovic <tinchester@gmail.com>
This commit fixes a couple regressions in 1.9.0 from 91be285. Attrs' logic for hashability is slightly complex: * https://www.attrs.org/en/stable/hashing.html * https://github.com/python-attrs/attrs/blob/9e443b18527dc96b194e92805fa751cbf8434ba9/src/attr/_make.py#L1660-L1689 Mypy now properly emulates attrs' logic so that custom `__hash__` implementations are preserved, `@frozen` subclasses are always hashable, and classes are only made unhashable based on the values of `eq` and `unsafe_hash`. Fixes python#17015 Fixes python#16556 (comment) Based on a patch in python#17012 Co-Authored-By: Tin Tvrtkovic <tinchester@gmail.com>
This commit fixes a couple regressions in 1.9.0 from 91be285. Attrs' logic for hashability is slightly complex: * https://www.attrs.org/en/stable/hashing.html * https://github.com/python-attrs/attrs/blob/9e443b18527dc96b194e92805fa751cbf8434ba9/src/attr/_make.py#L1660-L1689 Mypy now properly emulates attrs' logic so that custom `__hash__` implementations are preserved, `@frozen` subclasses are always hashable, and classes are only made unhashable based on the values of `eq` and `unsafe_hash`. Fixes #17015 Fixes #16556 (comment) Based on a patch in #17012 Co-Authored-By: Tin Tvrtkovic <tinchester@gmail.com> Co-authored-by: Hashem Nasarat <hashem@hudson-trading.com>
Fixes #16550
Improve hashability detection for attrs classes.
I added a new parameter to
add_attribute_to_class
,overwrite_existing
, since I needed it.Frozen classes remain hashable, non-frozen default to no. This can be overriden by passing in
hash=True
orunsafe_hash=True
(new parameter, added to stubs) todefine()
.Inheritance-wise I think we're correct, if a non-hashable class inherits from a hashable one, it's still unhashable at runtime.
Accompanying tests.