Issue536407
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2002-03-28 18:56 by david_abrahams, last changed 2022-04-10 16:05 by admin. This issue is now closed.
Files | ||||
---|---|---|---|---|
File name | Uploaded | Description | Edit | |
patch | david_abrahams, 2002-03-29 21:49 | patch contents |
Messages (5) | |||
---|---|---|---|
msg39401 - (view) | Author: David Abrahams (david_abrahams) | Date: 2002-03-28 18:56 | |
--- typeobject.c Mon Dec 17 12:14:22 2001 +++ typeobject.c.new Thu Mar 28 13:46:03 2002 @@ -1186,8 +1186,8 @@ type_getattro(PyTypeObject *type, PyObject *name) { PyTypeObject *metatype = type->ob_type; - PyObject *descr, *res; - descrgetfunc f; + PyObject *meta_attribute, *attribute; + descrgetfunc meta_get; /* Initialize this type (we'll assume the metatype is initialized) */ if (type->tp_dict == NULL) { @@ -1195,34 +1195,50 @@ return NULL; } - /* Get a descriptor from the metatype */ - descr = _PyType_Lookup(metatype, name); - f = NULL; - if (descr != NULL) { - f = descr->ob_type->tp_descr_get; - if (f != NULL && PyDescr_IsData (descr)) - return f(descr, - (PyObject *)type, (PyObject *)metatype); - } + /* No readable descriptor found yet */ + meta_get = NULL; + + /* Look for the attribute in the metatype */ + meta_attribute = _PyType_Lookup(metatype, name); - /* Look in tp_dict of this type and its bases */ - res = _PyType_Lookup(type, name); - if (res != NULL) { - f = res->ob_type->tp_descr_get; - if (f != NULL) - return f(res, (PyObject *) NULL, (PyObject *)type); - Py_INCREF(res); - return res; + if (meta_attribute != NULL) { + meta_get = meta_attribute->ob_type- >tp_descr_get; + + if (meta_get != NULL && PyDescr_IsData (meta_attribute)) { + /* Data descriptors implement tp_descr_set to intercept + * writes. Assume the attribute is not overridden in + * type's tp_dict (and bases): call the descriptor now. + */ + return meta_get (meta_attribute, + (PyObject *)type, (PyObject *)metatype); + } } - /* Use the descriptor from the metatype */ - if (f != NULL) { - res = f(descr, (PyObject *)type, (PyObject *)metatype); - return res; + /* No data descriptor found on metatype. Look in tp_dict of this + * type and its bases */ + attribute = _PyType_Lookup(type, name); + if (attribute != NULL) { + /* Implement descriptor functionality, if any */ + descrgetfunc local_get = attribute- >ob_type->tp_descr_get; + if (local_get != NULL) { + /* NULL 2nd argument indicates the descriptor was found on + * the target object itself (or a base) */ + return local_get(attribute, (PyObject *)NULL, (PyObject *)type); + } + + Py_INCREF(attribute); + return attribute; } - if (descr != NULL) { - Py_INCREF(descr); - return descr; + + /* No attribute found in local __dict__ (or bases): use the + * descriptor from the metatype, if any */ + if (meta_get != NULL) + return meta_get(meta_attribute, (PyObject *)type, (PyObject *)metatype); + + /* If an ordinary attribute was found on the metatype, return it now. */ + if (meta_attribute != NULL) { + Py_INCREF(meta_attribute); + return meta_attribute; } /* Give up */ |
|||
msg39402 - (view) | Author: David Abrahams (david_abrahams) | Date: 2002-03-29 21:22 | |
Logged In: YES user_id=52572 I have updated the patch so that it is made against the current sources. ------- --- typeobject.c Thu Mar 28 00:33:33 2002 +++ typeobject.c.new Fri Mar 29 16:20:12 2002 @@ -1237,8 +1237,8 @@ type_getattro(PyTypeObject *type, PyObject *name) { PyTypeObject *metatype = type->ob_type; - PyObject *descr, *res; - descrgetfunc f; + PyObject *meta_attribute, *attribute; + descrgetfunc meta_get; /* Initialize this type (we'll assume the metatype is initialized) */ if (type->tp_dict == NULL) { @@ -1246,40 +1246,56 @@ return NULL; } - /* Get a descriptor from the metatype */ - descr = _PyType_Lookup(metatype, name); - f = NULL; - if (descr != NULL) { - f = descr->ob_type->tp_descr_get; - if (f != NULL && PyDescr_IsData(descr)) - return f(descr, - (PyObject *)type, (PyObject *)metatype); - } + /* No readable descriptor found yet */ + meta_get = NULL; + + /* Look for the attribute in the metatype */ + meta_attribute = _PyType_Lookup(metatype, name); - /* Look in tp_dict of this type and its bases */ - res = _PyType_Lookup(type, name); - if (res != NULL) { - f = res->ob_type->tp_descr_get; - if (f != NULL) - return f(res, (PyObject *)NULL, (PyObject *)type); - Py_INCREF(res); - return res; + if (meta_attribute != NULL) { + meta_get = meta_attribute->ob_type- >tp_descr_get; + + if (meta_get != NULL && PyDescr_IsData (meta_attribute)) { + /* Data descriptors implement tp_descr_set to intercept + * writes. Assume the attribute is not overridden in + * type's tp_dict (and bases): call the descriptor now. + */ + return meta_get(meta_attribute, + (PyObject *)type, (PyObject *)metatype); + } } - /* Use the descriptor from the metatype */ - if (f != NULL) { - res = f(descr, (PyObject *)type, (PyObject *)metatype); - return res; + /* No data descriptor found on metatype. Look in tp_dict of this + * type and its bases */ + attribute = _PyType_Lookup(type, name); + if (attribute != NULL) { + /* Implement descriptor functionality, if any */ + descrgetfunc local_get = attribute- >ob_type->tp_descr_get; + if (local_get != NULL) { + /* NULL 2nd argument indicates the descriptor was found on + * the target object itself (or a base) */ + return local_get(attribute, (PyObject *)NULL, (PyObject *)type); + } + + Py_INCREF(attribute); + return attribute; } - if (descr != NULL) { - Py_INCREF(descr); - return descr; + + /* No attribute found in local __dict__ (or bases): use the + * descriptor from the metatype, if any */ + if (meta_get != NULL) + return meta_get(meta_attribute, (PyObject *)type, (PyObject *)metatype); + + /* If an ordinary attribute was found on the metatype, return it now. */ + if (meta_attribute != NULL) { + Py_INCREF(meta_attribute); + return meta_attribute; } /* Give up */ PyErr_Format(PyExc_AttributeError, - "type object '%.50s' has no attribute '%.400s'", - type->tp_name, PyString_AS_STRING (name)); + "type object '%.50s' has no attribute '%.400s'", + type->tp_name, PyString_AS_STRING (name)); return NULL; } |
|||
msg39403 - (view) | Author: Neil Schemenauer (nascheme) * ![]() |
Date: 2002-03-29 22:27 | |
Logged In: YES user_id=35752 Don't paste the patch in the comment box. |
|||
msg39404 - (view) | Author: David Abrahams (david_abrahams) | Date: 2002-03-29 22:30 | |
Logged In: YES user_id=52572 Thanks, Neil, I think I got the picture already (see Python-Dev). |
|||
msg39405 - (view) | Author: Guido van Rossum (gvanrossum) * ![]() |
Date: 2002-04-04 17:51 | |
Logged In: YES user_id=6380 Thanks, applied (after folding some long lines). Next time, please don't call the patch "patch". Call it something like "typeobject.patch". |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-10 16:05:10 | admin | set | github: 36348 |
2002-03-28 18:56:33 | david_abrahams | create |