[Python-Dev] RE: [Python-checkins] python/dist/src/Lib weakref.py,1.19,1.20

Tim Peters tim_one@email.msn.com
Sun, 25 May 2003 02:48:25 -0400


[Raymond Hettinger]
> The old behavior for missing keys may have been a bug.
> Do you care about the previous behavior for deleting
> based on equality rather than equality *and* hash?

Nope, because it was neither documented nor tested, and was behavior unique
to the WeakKeyDictionary flavor of dict -- no other flavor of dict works
that way, and it was just an accident due to the __delitem__ implementation.
Note too that it's a documented requirement of the mapping protocol that
keys that compare equal must also return equal hash values.

> Python 2.3b1 (#40, Apr 25 2003, 19:06:24) [MSC v.1200 32 bit (Intel)]
> on win32 Type "copyright", "credits" or "license" for more
> information. IDLE 0.8 -- press F1 for help
> >>> class One:
>      def __eq__(self, other):
>       return other == 1
>      def __hash__(self):
>       return 1492

> >>> import weakref
> >>> wkd = weakref.WeakKeyDictionary()
> >>> o = One()
> >>> wkd[o] = None
> >>> len(wkd)
> 1
> >>> del wkd[1]
> >>> len(wkd)
> 0

Just a case of GIGO (garbage in, garbage out) to me.

> Python 2.3b1+ (#40, May 23 2003, 00:08:36) [MSC v.1200 32
> Type "help", "copyright", "credits" or "license" for more
> >>> class One:
> ..     def __eq__(self, other):
> ..         return other == 1
> ..     def __hash__(self):
> ..         return 1492
> ..
> >>> import weakref
> >>> wkd = weakref.WeakKeyDictionary()
> >>> o = One()
> >>> wkd[o] = None
> >>> len(wkd)
> 1
> >>> del wkd[1]
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "C:\PY23\lib\weakref.py", line 167, in __delitem__
>     del self.data[ref(key)]
> TypeError: cannot create weak reference to 'int' object
> >>> len(wkd)
> 1
> >>>

As I said the first time <wink>,

    will succeed if and only if d.data has a key for a still-live object,
    and that key compares equal to k1; else it will raise KeyError
    (or maybe TypeError if k1 is a silly key to test in a weak-keyed dict,
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    or MemoryError if we run out of memory).  That's what I believe it
    should do.

I didn't add "and the hash codes are the same too" because that requirement
is part of the the mapping protocol.