Open grievejia opened 3 months ago
Yeah, as you noted, statically determining the hashability of a type is tricky because the hashing mechanism in Python unfortunately doesn't follow standard inheritance rules.
I'd welcome an extension to the typing spec that standardizes static typing behaviors related to hashability.
I agree that the current conformance test implementation makes some brittle assumptions. I'm fine with your proposed change.
I noticed that the conformance test currently enforces a hashability check on dataclasses: https://github.com/python/typing/blame/6d5c186ea3f45dd80dcad9f172479b270e54966a/conformance/tests/dataclasses_hash.py
If we take the annotation of
typing.Hashable
and the annotation ofobject
literally, then no type errors should be reported on that file, astyping.Hashable
is a protocol that requires adef __hash__(self) -> int
method, andobject
satisfies that protocol regardless of whether the dataclass transform creates its own__hash__
method or not.I understand that the issue of deciding whether an object is hashable or not in type checkers is a tricky business and there was a lot of pre-existing discussions/proposals around it. This makes me wonder if it's worth doing a dedicated "hashability" section in the spec, and use separate conformance tests to establish how
typing.Hashable
assignability should be handled. My understanding is that the pre-existing dataclass hash tests is intended to just test about whether the__hash__
method is nullified or not under the dataclass transform, but by testing it viatyping.Hashable
it kinds of indirectly dictate hashable assignment behaviors as a side effect.Concretely, what I had in mind was a refactor to
dataclasses_hash.py
, where we change the current assertions of the forminto something like this:
The new version does not depend on how
typing.Hashable
gets defined in typeshed, and it (arguably) aligns more directly with the intention of the tests. But I am unsure about how controversial this proposal would be and hence want to get some feedback on it first.