Re: A proposal to modify `None` so that it hashes to a constant

Wild suggestion: Make None.__hash__ writable. E.g. None.__hash__ = lambda : 0 # Currently raises AttributeError: 'NoneType' object attribute '__hash__' is read-only Best wishes Rob Cliffe On 01/12/2022 11:02, Oscar Benjamin wrote:
On Thu, 1 Dec 2022 at 06:56, Chris Angelico <rosuav@gmail.com> wrote:
On Thu, 1 Dec 2022 at 17:26, Yoni Lavi <yoni.lavi.p@gmail.com> wrote:
So it's not like it's even possible to require this generally for all objects. Well, I mean, in theory you could require that objects whose hash isn't otherwise defined get given the hash of zero. That doesn't violate any of the actual rules of hashes, but it does make those hashes quite suboptimal :)
It's interesting how id() and hash() have opposite requirements (id must return a unique number among concurrently-existing objects, hash must return the same number among comparing-equal objects), yet a hash can be built on an id. This also demonstrates a significant reason why None is special: it's a singleton that only compares equal to itself. The reason for using id for hash in other cases is to make different instances have different hashes but there is only ever one instance of None. A singleton class can have a hash function that matches identity based equality without using id: any constant hash function will do.
-- Oscar _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/MTTJJN2H... Code of Conduct: http://python.org/psf/codeofconduct/

On Mon, 5 Dec 2022 at 05:11, Rob Cliffe via Python-Dev <python-dev@python.org> wrote:
Wild suggestion: Make None.__hash__ writable. E.g. None.__hash__ = lambda : 0 # Currently raises AttributeError: 'NoneType' object attribute '__hash__' is read-only
Hashes have to be stable. If you change the hash of None after it's been inserted into a dictionary, you'll get all kinds of entertaining problems.
class X: ... def __init__(self): self.hash = 0 ... def __hash__(self): return self.hash ... x = X() d = {x: "This is x"} x.hash = 1 for key in d: print(key, key in d) ... <__main__.X object at 0x7f2d07c6f1c0> False
ChrisA

On Thu, Dec 01, 2022 at 10:18:49PM +0000, Rob Cliffe via Python-Dev wrote:
Wild suggestion: Make None.__hash__ writable. E.g. None.__hash__ = lambda : 0 # Currently raises AttributeError: 'NoneType' object attribute '__hash__' is read-only
You would have to write to `type(None).__hash__` because of the way dunders work. Now imagine that you have twenty different libraries or functions or classes, each the `__hash__` method to a different function. Chaos. You can simulate that chaos with this: ``` import random class ChangingHash: def __repr__(self): return "MyNone" def __hash__(self): # Simulate the effect of many different callers changing # the hash value returned at unpredictable times. return random.randint(1, 9) MyNone = ChangingHash() data = {MyNone: 100} print(MyNone in data) # 8 in 9 chance of printing False data[MyNone] = 200 print(data) # 8 in 9 chance of {MyNone: 100, MyNone: 200} print(MyNone in data) # now 7 in 9 chance of printing False ``` -- Steve

You are absolutely right, of course. It was a wild idea, and a bad one. I find myself moving towards supporting the OP. I can't see anything terrible about the hash of None always being 0, or perhaps better some other arbitrary constant. Rob On 04/12/2022 03:20, Steven D'Aprano wrote:
On Thu, Dec 01, 2022 at 10:18:49PM +0000, Rob Cliffe via Python-Dev wrote:
Wild suggestion: Make None.__hash__ writable. E.g. None.__hash__ = lambda : 0 # Currently raises AttributeError: 'NoneType' object attribute '__hash__' is read-only You would have to write to `type(None).__hash__` because of the way dunders work.
Now imagine that you have twenty different libraries or functions or classes, each the `__hash__` method to a different function. Chaos.
You can simulate that chaos with this:
``` import random
class ChangingHash: def __repr__(self): return "MyNone" def __hash__(self): # Simulate the effect of many different callers changing # the hash value returned at unpredictable times. return random.randint(1, 9)
MyNone = ChangingHash()
data = {MyNone: 100} print(MyNone in data) # 8 in 9 chance of printing False data[MyNone] = 200 print(data) # 8 in 9 chance of {MyNone: 100, MyNone: 200} print(MyNone in data) # now 7 in 9 chance of printing False ```
participants (3)
-
Chris Angelico
-
Rob Cliffe
-
Steven D'Aprano