[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:29:02 -0400


[Raymondo]
>>> The original code does its contortions to avoid raising a KeyError
>>> whenever the dictionary entry might have disappeared due to the
>>> ref count falling to zero and then a new, equal key was formed
>>> later.

[Timbot]
>> Sorry, I can't picture what you're trying to say.  Show some code?

[Razor]
> 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 C: pass
> ...
> >>> import weakref
> >>> wkd = weakref.WeakKeyDictionary()
> >>> del wkd[C()]
> >>> # No complaints

Right, and I call that a bug.  One of the new tests I checked in does
exactly that, BTW.  As I said last time, the idea that trying to delete a
key from a weak-keyed dict never raises KeyError was neither documented nor
verified by a test, so there's no reason to believe it was anything other
than a bug in the implementation of __delitem__.

> Python 2.3b1+ (#40, May 23 2003, 00:08:36) [MSC v.1200 32 b
> Type "help", "copyright", "credits" or "license" for more i
> >>> class C: pass
> ...
> >>> import weakref
> >>> wkd = weakref.WeakKeyDictionary()
> >>> del wkd[C()]
> 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)]
> KeyError: <weakref at 006BC600; to 'instance' at 006BAA30>
> >>> # Complains now.

Right, and that's intentional, and tested now too.  It's always been the
case (and still is) that wkd[C()] raised KeyError too -- why should
__delitem__, and only __delitem__, be exempt from complaining about a
senseless operation?

>>> If the data disappeared, then, I think ref(key) will return None

>> No, ref(x) never returns None, regardless of what x may be.  It may
>> raise TypeError if x is not of a weakly referencable type, and it
>> may raise MemoryError if we don't have enough memory left to
>> construct a weakref, but those are the only things that can go wrong.

> [Current version of the docs]
> """
> ref( object[, callback])
>
> Return a weak reference to object. The original object can be
> retrieved by calling the reference object if the referent is still
> alive; if the referent is no longer alive, calling the reference
> object will cause None to be returned. """

That's what I said last time:

    w = ref(x) followed later by w() will return None, iff x has gone away
    in the meantime -- maybe that's what you're thinking of.

Note that "calling the reference object" in the docs does not mean the call
"ref(x)" itself, it means calling the object returned by ref(x) (what I
named "w" in the quote just above).