[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.41,2.16.8.42
Guido van Rossum
gvanrossum@users.sourceforge.net
Sun, 17 Jun 2001 16:28:33 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv30954
Modified Files:
Tag: descr-branch
typeobject.c
Log Message:
Test for the Py_TPFLAGS_BASETYPE flag.
Fold type_init() into type_new().
You can now instantiate object() again.
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16.8.41
retrieving revision 2.16.8.42
diff -C2 -r2.16.8.41 -r2.16.8.42
*** typeobject.c 2001/06/16 14:41:40 2.16.8.41
--- typeobject.c 2001/06/17 23:28:31 2.16.8.42
***************
*** 321,347 ****
}
! /* TypeType's initializer; called when a type is subclassed */
staticforward void object_dealloc(PyObject *);
staticforward int object_init(PyObject *, PyObject *, PyObject *);
! static int
! type_init(PyObject *self, PyObject *args, PyObject *kwds)
{
! PyObject *name, *bases, *dict, *slots;
! PyTypeObject *type, *base;
static char *kwlist[] = {"name", "bases", "dict", 0};
etype *et;
struct memberlist *mp;
! int i, nbases, nslots, slotoffset, allocsize;
!
! assert(PyType_Check(self));
! type = (PyTypeObject *)self;
! /* Check this is a virginal type object */
! if (type->tp_dict != NULL) {
! PyErr_SetString(PyExc_TypeError,
! "can't re-initialize type objects");
! return -1;
}
--- 321,386 ----
}
! static int
! extra_ivars(PyTypeObject *type, PyTypeObject *base)
! {
! int t_size = type->tp_basicsize;
! int b_size = base->tp_basicsize;
!
! assert((type->tp_flags & Py_TPFLAGS_GC) >=
! (base->tp_flags & Py_TPFLAGS_GC)); /* base has GC, type not! */
! if (type->tp_flags & Py_TPFLAGS_GC)
! t_size -= PyGC_HEAD_SIZE;
! if (base->tp_flags & Py_TPFLAGS_GC)
! b_size -= PyGC_HEAD_SIZE;
! assert(t_size >= b_size); /* type smaller than base! */
! if (type->tp_itemsize || base->tp_itemsize) {
! /* If itemsize is involved, stricter rules */
! return t_size != b_size ||
! type->tp_itemsize != base->tp_itemsize;
! }
! if (t_size == b_size)
! return 0;
! if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 &&
! type->tp_dictoffset == b_size &&
! t_size == b_size + sizeof(PyObject *))
! return 0; /* "Forgive" adding a __dict__ only */
! return 1;
! }
!
! static PyTypeObject *
! solid_base(PyTypeObject *type)
! {
! PyTypeObject *base;
+ if (type->tp_base)
+ base = solid_base(type->tp_base);
+ else
+ base = &PyBaseObject_Type;
+ if (extra_ivars(type, base))
+ return type;
+ else
+ return base;
+ }
+
staticforward void object_dealloc(PyObject *);
staticforward int object_init(PyObject *, PyObject *, PyObject *);
! static PyObject *
! type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
{
! PyObject *name, *bases, *dict;
static char *kwlist[] = {"name", "bases", "dict", 0};
+ PyObject *slots;
+ PyTypeObject *type, *base;
etype *et;
struct memberlist *mp;
! int i, nbases, nslots, slotoffset;
! if (PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
! (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) {
! /* type(x) -> x.__class__ */
! PyObject *x = PyTuple_GET_ITEM(args, 0);
! Py_INCREF(x->ob_type);
! return (PyObject *) x->ob_type;
}
***************
*** 349,357 ****
if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist,
&name, &bases, &dict))
! return -1;
! if (!PyTuple_Check(bases) || !PyDict_Check(dict)) {
! PyErr_SetString(PyExc_TypeError,
! "usage: type(name, bases, dict) ");
! return -1;
}
--- 388,410 ----
if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist,
&name, &bases, &dict))
! return NULL;
! if (PyTuple_Check(bases)) {
! int i, n;
! n = PyTuple_GET_SIZE(bases);
! for (i = 0; i < n; i++) {
! PyObject *base_i = PyTuple_GET_ITEM(bases, i);
! PyTypeObject *type_i = base_i->ob_type;
! if (issubtype(metatype, type_i))
! continue;
! if (issubtype(type_i, metatype)) {
! metatype = type_i;
! continue;
! }
! PyErr_SetString(PyExc_TypeError,
! "metaclass conflict among bases");
! return NULL;
! }
! if (metatype->tp_new != type_new)
! return metatype->tp_new(metatype, args, kwds);
}
***************
*** 361,365 ****
bases = Py_BuildValue("(O)", &PyBaseObject_Type);
if (bases == NULL)
! return -1;
nbases = 1;
}
--- 414,418 ----
bases = Py_BuildValue("(O)", &PyBaseObject_Type);
if (bases == NULL)
! return NULL;
nbases = 1;
}
***************
*** 370,387 ****
base = best_base(bases);
if (base == NULL)
! return -1;
! if (base->tp_init == NULL && base != &PyBaseObject_Type) {
! PyErr_SetString(PyExc_TypeError,
! "base type must have a constructor slot");
! return -1;
}
- /* Set tp_base and tp_bases */
- type->tp_bases = bases;
- Py_INCREF(base);
- type->tp_base = base;
-
/* Check for a __slots__ sequence variable in dict, and count it */
- /* XXX This should move to type_alloc() */
slots = PyDict_GetItemString(dict, "__slots__");
nslots = 0;
--- 423,435 ----
base = best_base(bases);
if (base == NULL)
! return NULL;
! if (!PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) {
! PyErr_Format(PyExc_TypeError,
! "type '%.100s' is not an acceptable base type",
! base->tp_name);
! return NULL;
}
/* Check for a __slots__ sequence variable in dict, and count it */
slots = PyDict_GetItemString(dict, "__slots__");
nslots = 0;
***************
*** 393,397 ****
slots = PySequence_Tuple(slots);
if (slots == NULL)
! return -1;
nslots = PyTuple_GET_SIZE(slots);
for (i = 0; i < nslots; i++) {
--- 441,445 ----
slots = PySequence_Tuple(slots);
if (slots == NULL)
! return NULL;
nslots = PyTuple_GET_SIZE(slots);
for (i = 0; i < nslots; i++) {
***************
*** 400,404 ****
"__slots__ must be a sequence of strings");
Py_DECREF(slots);
! return -1;
}
}
--- 448,452 ----
"__slots__ must be a sequence of strings");
Py_DECREF(slots);
! return NULL;
}
}
***************
*** 409,427 ****
nslots = 1;
! /* Check allocation size and initialize the type object */
! allocsize = sizeof(etype) + nslots*sizeof(struct memberlist);
! if (type->ob_type->tp_basicsize < allocsize) {
! PyErr_Format(
! PyExc_SystemError,
! "insufficient allocated memory for subtype: "
! "allocated %d, needed %d",
! type->ob_type->tp_basicsize,
! allocsize);
! return -1;
! }
et = (etype *)type;
Py_INCREF(name);
et->name = name;
et->slots = slots;
type->tp_as_number = &et->as_number;
type->tp_as_sequence = &et->as_sequence;
--- 457,474 ----
nslots = 1;
! /* Allocate the type object */
! type = (PyTypeObject *)metatype->tp_alloc(metatype, nslots);
! if (type == NULL)
! return NULL;
!
! /* Keep name and slots alive in the extended type object */
et = (etype *)type;
Py_INCREF(name);
et->name = name;
et->slots = slots;
+
+ /* Initialize essential fields */
+ type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE |
+ Py_TPFLAGS_BASETYPE;
type->tp_as_number = &et->as_number;
type->tp_as_sequence = &et->as_sequence;
***************
*** 430,437 ****
type->tp_name = PyString_AS_STRING(name);
/* Initialize tp_introduced from passed-in dict */
type->tp_introduced = dict = PyDict_Copy(dict);
if (dict == NULL)
! return -1;
/* Add descriptors for custom slots from __slots__, or for __dict__ */
--- 477,489 ----
type->tp_name = PyString_AS_STRING(name);
+ /* Set tp_base and tp_bases */
+ type->tp_bases = bases;
+ Py_INCREF(base);
+ type->tp_base = base;
+
/* Initialize tp_introduced from passed-in dict */
type->tp_introduced = dict = PyDict_Copy(dict);
if (dict == NULL)
! return NULL;
/* Add descriptors for custom slots from __slots__, or for __dict__ */
***************
*** 467,584 ****
type->tp_setattro = PyObject_GenericSetAttr;
}
- if (base->tp_dealloc == NULL)
- type->tp_dealloc = object_dealloc;
- else
- type->tp_dealloc = subtype_dealloc;
if (base->tp_new == NULL)
type->tp_new = PyType_GenericNew;
if (base->tp_alloc == NULL)
type->tp_alloc = PyType_GenericAlloc;
- if (base->tp_init == NULL)
- type->tp_init = object_init;
/* Initialize the rest */
if (PyType_InitDict(type) < 0)
! return -1;
/* Override slots that deserve it */
override_slots(type, type->tp_dict);
- return 0;
- }
-
- static int
- extra_ivars(PyTypeObject *type, PyTypeObject *base)
- {
- int t_size = type->tp_basicsize;
- int b_size = base->tp_basicsize;
-
- assert((type->tp_flags & Py_TPFLAGS_GC) >=
- (base->tp_flags & Py_TPFLAGS_GC)); /* base has GC, type not! */
- if (type->tp_flags & Py_TPFLAGS_GC)
- t_size -= PyGC_HEAD_SIZE;
- if (base->tp_flags & Py_TPFLAGS_GC)
- b_size -= PyGC_HEAD_SIZE;
- assert(t_size >= b_size); /* type smaller than base! */
- if (type->tp_itemsize || base->tp_itemsize) {
- /* If itemsize is involved, stricter rules */
- return t_size != b_size ||
- type->tp_itemsize != base->tp_itemsize;
- }
- if (t_size == b_size)
- return 0;
- if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 &&
- type->tp_dictoffset == b_size &&
- t_size == b_size + sizeof(PyObject *))
- return 0; /* "Forgive" adding a __dict__ only */
- return 1;
- }
-
- static PyTypeObject *
- solid_base(PyTypeObject *type)
- {
- PyTypeObject *base;
-
- if (type->tp_base)
- base = solid_base(type->tp_base);
- else
- base = &PyBaseObject_Type;
- if (extra_ivars(type, base))
- return type;
- else
- return base;
- }
-
- static PyObject *
- type_alloc(PyTypeObject *metatype, int nitems)
- {
- PyTypeObject *type;
-
- type = (PyTypeObject *)PyType_GenericAlloc(metatype, nitems);
- if (type != NULL)
- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
return (PyObject *)type;
}
static PyObject *
- type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
- {
- PyObject *name, *bases, *dict;
- static char *kwlist[] = {"name", "bases", "dict", 0};
-
- if (PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
- (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) {
- /* type(x) -> x.__class__ */
- PyObject *x = PyTuple_GET_ITEM(args, 0);
- Py_INCREF(x->ob_type);
- return (PyObject *) x->ob_type;
- }
-
- /* Check arguments (again?!?! yes, alas -- we need the bases!) */
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist,
- &name, &bases, &dict))
- return NULL;
- if (PyTuple_Check(bases)) {
- int i, n;
- n = PyTuple_GET_SIZE(bases);
- for (i = 0; i < n; i++) {
- PyObject *base_i = PyTuple_GET_ITEM(bases, i);
- PyTypeObject *type_i = base_i->ob_type;
- if (issubtype(metatype, type_i))
- continue;
- if (issubtype(type_i, metatype)) {
- metatype = type_i;
- continue;
- }
- PyErr_SetString(PyExc_TypeError,
- "metaclass conflict among bases");
- return NULL;
- }
- if (metatype->tp_new != type_new)
- return metatype->tp_new(metatype, args, kwds);
- }
- return PyType_GenericNew(metatype, args, kwds);
- }
-
- static PyObject *
type_getattro(PyTypeObject *type, PyObject *name)
{
--- 519,537 ----
type->tp_setattro = PyObject_GenericSetAttr;
}
if (base->tp_new == NULL)
type->tp_new = PyType_GenericNew;
if (base->tp_alloc == NULL)
type->tp_alloc = PyType_GenericAlloc;
/* Initialize the rest */
if (PyType_InitDict(type) < 0)
! return NULL;
/* Override slots that deserve it */
override_slots(type, type->tp_dict);
return (PyObject *)type;
}
static PyObject *
type_getattro(PyTypeObject *type, PyObject *name)
{
***************
*** 614,619 ****
0, /* ob_size */
"type", /* tp_name */
! sizeof(etype) + sizeof(struct memberlist), /* tp_basicsize */
! 0, /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */
--- 567,572 ----
0, /* ob_size */
"type", /* tp_name */
! sizeof(etype), /* tp_basicsize */
! sizeof(struct memberlist), /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */
***************
*** 631,635 ****
0, /* tp_setattro */
0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT, /* tp_flags */
type_doc, /* tp_doc */
0, /* tp_traverse */
--- 584,588 ----
0, /* tp_setattro */
0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
type_doc, /* tp_doc */
0, /* tp_traverse */
***************
*** 647,652 ****
0, /* tp_descr_set */
offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */
! type_init, /* tp_init */
! type_alloc, /* tp_alloc */
type_new, /* tp_new */
};
--- 600,605 ----
0, /* tp_descr_set */
offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */
! 0, /* tp_init */
! PyType_GenericAlloc, /* tp_alloc */
type_new, /* tp_new */
};
***************
*** 678,682 ****
sizeof(PyObject), /* tp_basicsize */
0, /* tp_itemsize */
! 0/*(destructor)object_dealloc*/, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
--- 631,635 ----
sizeof(PyObject), /* tp_basicsize */
0, /* tp_itemsize */
! (destructor)object_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
***************
*** 693,697 ****
0, /* tp_setattro */
0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT, /* tp_flags */
"The most base type", /* tp_doc */
0, /* tp_traverse */
--- 646,650 ----
0, /* tp_setattro */
0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
"The most base type", /* tp_doc */
0, /* tp_traverse */
***************
*** 709,715 ****
0, /* tp_descr_set */
0, /* tp_dictoffset */
! 0, /* tp_init */
! 0, /* tp_alloc */
! 0, /* tp_new */
};
--- 662,668 ----
0, /* tp_descr_set */
0, /* tp_dictoffset */
! object_init, /* tp_init */
! PyType_GenericAlloc, /* tp_alloc */
! PyType_GenericNew, /* tp_new */
};