[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.15,2.16.8.16
Guido van Rossum
gvanrossum@users.sourceforge.net
Thu, 10 May 2001 14:15:44 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv27865
Modified Files:
Tag: descr-branch
typeobject.c
Log Message:
Make attributes of subtypes writable, but only for dynamic subtypes
derived in Python using a class statement; static subtypes derived in
C still have read-only attributes.
The __dict__ is a read-only proxy in both cases (because the setattro
slot enforces certain invariants that could be broken by changing the
__dict__ directly).
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16.8.15
retrieving revision 2.16.8.16
diff -C2 -r2.16.8.15 -r2.16.8.16
*** typeobject.c 2001/05/10 16:55:42 2.16.8.15
--- typeobject.c 2001/05/10 21:15:42 2.16.8.16
***************
*** 97,110 ****
assert(PyString_Check(name));
! if (type->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
! if (type->tp_dict == NULL) {
! if (PyType_InitDict(type) < 0)
! return NULL;
! }
! descr = PyDict_GetItem(type->tp_dict, name);
! if (descr != NULL && PyDescr_IsMethod(descr) &&
! (f = descr->ob_type->tp_descr_get) != NULL)
! return (*f)(descr, NULL);
! }
if (tp->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
--- 97,107 ----
assert(PyString_Check(name));
! /* Complications: some attributes, like __class__ and __repr__, occur
! in the type's dict as well as in the metatype's dict. The
! descriptor in the type's dict is for attributes of its instances,
! while the descriptor in the metatype's dict is for the attributes
! of the type. Rule: if the descriptor found in the metatype's dict
! describes data, it wins; otherwise anything found in the type's
! dict wins. */
if (tp->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
***************
*** 114,118 ****
}
descr = PyDict_GetItem(tp->tp_dict, name);
! if (descr != NULL &&
(f = descr->ob_type->tp_descr_get) != NULL)
return (*f)(descr, (PyObject *)type);
--- 111,115 ----
}
descr = PyDict_GetItem(tp->tp_dict, name);
! if (descr != NULL && PyDescr_IsData(descr) &&
(f = descr->ob_type->tp_descr_get) != NULL)
return (*f)(descr, (PyObject *)type);
***************
*** 131,134 ****
--- 128,138 ----
}
+ if (tp->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
+ descr = PyDict_GetItem(tp->tp_dict, name);
+ if (descr != NULL &&
+ (f = descr->ob_type->tp_descr_get) != NULL)
+ return (*f)(descr, (PyObject *)type);
+ }
+
PyErr_Format(PyExc_AttributeError,
"type '%.50s' has no attribute '%.400s'",
***************
*** 267,271 ****
memset(et, '\0', sizeof(etype));
type = &et->type;
! PyObject_INIT(type, &PyType_Type);
type->tp_as_number = &et->as_number;
type->tp_as_sequence = &et->as_sequence;
--- 271,275 ----
memset(et, '\0', sizeof(etype));
type = &et->type;
! PyObject_INIT(type, &PyDynamicType_Type);
type->tp_as_number = &et->as_number;
type->tp_as_sequence = &et->as_sequence;
***************
*** 313,320 ****
return (PyObject *)type;
}
! /* Only for dynamic types, created by type_construct() above */
static void
! type_dealloc(PyTypeObject *type)
{
Py_XDECREF(type->tp_base);
--- 317,410 ----
return (PyObject *)type;
}
+
+ PyTypeObject PyType_Type = {
+ PyObject_HEAD_INIT(&PyTurtle_Type)
+ 0, /* Number of items for varobject */
+ "type", /* Name of this type */
+ sizeof(PyTypeObject), /* Basic object size */
+ 0, /* Item size for varobject */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)type_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ (ternaryfunc)type_call, /* tp_call */
+ 0, /* tp_str */
+ (getattrofunc)type_getattro, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ "Define the behavior of a particular type of object.", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ type_members, /* tp_members */
+ type_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ (ternaryfunc)type_construct, /* tp_construct */
+ };
! /* Support for dynamic types, created by type_construct() above */
!
! static int
! dtype_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
! {
! PyTypeObject *tp = type->ob_type; /* Usually == &PyDynamicType_Type */
!
! assert(PyString_Check(name));
!
! /* If the metatype has a descriptor this attribute with a
! descr_set slot, use it. This may fail for read-only attrs! */
! if (tp->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
! PyObject *descr;
! descrsetfunc f;
! if (tp->tp_dict == NULL) {
! if (PyType_InitDict(tp) < 0)
! return -1;
! }
! descr = PyDict_GetItem(tp->tp_dict, name);
! if (descr != NULL &&
! (f = descr->ob_type->tp_descr_set) != NULL)
! return (*f)(descr, (PyObject *)type, value);
! }
!
! /* If the type has a dict, store the value in it */
! if (type->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
! if (type->tp_dict == NULL) {
! if (PyType_InitDict(type) < 0)
! return -1;
! }
! if (value == NULL) {
! int res = PyObject_DelItem(type->tp_dict, name);
! if (res < 0 &&
! PyErr_ExceptionMatches(PyExc_KeyError))
! PyErr_SetObject(PyExc_AttributeError, name);
! return res;
! }
! else
! return PyObject_SetItem(type->tp_dict, name, value);
! }
!
! /* If the type has no dict, so we can't set attributes */
! PyErr_Format(PyExc_AttributeError,
! "type '%.50s' has no writable attribute '%.400s'",
! type->tp_name, PyString_AS_STRING(name));
! return -1;
! }
!
static void
! dtype_dealloc(PyTypeObject *type)
{
Py_XDECREF(type->tp_base);
***************
*** 323,333 ****
}
! PyTypeObject PyType_Type = {
PyObject_HEAD_INIT(&PyTurtle_Type)
0, /* Number of items for varobject */
! "type", /* Name of this type */
sizeof(PyTypeObject), /* Basic object size */
0, /* Item size for varobject */
! (destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
--- 413,423 ----
}
! PyTypeObject PyDynamicType_Type = {
PyObject_HEAD_INIT(&PyTurtle_Type)
0, /* Number of items for varobject */
! "dynamic-type", /* Name of this type */
sizeof(PyTypeObject), /* Basic object size */
0, /* Item size for varobject */
! (destructor)dtype_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
***************
*** 342,346 ****
0, /* tp_str */
(getattrofunc)type_getattro, /* tp_getattro */
! 0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
--- 432,436 ----
0, /* tp_str */
(getattrofunc)type_getattro, /* tp_getattro */
! (setattrofunc)dtype_setattro, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */