On Sun, Feb 4, 2018, 9:50 PM Guido van Rossum <guido at python.org> wrote:

Looks like this is turning into a major flamewar regardless of what I say.
:-(
I really don't want to lose the ability to add a hash function to a
mutable dataclass by flipping a flag in the decorator. I'll explain below.
But I am fine if this flag has a name that clearly signals it's an unsafe
thing to do.

I propose to replace the existing (as of 3.7.0b1) hash= keyword for the
@dataclass decorator with a simpler flag named unsafe_hash=. This would be
a simple bool (not a tri-state flag like the current hash=None|False|True).
The default would be False, and the behavior then would be to add a hash
function automatically only if it's safe (using the same rules as for
hash=None currently). With unsafe_hash=True, a hash function would always
be generated that takes all fields into account except those declared using
field(hash=False). If there's already a `def __hash__` in the function I
don't care what it does, maybe it should raise rather than quietly doing
nothing or quietly overwriting it.

Here's my use case.

May be it is better to provide a special purpose function `make_unsafe_hash` in
dataclass module which will patch a dataclass, instead of to clutter @dataclass
API with arguments which are rather special case.

This `unsafe_hash` argument will constantly raise questions among ordinary users
like me, and will be possibly considered as a non-obvious design - there is a
public API but it is somehow unsafe. On the other hand, with a function, when
the user asks how to make a `frozen=False` dataclass hashable, you can suggest
to use this `make_unsafe_hash` function with all its cautions in its docs or to try to
implement __hash__ by yourself.

Also taking into account the Python approach for backward compatibility it is
better to stick with function and if it will be usefull to add a `unsafe_hash`
argument in Python 3.8. It is easier to add later than to deprecate in the future.

With kind regards,
-gdg