[Python-Dev] Dataclasses and correct hashability

Guido van Rossum guido at python.org
Tue Feb 6 14:18:20 EST 2018

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__

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.

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).

On Tue, Feb 6, 2018 at 10:11 AM, Ethan Furman <ethan at stoneleaf.us> wrote:

> On 02/06/2018 09:38 AM, Guido van Rossum wrote:
> Where do you get the impression that one would have to explicitly request
>> __hash__ if frozen=True is set? To the
>> contrary, my proposal is for @dataclass to automatically add a __hash__
>> method when frozen=True is set. This is what the
>> code currently released as 3.7.0b1 does if hash=None (the default).
> Which is my issue with the naming -- although, really, it's more with the
> parameter/argument:  in a hand-written class,
>   __hash__ = None
> means the object in is not hashable, but with the decorator:
>   @dataclass(..., hash=None, ...)
> it means something else.
> My preference for "fixing" the issue:
> 1) make the default be a custom object (not None), so that `hash=None`
>    means disable hashing
> 2) change the param name -- maybe to `add_hash` (I agree with D'Aprano
>    that `unsafe_hash` can be misleading)
> --
> ~Ethan~
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/guido%
> 40python.org

--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180206/d6563d3a/attachment.html>

More information about the Python-Dev mailing list