Commit 84ff686d authored by Guido van Rossum's avatar Guido van Rossum

Clarifying code rearrangement and comments by David Abrahams. I've

got to admit that I haven't reviewed this carefully, but it looks okay
from 30,000 views, and doesn't break anything.  (SF patch 536407.)
parent de0aea0e
...@@ -1236,8 +1236,8 @@ static PyObject * ...@@ -1236,8 +1236,8 @@ static PyObject *
type_getattro(PyTypeObject *type, PyObject *name) type_getattro(PyTypeObject *type, PyObject *name)
{ {
PyTypeObject *metatype = type->ob_type; PyTypeObject *metatype = type->ob_type;
PyObject *descr, *res; PyObject *meta_attribute, *attribute;
descrgetfunc f; descrgetfunc meta_get;
/* Initialize this type (we'll assume the metatype is initialized) */ /* Initialize this type (we'll assume the metatype is initialized) */
if (type->tp_dict == NULL) { if (type->tp_dict == NULL) {
...@@ -1245,40 +1245,58 @@ type_getattro(PyTypeObject *type, PyObject *name) ...@@ -1245,40 +1245,58 @@ type_getattro(PyTypeObject *type, PyObject *name)
return NULL; return NULL;
} }
/* Get a descriptor from the metatype */ /* No readable descriptor found yet */
descr = _PyType_Lookup(metatype, name); meta_get = NULL;
f = NULL;
if (descr != NULL) { /* Look for the attribute in the metatype */
f = descr->ob_type->tp_descr_get; meta_attribute = _PyType_Lookup(metatype, name);
if (f != NULL && PyDescr_IsData(descr))
return f(descr, if (meta_attribute != NULL) {
(PyObject *)type, (PyObject *)metatype); 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);
}
} }
/* Look in tp_dict of this type and its bases */ /* No data descriptor found on metatype. Look in tp_dict of this
res = _PyType_Lookup(type, name); * type and its bases */
if (res != NULL) { attribute = _PyType_Lookup(type, name);
f = res->ob_type->tp_descr_get; if (attribute != NULL) {
if (f != NULL) /* Implement descriptor functionality, if any */
return f(res, (PyObject *)NULL, (PyObject *)type); descrgetfunc local_get = attribute->ob_type->tp_descr_get;
Py_INCREF(res); if (local_get != NULL) {
return res; /* 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;
} }
/* Use the descriptor from the metatype */ /* No attribute found in local __dict__ (or bases): use the
if (f != NULL) { * descriptor from the metatype, if any */
res = f(descr, (PyObject *)type, (PyObject *)metatype); if (meta_get != NULL)
return res; return meta_get(meta_attribute, (PyObject *)type,
} (PyObject *)metatype);
if (descr != NULL) {
Py_INCREF(descr); /* If an ordinary attribute was found on the metatype, return it now */
return descr; if (meta_attribute != NULL) {
Py_INCREF(meta_attribute);
return meta_attribute;
} }
/* Give up */ /* Give up */
PyErr_Format(PyExc_AttributeError, PyErr_Format(PyExc_AttributeError,
"type object '%.50s' has no attribute '%.400s'", "type object '%.50s' has no attribute '%.400s'",
type->tp_name, PyString_AS_STRING(name)); type->tp_name, PyString_AS_STRING(name));
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment