[Python-Dev] Dataclasses and correct hashability

Ethan Furman ethan at stoneleaf.us
Tue Feb 6 15:44:52 EST 2018


On 02/06/2018 12:24 PM, Guido van Rossum wrote:
> On Tue, Feb 6, 2018 at 11:40 AM, Ethan Furman wrote:

>> 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)
>
> There seems to be a misunderstanding underlying these questions. Even if
 > all fields have an immutable type (e.g. all ints, supporting __eq__ and
 > __hash__), if the containing class isn't frozen, they can be assigned to.
 > E.g.
>
> @dataclass()
> class Point:
>   x: int
>   y: int
>
> p = Point(1, 1)
> p.x = 2  # This is legal
>
> The only way to make that assignment to p.x illegal is to make the *class*
 > frozen (using @dataclass(frozen=True)) -- nothing we can do about the *field*
 > will change this.

Oh, right.  When I was thinking this I thought a field could be frozen individually, didn't find the option at the field 
level when I checked the PEP, and then promptly forgot and suggested it anyway.

Although, couldn't we add a field-level frozen attribute (using property for the implementation), and check that all 
equality fields are properties as well as hashable?

--
~Ethan~


More information about the Python-Dev mailing list