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