[Python-Dev] Dataclasses and correct hashability
Ethan Furman
ethan at stoneleaf.us
Tue Feb 6 14:40:49 EST 2018
On 02/06/2018 11:18 AM, Guido van Rossum wrote:
> We may be in violent agreement.
>
> I propose *not* to add a way to *disable* hashing when the rest of the flags to @dataclass() would indicate that it's
> safe to add a __hash__ method.
Okay.
> I propose that with @dataclass(unsafe_hash=False) (the default), a __hash__ method is added when the following
> conditions are true:
>
> - frozen=True (not the default)
> - compare=True (the default)
> - no __hash__ method is defined in the class
>
> If we instead use @dataclass(unsafe_hash=True), a __hash__ will be added regardless of the other flags, but if a
> __hash__ method is present, an exception is raised.
>
> Other values (e.g. unsafe_hash=None) are illegal for this flag.
Ah! Excellent, that greatly allays my worries.
> Note that the the hash= flag to the field() function is unchanged from what's currently in PEP 557 or in the
> implementation in 3.7.0b1. In particular, the generated __hash__ method will disregard fields declared using
> field(hash=False). It will also disregard fields declared using field(compare=False, hash=False|None).
It sounds like `unsafe_hash=True` indicates a truly unsafe hash (that is, mutable data is involved in the hash
calculation), but there still seems to be one possibility for an "unsafe_hash" to actually be safe -- that is, if only
immutable fields are used in __eq__, then dataclass could safely generate a hash for us.
Do we have a way to know if the equality fields are hashable? I suppose we could check each one for a for a non-None
__hash__. Then we could modify that first condition from
- frozen=True
to
- frozen=True or all(getattr(eq_fld, '__hash__', None) is not None for eq_field in equality_fields)
Thoughts?
On a different note, should the PEP be updated with the current signature? It still talks about hash=None being the
default.
--
~Ethan~
More information about the Python-Dev
mailing list