[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.18,2.16.8.19

Guido van Rossum gvanrossum@users.sourceforge.net
2001年5月11日 14:51:37 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv22095
Modified Files:
 Tag: descr-branch
	typeobject.c 
Log Message:
Another cool feature: if a subtype of a built-in type defines a class
variable __slots__ (which must be a sequence of strings), it doesn't
have a __dict__, but instead it has named slots whose names are given
by the strings in the sequence. Setting __slots__ = [] implies the
subtype has no slots beyond those in the base class.
(I think subtypes of such subtypes must specifiy __slots__ = [] to
prevent adding a __dict__.)
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16.8.18
retrieving revision 2.16.8.19
diff -C2 -r2.16.8.18 -r2.16.8.19
*** typeobject.c	2001年05月11日 20:12:27	2.16.8.18
--- typeobject.c	2001年05月11日 21:51:35	2.16.8.19
***************
*** 126,131 ****
 staticforward void override_slots(PyTypeObject *type, PyObject *dict);
 
- #define NMEMBERS 1
- 
 typedef struct {
 	PyTypeObject type;
--- 126,129 ----
***************
*** 134,139 ****
 	PyMappingMethods as_mapping;
 	PyBufferProcs as_buffer;
! 	struct memberlist members[NMEMBERS+1];
! 	char name[1];
 } etype;
 
--- 132,137 ----
 	PyMappingMethods as_mapping;
 	PyBufferProcs as_buffer;
! 	PyObject *name, *slots;
! 	struct memberlist members[1];
 } etype;
 
***************
*** 142,151 ****
 type_construct(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
! 	char *name;
! 	PyObject *bases, *dict, *x;
 	PyTypeObject *base;
 	char *dummy = NULL;
 	etype *et;
 	struct memberlist *mp;
 
 	/* Check arguments */
--- 140,149 ----
 type_construct(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
! 	PyObject *name, *bases, *dict, *x, *slots;
 	PyTypeObject *base;
 	char *dummy = NULL;
 	etype *et;
 	struct memberlist *mp;
+ 	int i, nslots, slotoffset, allocsize;
 
 	/* Check arguments */
***************
*** 155,159 ****
 		return NULL;
 	}
! 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "sOO", &dummy,
 					 &name, &bases, &dict))
 		return NULL;
--- 153,157 ----
 		return NULL;
 	}
! 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", &dummy,
 					 &name, &bases, &dict))
 		return NULL;
***************
*** 180,195 ****
 	}
 
 	/* Allocate memory and construct a type object in it */
! 	et = PyObject_MALLOC(sizeof(etype) + strlen(name));
 	if (et == NULL)
 		return NULL;
! 	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;
 	type->tp_as_mapping = &et->as_mapping;
 	type->tp_as_buffer = &et->as_buffer;
! 	type->tp_name = strcpy(et->name, name);
 	type->tp_flags = Py_TPFLAGS_DEFAULT;
 
--- 178,223 ----
 	}
 
+ 	/* Check for a __slots__ sequence variable in dict, and count it */
+ 	slots = PyDict_GetItemString(dict, "__slots__");
+ 	nslots = 0;
+ 	if (slots != NULL) {
+ 		/* Make it into a tuple */
+ 		if (PyString_Check(slots))
+ 			slots = Py_BuildValue("(O)", slots);
+ 		else
+ 			slots = PySequence_Tuple(slots);
+ 		if (slots == NULL)
+ 			return NULL;
+ 		nslots = PyTuple_GET_SIZE(slots);
+ 		for (i = 0; i < nslots; i++) {
+ 			if (!PyString_Check(PyTuple_GET_ITEM(slots, i))) {
+ 				PyErr_SetString(PyExc_TypeError,
+ 				"__slots__ must be a sequence of strings");
+ 				Py_DECREF(slots);
+ 				return NULL;
+ 			}
+ 		}
+ 	}
+ 	if (slots == NULL && base->tp_dictoffset == 0 &&
+ 	 (base->tp_setattro == PyGeneric_SetAttr ||
+ 	 base->tp_setattro == NULL))
+ 		nslots = 1;
+ 
 	/* Allocate memory and construct a type object in it */
