[Tutor] Problems with deleting dictionary keys.

Roeland Rengelink r.b.rigilink@chello.nl
Tue, 14 Aug 2001 07:24:52 +0200


Note to readers: This thread is only relevant in Python2.2.

Python2.2a1 is the first alpha release of a new Python version that
promises to make a start at healing the type/class dichotomy. This will
allow you to inherit form built-in types (dictionaries/lists for now, in
the future also strings and the rest).

Some of this is pretty advanced stuff. See the announcements and
references on the Python website. Nevertheless, I think Guido would love
to see Python beginners experimenting with this stuff. So maybe you
should give it a try. Report feedback/questions etc here, and I'm sure
he'll have a look.


Allan Crooks wrote:
> 
> Hi,
> 
> I've got the following problem with dictionaries. The problem is, I get
> this error when I try to delete a key value with the __setitem__
> method.
> 
> I feel that the problem will be clearer if I give you example code. :)
> 
> -------
> 
> Python 2.2a1 (#21, Jul 18 2001, 04:25:46) [MSC 32 bit (Intel)] on
> win32
> Type "copyright", "credits" or "license" for more information.
> 
> >>> class d2(dictionary):
> ...     def __setitem__(self, key, value):
> ...          if value==0:
> ...             del self[key]
> ...          else:
> ...             print "Setting [%s] to %s." % (key, value)
> ...
> >>> d = d2()
> >>> d.update({'p': 1, 'l': 2, 'a': 3, 'i': 4, 'd': 5})
> >>> d
> {'a': 3, 'p': 1, 'i': 4, 'd': 5, 'l': 2}
> >>> d['a']=10
> Setting [a] to 10.
> >>> d['a']=0
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "<stdin>", line 4, in __setitem__
> SystemError: NULL object passed to Py_BuildValue
> 
> I seem to remember there being a problem in earlier versions of
> Python, where if you modify the dictionary while doing other things
> to it, it would crash the interpreter.
> 
> So what I need to know is if this is a bug, or if I'm doing something
> wrong....
> 

I think this is a known bug. Guido has stated that the new types don't
support __delitem__ yet. I think you're seeing the consequences:

For example:

>>> class A(dictionary):
...     def __setitem__(self, key, val):
...             if val==0:
...                     dictionary.__delitem__(self, key)
...             else:
...                     dictionary.__setitem__(self, key, val)
... 
>>> a = A()
>>> a[1] = 1
>>> a
{1: 1}
>>> a[1] = 0
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 4, in __setitem__
AttributeError: type object 'dictionary' has no attribute '__delitem__'
>>> dictionary.__delitem__
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: type object 'dictionary' has no attribute '__delitem__'

although this works:
>>> b = dictionary() 
>>> b[1] = 1
>>> del b[1]

and this too:

>>> class B(dictionary):
...     def delete_it(self, key):
...             del self[key]
... 
>>> b = B()
>>> b[1] = 1
>>> b.delete_it(1)

so it's somewhat surprising that del self[key] doesn't work in
__setitem__

You might want to report this as a bug. (If you don't want to, I can).
SystemErrors are the Python equivalent of core dumps.

Probably the absence of __delitem__ in dictionaries and the systemerror
when using del self[a] in a __setitem__, are related. No idea how,
though.

Hope this helps,

Roeland

-- 
r.b.rigilink@chello.nl

"Half of what I say is nonsense. Unfortunately I don't know which half"