That seems a rare case (though I hadn't thought of it). I had thought of the use case where you want a frozen type without a hash; that you can presumably implement using
def __hash__(self): raise TypeError("not hashable") We can do a similar thing to preserve the superclass __hash__ if it's rare enough: def __hash__(self): return super().__hash__() If at all possible I'd like to kill the tri-state hash= flag -- the amount of time spent creating and discussing the huge table in the bpo issue are an indication of how much effort it would take other people to understand it. If either of those use cases becomes annoyingly common we'll have to think of something else. On Tue, Feb 6, 2018 at 5:38 PM, Eric V. Smith <e...@trueblade.com> wrote: > Sorry for the late reply. Still recovering from a computer failure. > > My only concern with this approach is: what if you don’t want any __hash__ > added? Say you want to use your base class’s hashing. I guess you could > always “del cls.__hash__” after the class is created, but it’s not elegant. > > That’s what we got from the tri-state option: never add (False), always > add (True), or add if it’s safe (None). > > -- > Eric > > On Feb 5, 2018, at 12:49 AM, Guido van Rossum <gu...@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. > > A frozen class requires a lot of discipline, since you have to compute the > values of all fields before calling the constructor. A mutable class allows > other initialization patterns, e.g. manually setting some fields after the > instance has been constructed, or having a separate non-dunder init() > method. There may be good reasons for using these patterns, e.g. the object > may be part of a cycle (e.g. parent/child links in a tree). Or you may just > use one of these patterns because you're a pretty casual coder. Or you're > modeling something external. > > My point is that once you have one of those patterns in place, changing > your code to avoid them may be difficult. And yet your code may treat the > objects as essentially immutable after the initialization phase (e.g. a > parse tree). So if you create a dataclass and start coding like that for a > while, and much later you need to put one of these into a set or use it as > a dict key, switching to frozen=True may not be a quick option. And writing > a __hash__ method by hand may feel like a lot of busywork. So this is where > [unsafe_]hash=True would come in handy. > > I think naming the flag unsafe_hash should take away most objections, > since it will be clear that this is not a safe thing to do. People who > don't understand the danger are likely to copy a worse solution from > StackOverflow anyway. The docs can point to frozen=True and explain the > danger. > > -- > --Guido van Rossum (python.org/~guido) > > _______________________________________________ > Python-Dev mailing list > Python-Dev@python.org > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/ > eric%2Ba-python-dev%40trueblade.com > > -- --Guido van Rossum (python.org/~guido)
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com