Overriding dict constructor
Duncan Booth
duncan.booth at invalid.invalid
Tue Sep 21 03:37:33 EDT 2010
Steven D'Aprano <steve at REMOVE-THIS-cybersource.com.au> wrote:
> On Mon, 20 Sep 2010 11:53:48 +0000, Duncan Booth wrote:
>
>> I was going to suggest overriding items() (or iteritems() for Python
>> 2.x), but while that is another hole that your values leak out it
isn't
>> the hole used by the dict constructor.
>
> Yes, I already override items(), keys(), values(), their iter...
> versions, and just about every damn method that dicts have :/
>
> I suspect that the dict() constructor is just grabbing the key/value
> pairs directly from the underlying hash table. If that's the case, my
> choices are to not inherit from dict at all, or take your suggestion
and
> keep an auxiliary dict alongside the main one.
>
>From Python 2.x sources that I have lying around (sorry I have no idea
if the code for 3.x has changed much):
dict_init calls dict_update_common which does:
if (PyObject_HasAttrString(arg, "keys"))
result = PyDict_Merge(self, arg, 1);
else
result = PyDict_MergeFromSeq2(self, arg, 1);
PyDict_Merge says:
/* We accept for the argument either a concrete dictionary object,
* or an abstract "mapping" object. For the former, we can do
* things quite efficiently. For the latter, we only require that
* PyMapping_Keys() and PyObject_GetItem() be supported.
*/
which basically boils down to "if PyDict_Check() is true then iterate
directly over the structure and use the existing key, hash and value
fields to insert into the new dict".
If PyDict_Check() is false then it iterates over the keys and calls
PyObject_GetItem().
--
Duncan Booth http://kupuguy.blogspot.com
More information about the Python-list
mailing list