! 	allocsize = sizeof(etype) + nslots*sizeof(struct memberlist);
! 	et = PyObject_MALLOC(allocsize);
 	if (et == NULL)
 		return NULL;
! 	memset(et, '0円', allocsize);
 	type = &et->type;
 	PyObject_INIT(type, &PyDynamicType_Type);
+ 	Py_INCREF(name);
+ 	et->name = name;
+ 	et->slots = slots;
 	type->tp_as_number = &et->as_number;
 	type->tp_as_sequence = &et->as_sequence;
 	type->tp_as_mapping = &et->as_mapping;
 	type->tp_as_buffer = &et->as_buffer;
! 	type->tp_name = PyString_AS_STRING(name);
 	type->tp_flags = Py_TPFLAGS_DEFAULT;
 
***************
*** 216,235 ****
 	}
 
! 	/* Add a __dict__ slot if we don't already have one,
! 	 but only if the getattro is generic */
! 	if (type->tp_dictoffset == 0 &&
! 	 type->tp_setattro == PyGeneric_SetAttr) {
! 		int dictoffset = type->tp_basicsize;
! 		if (type->tp_flags & Py_TPFLAGS_GC)
! 			dictoffset -= PyGC_HEAD_SIZE;
! 		type->tp_dictoffset = dictoffset;
 		type->tp_basicsize += sizeof(PyObject *);
- 		mp = et->members;
 		mp->name = "__dict__";
 		mp->type = T_OBJECT;
! 		mp->offset = dictoffset;
 		mp->readonly = 1;
- 		add_members(type, mp);
 	}
 
 	x = PyObject_CallMethod(type->tp_dict, "update", "O", dict);
--- 244,270 ----
 	}
 
! 	/* Add custom slots */
! 	mp = et->members;
! 	slotoffset = type->tp_basicsize;
! 	if (type->tp_flags & Py_TPFLAGS_GC)
! 		slotoffset -= PyGC_HEAD_SIZE;
! 	if (slots != NULL) {
! 		for (i = 0; i < nslots; i++, mp++) {
! 			mp->name = PyString_AS_STRING(
! 				PyTuple_GET_ITEM(slots, i));
! 			mp->type = T_OBJECT;
! 			mp->offset = slotoffset + i*sizeof(PyObject *);
! 		}
! 		type->tp_basicsize += nslots*sizeof(PyObject *);
! 	}
! 	else if (nslots) {
! 		type->tp_dictoffset = slotoffset;
 		type->tp_basicsize += sizeof(PyObject *);
 		mp->name = "__dict__";
 		mp->type = T_OBJECT;
! 		mp->offset = slotoffset;
 		mp->readonly = 1;
 	}
+ 	add_members(type, et->members);
 
 	x = PyObject_CallMethod(type->tp_dict, "update", "O", dict);
***************
*** 311,316 ****
--- 346,355 ----
 dtype_dealloc(PyTypeObject *type)
 {
+ 	etype *et = (etype *)type;
+ 
 	Py_XDECREF(type->tp_base);
 	Py_XDECREF(type->tp_dict);
+ 	Py_XDECREF(et->name);
+ 	Py_XDECREF(et->slots);
 	PyObject_DEL(type);
 }
***************
*** 348,352 ****
 	type_members,				/* tp_members */
 	type_getsets,				/* tp_getset */
! 	0,					/* tp_base */
 	0,					/* tp_dict */
 	0,					/* tp_descr_get */
--- 387,391 ----
 	type_members,				/* tp_members */
 	type_getsets,				/* tp_getset */
! 	&PyType_Type,				/* tp_base */
 	0,					/* tp_dict */
 	0,					/* tp_descr_get */

AltStyle によって変換されたページ (->オリジナル) /