📄 typeobject.c
字号:
slots (in etype):
A tuple of strings can't be part of a cycle.
*/
CLEAR(type->tp_mro);
#undef CLEAR
return 0;
}
static int
type_is_gc(PyTypeObject *type)
{
return type->tp_flags & Py_TPFLAGS_HEAPTYPE;
}
#ifndef SYMBIAN
PyTypeObject PyType_Type = {
PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_PyType_Type = {
PyObject_HEAD_INIT(NULL)
#endif
0, /* ob_size */
"type", /* tp_name */
sizeof(etype), /* tp_basicsize */
sizeof(PyMemberDef), /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
type_compare, /* tp_compare */
(reprfunc)type_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)_Py_HashPointer, /* tp_hash */
(ternaryfunc)type_call, /* tp_call */
0, /* tp_str */
(getattrofunc)type_getattro, /* tp_getattro */
(setattrofunc)type_setattro, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
type_doc, /* tp_doc */
(traverseproc)type_traverse, /* tp_traverse */
(inquiry)type_clear, /* tp_clear */
0, /* tp_richcompare */
offsetof(PyTypeObject, tp_weaklist), /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
type_methods, /* tp_methods */
type_members, /* tp_members */
type_getsets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
type_new, /* tp_new */
_PyObject_GC_Del, /* tp_free */
(inquiry)type_is_gc, /* tp_is_gc */
};
/* The base type of all types (eventually)... except itself. */
static int
object_init(PyObject *self, PyObject *args, PyObject *kwds)
{
return 0;
}
static void
object_dealloc(PyObject *self)
{
self->ob_type->tp_free(self);
}
static PyObject *
object_repr(PyObject *self)
{
PyTypeObject *type;
PyObject *mod, *name, *rtn;
type = self->ob_type;
mod = type_module(type, NULL);
if (mod == NULL)
PyErr_Clear();
else if (!PyString_Check(mod)) {
Py_DECREF(mod);
mod = NULL;
}
name = type_name(type, NULL);
if (name == NULL)
return NULL;
if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__"))
rtn = PyString_FromFormat("<%s.%s object at %p>",
PyString_AS_STRING(mod),
PyString_AS_STRING(name),
self);
else
rtn = PyString_FromFormat("<%s object at %p>",
type->tp_name, self);
Py_XDECREF(mod);
Py_DECREF(name);
return rtn;
}
static PyObject *
object_str(PyObject *self)
{
unaryfunc f;
f = self->ob_type->tp_repr;
if (f == NULL)
f = object_repr;
return f(self);
}
static long
object_hash(PyObject *self)
{
return _Py_HashPointer(self);
}
static PyObject *
object_get_class(PyObject *self, void *closure)
{
Py_INCREF(self->ob_type);
return (PyObject *)(self->ob_type);
}
static int
equiv_structs(PyTypeObject *a, PyTypeObject *b)
{
return a == b ||
(a != NULL &&
b != NULL &&
a->tp_basicsize == b->tp_basicsize &&
a->tp_itemsize == b->tp_itemsize &&
a->tp_dictoffset == b->tp_dictoffset &&
a->tp_weaklistoffset == b->tp_weaklistoffset &&
((a->tp_flags & Py_TPFLAGS_HAVE_GC) ==
(b->tp_flags & Py_TPFLAGS_HAVE_GC)));
}
static int
same_slots_added(PyTypeObject *a, PyTypeObject *b)
{
PyTypeObject *base = a->tp_base;
int size;
if (base != b->tp_base)
return 0;
if (equiv_structs(a, base) && equiv_structs(b, base))
return 1;
size = base->tp_basicsize;
if (a->tp_dictoffset == size && b->tp_dictoffset == size)
size += sizeof(PyObject *);
if (a->tp_weaklistoffset == size && b->tp_weaklistoffset == size)
size += sizeof(PyObject *);
return size == a->tp_basicsize && size == b->tp_basicsize;
}
static int
object_set_class(PyObject *self, PyObject *value, void *closure)
{
PyTypeObject *old = self->ob_type;
PyTypeObject *new, *newbase, *oldbase;
if (value == NULL) {
PyErr_SetString(PyExc_TypeError,
"can't delete __class__ attribute");
return -1;
}
if (!PyType_Check(value)) {
PyErr_Format(PyExc_TypeError,
"__class__ must be set to new-style class, not '%s' object",
value->ob_type->tp_name);
return -1;
}
new = (PyTypeObject *)value;
newbase = new;
oldbase = old;
while (equiv_structs(newbase, newbase->tp_base))
newbase = newbase->tp_base;
while (equiv_structs(oldbase, oldbase->tp_base))
oldbase = oldbase->tp_base;
if (newbase != oldbase &&
(newbase->tp_base != oldbase->tp_base ||
!same_slots_added(newbase, oldbase))) {
PyErr_Format(PyExc_TypeError,
"__class__ assignment: "
"'%s' object layout differs from '%s'",
new->tp_name,
old->tp_name);
return -1;
}
if (new->tp_flags & Py_TPFLAGS_HEAPTYPE) {
Py_INCREF(new);
}
self->ob_type = new;
if (old->tp_flags & Py_TPFLAGS_HEAPTYPE) {
Py_DECREF(old);
}
return 0;
}
const static PyGetSetDef object_getsets[] = {
{"__class__", object_get_class, object_set_class,
"the object's class"},
{0}
};
static PyObject *
object_reduce(PyObject *self, PyObject *args)
{
/* Call copy_reg._reduce(self) */
#ifndef SYMBIAN
static PyObject *copy_reg_str;
#else
#define copy_reg_str (PYTHON_GLOBALS->copy_reg_str)
#endif
PyObject *copy_reg, *res;
if (!copy_reg_str) {
copy_reg_str = PyString_InternFromString("copy_reg");
if (copy_reg_str == NULL)
return NULL;
}
copy_reg = PyImport_Import(copy_reg_str);
if (!copy_reg)
return NULL;
res = PyEval_CallMethod(copy_reg, "_reduce", "(O)", self);
Py_DECREF(copy_reg);
return res;
}
const static PyMethodDef object_methods[] = {
{"__reduce__", object_reduce, METH_NOARGS, "helper for pickle"},
{0}
};
#ifndef SYMBIAN
PyTypeObject PyBaseObject_Type = {
PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_PyBaseObject_Type = {
PyObject_HEAD_INIT(NULL)
#endif
0, /* ob_size */
"object", /* tp_name */
sizeof(PyObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)object_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
object_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
object_hash, /* tp_hash */
0, /* tp_call */
object_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
"The most base type", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
object_methods, /* tp_methods */
0, /* tp_members */
object_getsets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
object_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
_PyObject_Del, /* tp_free */
};
/* Initialize the __dict__ in a type object */
static int
add_methods(PyTypeObject *type, PyMethodDef *meth)
{
PyObject *dict = type->tp_dict;
for (; meth->ml_name != NULL; meth++) {
PyObject *descr;
if (PyDict_GetItemString(dict, meth->ml_name))
continue;
descr = PyDescr_NewMethod(type, meth);
if (descr == NULL)
return -1;
if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
return -1;
Py_DECREF(descr);
}
return 0;
}
static int
add_members(PyTypeObject *type, PyMemberDef *memb)
{
PyObject *dict = type->tp_dict;
for (; memb->name != NULL; memb++) {
PyObject *descr;
if (PyDict_GetItemString(dict, memb->name))
continue;
descr = PyDescr_NewMember(type, memb);
if (descr == NULL)
return -1;
if (PyDict_SetItemString(dict, memb->name, descr) < 0)
return -1;
Py_DECREF(descr);
}
return 0;
}
static int
add_getset(PyTypeObject *type, PyGetSetDef *gsp)
{
PyObject *dict = type->tp_dict;
for (; gsp->name != NULL; gsp++) {
PyObject *descr;
if (PyDict_GetItemString(dict, gsp->name))
continue;
descr = PyDescr_NewGetSet(type, gsp);
if (descr == NULL)
return -1;
if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
return -1;
Py_DECREF(descr);
}
return 0;
}
static void
inherit_special(PyTypeObject *type, PyTypeObject *base)
{
int oldsize, newsize;
/* Special flag magic */
if (!type->tp_as_buffer && base->tp_as_buffer) {
type->tp_flags &= ~Py_TPFLAGS_HAVE_GETCHARBUFFER;
type->tp_flags |=
base->tp_flags & Py_TPFLAGS_HAVE_GETCHARBUFFER;
}
if (!type->tp_as_sequence && base->tp_as_sequence) {
type->tp_flags &= ~Py_TPFLAGS_HAVE_SEQUENCE_IN;
type->tp_flags |= base->tp_flags & Py_TPFLAGS_HAVE_SEQUENCE_IN;
}
if ((type->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS) !=
(base->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS)) {
if ((!type->tp_as_number && base->tp_as_number) ||
(!type->tp_as_sequence && base->tp_as_sequence)) {
type->tp_flags &= ~Py_TPFLAGS_HAVE_INPLACEOPS;
if (!type->tp_as_number && !type->tp_as_sequence) {
type->tp_flags |= base->tp_flags &
Py_TPFLAGS_HAVE_INPLACEOPS;
}
}
/* Wow */
}
if (!type->tp_as_number && base->tp_as_number) {
type->tp_flags &= ~Py_TPFLAGS_CHECKTYPES;
type->tp_flags |= base->tp_flags & Py_TPFLAGS_CHECKTYPES;
}
/* Copying basicsize is connected to the GC flags */
oldsize = base->tp_basicsize;
newsize = type->tp_basicsize ? type->tp_basicsize : oldsize;
if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC) &&
(base->tp_flags & Py_TPFLAGS_HAVE_GC) &&
(type->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE/*GC slots exist*/) &&
(!type->tp_traverse && !type->tp_clear)) {
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
if (type->tp_traverse == NULL)
type->tp_traverse = base->tp_traverse;
if (type->tp_clear == NULL)
type->tp_clear = base->tp_clear;
}
if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
/* The condition below could use some explanation.
It appears that tp_new is not inherited for static types
whose base class is 'object'; this seems to be a precaution
so that old extension types don't suddenly become
callable (object.__new__ wouldn't insure the invariants
that the extension type's own factory function ensures).
Heap types, of course, are under our control, so they do
inherit tp_new; static extension types that specify some
other built-in type as the default are considered
new-style-aware so they also inherit object.__new__. */
if (base != &PyBaseObject_Type ||
(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
if (type->tp_new == NULL)
type->tp_new = base->tp_new;
}
}
type->tp_basicsize = newsize;
/* Copy other non-function slots */
#undef COPYVAL
#define COPYVAL(SLOT) \
if (type->SLOT == 0) type->SLOT = base->SLOT
COPYVAL(tp_itemsize);
if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_WEAKREFS) {
COPYVAL(tp_weaklistoffset);
}
if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
COPYVAL(tp_dictoffset);
}
}
static void
inherit_slots(PyTypeObject *type, PyTypeObject *base)
{
PyTypeObject *basebase;
#undef SLOTDEFINED
#undef COPYSLOT
#undef COPYNUM
#undef COPYSEQ
#undef COPYMAP
#undef COPYBUF
#define SLOTDEFINED(SLOT) \
(base->SLOT != 0 && \
(basebase == NULL || base->SLOT != basebase->SLOT))
/* XXX:CW32 Ugly casting to avoid constness mismatch error. */
#define COPYSLOT(SLOT) \
if (!type->SLOT && SLOTDEFINED(SLOT)) *(void **)&type->SLOT = (void *)(base->SLOT)
#define COPYNUM(SLOT) COPYSLOT(tp_as_number->SLOT)
#define COPYSEQ(SLOT) COPYSLOT(tp_as_sequence->SLOT)
#define COPYMAP(SLOT) COPYSLOT(tp_as_mapping->SLOT)
#define COPYBUF(SLOT) COPYSLOT(tp_as_buffer->SLOT)
/* This won't inherit indirect slots (from tp_as_number etc.)
if type doesn't provide the space. */
if (type->tp_as_number != NULL && base->tp_as_number != NULL) {
basebase = base->tp_base;
if (basebase->tp_as_number == NULL)
basebase = NULL;
COPYNUM(nb_add);
COPYNUM(nb_subtract);
COPYNUM(nb_multiply);
COPYNUM(nb_divide);
COPYNUM(nb_remainder);
COPYNUM(nb_divmod);
COPYNUM(nb_power);
COPYNUM(nb_negative);
COPYNUM(nb_positive);
COPYNUM(nb_absolute);
COPYNUM(nb_nonzero);
COPYNUM(nb_invert);
COPYNUM(nb_lshift);
COPYNUM(nb_rshift);
COPYNUM(nb_and);
COPYNUM(nb_xor);
COPYNUM(nb_or);
COPYNUM(nb_coerce);
COPYNUM(nb_int);
COPYNUM(nb_long);
COPYNUM(nb_float);
COPYNUM(nb_oct);
COPYNUM(nb_hex);
COPYNUM(nb_inplace_add);
COPYNUM(nb_inplace_subtract);
COPYNUM(nb_inplace_multiply);
COPYNUM(nb_inplace_divide);
COPYNUM(nb_inplace_remainder);
COPYNUM(nb_inplace_power);
COPYNUM(nb_inplace_lshift);
COPYNUM(nb_inplace_rshift);
COPYNUM(nb_inplace_and);
COPYNUM(nb_inplace_xor);
COPYNUM(nb_inplace_or);
if (base->tp_flags & Py_TPFLAGS_CHECKTYPES) {
COPYNUM(nb_true_divide);
COPYNUM(nb_floor_divide);
COPYNUM(nb_inplace_true_divide);
COPYNUM(nb_inplace_floor_divide);
}
}
if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) {
basebase = base->tp_base;
if (basebase->tp_as_sequence == NULL)
basebase = NULL;
COPYSEQ(sq_length);
COPYSEQ(sq_concat);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -