PyDict_Get/SetItem and dict subclasses
Hi, PyDict_GetItem() and PyDict_SetItem() don't call __getitem__ and __setitem__ for dict subclasses. Is there a reason for that? I found this surprising behaviour when I replaced a dict by a custom dict checking the key type on set. But my __setitem__ was not called because the function using the dict was implemented in C (and I didn't know that ;-)). Victor
2011/11/5 Victor Stinner
Hi,
PyDict_GetItem() and PyDict_SetItem() don't call __getitem__ and __setitem__ for dict subclasses. Is there a reason for that?
It's the same reason that PyUnicode_Concat doesn't call __add__ on unicode subclasses or PyList_Append doesn't call "append" on list subclasses. It's a concrete API. Code which expects subclasses should use PyObject_GetItem and friends, the abstract API. -- Regards, Benjamin
Hi Victor,
PyDict_GetItem() and PyDict_SetItem() don't call __getitem__ and __setitem__ for dict subclasses. Is there a reason for that?
http://bugs.python.org/issue10977 “Currently, the concrete object C API bypasses any methods defined on subclasses of builtin types.” Cheers
Le 05/11/2011 17:34, Éric Araujo a écrit :
Hi Victor,
PyDict_GetItem() and PyDict_SetItem() don't call __getitem__ and __setitem__ for dict subclasses. Is there a reason for that?
http://bugs.python.org/issue10977 “Currently, the concrete object C API bypasses any methods defined on subclasses of builtin types.”
I think that's the correct behaviour. If you expect to get an arbitrary mapping, just use the abstract API. You should use PyDict_GetItem when you know the object is exactly a dict (generally because you have created it yourself, or you know at least where and how it was created). Regards Antoine.
Am 06.11.2011 17:39, schrieb Antoine Pitrou:
Le 05/11/2011 17:34, Éric Araujo a écrit :
Hi Victor,
PyDict_GetItem() and PyDict_SetItem() don't call __getitem__ and __setitem__ for dict subclasses. Is there a reason for that?
http://bugs.python.org/issue10977 “Currently, the concrete object C API bypasses any methods defined on subclasses of builtin types.”
I think that's the correct behaviour. If you expect to get an arbitrary mapping, just use the abstract API. You should use PyDict_GetItem when you know the object is exactly a dict (generally because you have created it yourself, or you know at least where and how it was created).
If anybody has spare time at their hands, they should go through the code base and eliminate all uses of concrete API where it's not certain that the object really is of the base class (unless I missed that somebody already did, and that any remaining occurrences would be just minor bugs). Regards, Martin
On Nov 6, 2011, at 1:26 PM, Martin v. Löwis wrote:
Am 06.11.2011 17:39, schrieb Antoine Pitrou:
Le 05/11/2011 17:34, Éric Araujo a écrit :
Hi Victor,
PyDict_GetItem() and PyDict_SetItem() don't call __getitem__ and __setitem__ for dict subclasses. Is there a reason for that?
http://bugs.python.org/issue10977 “Currently, the concrete object C API bypasses any methods defined on subclasses of builtin types.”
I think that's the correct behaviour. If you expect to get an arbitrary mapping, just use the abstract API. You should use PyDict_GetItem when you know the object is exactly a dict (generally because you have created it yourself, or you know at least where and how it was created).
If anybody has spare time at their hands, they should go through the code base and eliminate all uses of concrete API where it's not certain that the object really is of the base class (unless I missed that somebody already did, and that any remaining occurrences would be just minor bugs).
Also check uses of PyList_SetItem and other uses of the concrete API. Raymond
participants (6)
-
"Martin v. Löwis"
-
Antoine Pitrou
-
Benjamin Peterson
-
Raymond Hettinger
-
Victor Stinner
-
Éric Araujo