[Python-Dev] Creating dicts from dict subclasses
Walter Dörwald
walter at livinglogic.de
Wed Dec 13 23:18:53 CET 2006
Guido van Rossum wrote:
> On 12/13/06, Walter Dörwald <walter at livinglogic.de> wrote:
>> I tried to reimplement weakref.WeakValueDictionary as a subclass of
>> dict. The test passes except for one problem: To compare results
>> test_weakref.py converts a weakdict to a real dict via dict(weakdict).
>> This no longer works because PyDict_Merge() does a PyDict_Check() on the
>> argument and then ignores all overwritten methods. (The old version
>> worked because UserDict.UserDict was used).
>>
>> The simplest solution is to replace the PyDict_Check() call with
>> PyDict_CheckExact(), but this might slow things down too much, because
>> the fallback code basically does:
>>
>> for key in iter(arg.keys()):
>> self[key] = arg.__getitem__(key)
>>
>> Why can't we use:
>>
>> for key in iter(arg):
>> self[key] = arg.__getitem__(key)
>>
>> instead?
>
> The only reason I can think of is backwards compatibility: not all
> "mappings" created pre-2.2 would support iteration. Maybe you could
> check for a tp_iter slot and if non-NULL use the latter otherwise use
> the original fallback?
This doesn't seem to work. It breaks test_update() in test_dict.py which
does this:
d = {}
class SimpleUserDict:
def __init__(self):
self.d = {1:1, 2:2, 3:3}
def keys(self):
return self.d.keys()
def __getitem__(self, i):
return self.d[i]
d.update(SimpleUserDict())
self.assertEqual(d, {1:1, 2:2, 3:3})
This fails with
KeyError: 0
because SimpleUserDict doesn't implement __iter__, so it gets an
iterator implementation via __getitem__.
So maybe this only makes sense for Python 3.0 where we can demand that
dict-like classes implement __iter__?
Servus,
Walter
More information about the Python-Dev
mailing list