__delitem__ "feature"

kj no.email at please.post
Sun Dec 26 12:53:17 EST 2010




When I execute this file:

#----------------------------------------------------------------------
def nodelfactory(klass):
    class nodel(klass):
        def _delitem(self, _):
            raise TypeError("can't delete")

        # __delitem__ = _delitem

        def __init__(self, *a, **k):
            klass.__init__(self, *a, **k)
            self.__delitem__ = self._delitem

    nodel.__name__ = 'nodel%s' % klass.__name__
    return nodel


if __name__ == '__main__':
    import traceback as tb


    d = nodelfactory(dict)([('k1', 'v1'), ('k2', 'v2')])

    try: d.__delitem__('k1')
    except TypeError: tb.print_exc()
    print d

    try: del d['k1']
    except TypeError: tb.print_exc()
    print d


    l = nodelfactory(list)([1, 2, 3, 4])

    try: l.__delitem__(0)
    except TypeError: tb.print_exc()
    print l

    try: del l[0]
    except TypeError: tb.print_exc()
    print l
#----------------------------------------------------------------------

...the output I get is:

Traceback (most recent call last):
  File "/tmp/delbug.py", line 20, in <module>
    try: d.__delitem__('k1')
  File "/tmp/delbug.py", line 4, in _delitem
    raise TypeError("can't delete")
TypeError: can't delete
{'k2': 'v2', 'k1': 'v1'}
{'k2': 'v2'}
Traceback (most recent call last):
  File "/tmp/delbug.py", line 30, in <module>
    try: l.__delitem__(0)
  File "/tmp/delbug.py", line 4, in _delitem
    raise TypeError("can't delete")
TypeError: can't delete
[1, 2, 3, 4]
[2, 3, 4]

It means that, for both subclasses, del fails to trigger the
dynamically installed instance method __delitem__.

If I replace dict with UserDict, *both* deletion attempts lead to
a call to the dynamic __delitem__ method, and are thus blocked.
This is the behavior I expected of dict (and will help me hold on
to my belief that I'm not going insane when inevitably I'm told
that there's no bug in dict or list).

Interestingly enough, if I replace list with UserList, I see no
change in behavior.  So maybe I am going insane after all.

~kj

P.S. If you uncomment the commented-out line, and comment out the
last line of the __init__ method (which installs self._delitem as
self.__delitem__) then *all* the deletion attempts invoke the
__delitem__ method, and are therefore blocked.  FWIW.



More information about the Python-list mailing list