On 7 February 2018 at 12:48, Guido van Rossum <guido@python.org> wrote:
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")
Now that attributes in the class dict pre-empt the generated versions, "__hash__ = None" in the class body will also turn off hash generation without enabling hashing.
We can do a similar thing to preserve the superclass __hash__ if it's rare enough:
def __hash__(self): return super().__hash__()
Similarly for this variant, you can do "__hash__ = BaseClassWithDesiredHashAlgorithm.__hash__". (That may be more appropriate than dynamic lookup in the MRO if you're extending a frozen class with a subclass that adds more fields, but you want to keep using the base class hash definition for some reason)
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.
+1 - the nice thing about "unsafe_hash=True" is that you *only* need it if adding the hash would be unsafe, and you haven't set __hash__ explicitly in the class body. While "frozen=True, unsafe_hash=True" is redundant (since the hash is safe when instances are frozen), it isn't a surprising defect waiting to happen the way "frozen=False, hash=True" is in the current interface. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia