[Python-Dev] tp_(get|set)attro? inheritance bug?
Brett
bac at OCF.Berkeley.EDU
Thu Jun 17 17:37:38 EDT 2004
Did an SF bug report ever get filed for this?
On Jun 11, 2004, at 10:58, Gustavo J. A. M. Carneiro wrote:
> Documentation says, regarding tp_getattr:
> «
> This field is inherited by subtypes together with tp_getattro: a
> subtype
> inherits both tp_getattr and tp_getattro from its base type when the
> subtype's tp_getattr and tp_getattro are both NULL.
> »
>
> Implementation disagrees, at least in cvs head, but the effect of the
> bug (non-inheritance of tp_getattr) happens in 2.3.3. Follow with me:
>
> In function type_new (typeobject.c) line 1927:
> /* Special case some slots */
> if (type->tp_dictoffset != 0 || nslots > 0) {
> if (base->tp_getattr == NULL && base->tp_getattro == NULL)
> type->tp_getattro = PyObject_GenericGetAttr;
> if (base->tp_setattr == NULL && base->tp_setattro == NULL)
> type->tp_setattro = PyObject_GenericSetAttr;
> }
> ...later in the same function... line
>
> /* Initialize the rest */
> if (PyType_Ready(type) < 0) {
> Py_DECREF(type);
> return NULL;
> }
>
> Inside PyType_Ready(), line 3208:
> for (i = 1; i < n; i++) {
> PyObject *b = PyTuple_GET_ITEM(bases, i);
> if (PyType_Check(b))
> inherit_slots(type, (PyTypeObject *)b);
> }
>
> Inside inherit_slots, line (3056):
> if (type->tp_getattr == NULL && type->tp_getattro == NULL) {
> type->tp_getattr = base->tp_getattr;
> type->tp_getattro = base->tp_getattro;
> }
> if (type->tp_setattr == NULL && type->tp_setattro == NULL) {
> type->tp_setattr = base->tp_setattr;
> type->tp_setattro = base->tp_setattro;
> }
>
> So, if you have followed through, you'll notice that type_new first
> sets tp_getattro = GenericGetAttr, in case 'base' has neither
> tp_getattr
> nor tp_getattro.
> So, you are thinking that there is no problem. If base has
> tp_getattr, that code path won't be execute. The problem is with
> multiple inheritance. In type_new, 'base' is determined by calling
> best_base(). But the selected base may not have tp_getattr, while
> another might have. In this case, setting tp_getattro based on
> information from the wrong base precludes the slot from being inherited
> from the right base. This is happening in pygtk, unfortunately.
>
> One possible solution would be to move the first code block to after
> the PyType_Ready() call.
>
> --
> Gustavo João Alves Marques Carneiro
> <gjc at inescporto.pt> <gustavo at users.sourceforge.net>
> The universe is always one step beyond logic.
>
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> http://mail.python.org/mailman/options/python-dev/brett%40python.org
More information about the Python-Dev
mailing list