📄 classobject.c
字号:
return 0;
cp = (PyClassObject *)class;
n = PyTuple_Size(cp->cl_bases);
for (i = 0; i < n; i++) {
if (PyClass_IsSubclass(PyTuple_GetItem(cp->cl_bases, i), base))
return 1;
}
return 0;
}
/* Instance objects */
DL_EXPORT(PyObject *)
PyInstance_NewRaw(PyObject *klass, PyObject *dict)
{
PyInstanceObject *inst;
if (!PyClass_Check(klass)) {
PyErr_BadInternalCall();
return NULL;
}
if (dict == NULL) {
dict = PyDict_New();
if (dict == NULL)
return NULL;
}
else {
if (!PyDict_Check(dict)) {
PyErr_BadInternalCall();
return NULL;
}
Py_INCREF(dict);
}
inst = PyObject_GC_New(PyInstanceObject, &PyInstance_Type);
if (inst == NULL) {
Py_DECREF(dict);
return NULL;
}
inst->in_weakreflist = NULL;
Py_INCREF(klass);
inst->in_class = (PyClassObject *)klass;
inst->in_dict = dict;
_PyObject_GC_TRACK(inst);
return (PyObject *)inst;
}
DL_EXPORT(PyObject *)
PyInstance_New(PyObject *klass, PyObject *arg, PyObject *kw)
{
register PyInstanceObject *inst;
PyObject *init;
#ifndef SYMBIAN
static PyObject *initstr;
#else
SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#define initstr (pyglobals->initstr)
#endif
inst = (PyInstanceObject *) PyInstance_NewRaw(klass, NULL);
if (inst == NULL)
return NULL;
if (initstr == NULL)
initstr = PyString_InternFromString("__init__");
init = instance_getattr2(inst, initstr);
if (init == NULL) {
if ((arg != NULL && (!PyTuple_Check(arg) ||
PyTuple_Size(arg) != 0))
|| (kw != NULL && (!PyDict_Check(kw) ||
PyDict_Size(kw) != 0))) {
PyErr_SetString(PyExc_TypeError,
"this constructor takes no arguments");
Py_DECREF(inst);
inst = NULL;
}
}
else {
PyObject *res = PyEval_CallObjectWithKeywords(init, arg, kw);
Py_DECREF(init);
if (res == NULL) {
Py_DECREF(inst);
inst = NULL;
}
else {
if (res != Py_None) {
PyErr_SetString(PyExc_TypeError,
"__init__() should return None");
Py_DECREF(inst);
inst = NULL;
}
Py_DECREF(res);
}
}
return (PyObject *)inst;
}
/* Instance methods */
static void
instance_dealloc(register PyInstanceObject *inst)
{
PyObject *error_type, *error_value, *error_traceback;
PyObject *del;
#ifndef SYMBIAN
static PyObject *delstr;
#else
SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#define delstr (pyglobals->delstr)
#endif
#ifdef Py_REF_DEBUG
extern long _Py_RefTotal;
#endif
_PyObject_GC_UNTRACK(inst);
if (inst->in_weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) inst);
/* Temporarily resurrect the object. */
#ifdef Py_TRACE_REFS
#ifndef Py_REF_DEBUG
# error "Py_TRACE_REFS defined but Py_REF_DEBUG not."
#endif
/* much too complicated if Py_TRACE_REFS defined */
inst->ob_type = &PyInstance_Type;
_Py_NewReference((PyObject *)inst);
#ifdef COUNT_ALLOCS
/* compensate for boost in _Py_NewReference; note that
* _Py_RefTotal was also boosted; we'll knock that down later.
*/
inst->ob_type->tp_allocs--;
#endif
#else /* !Py_TRACE_REFS */
/* Py_INCREF boosts _Py_RefTotal if Py_REF_DEBUG is defined */
Py_INCREF(inst);
#endif /* !Py_TRACE_REFS */
/* Save the current exception, if any. */
PyErr_Fetch(&error_type, &error_value, &error_traceback);
/* Execute __del__ method, if any. */
if (delstr == NULL)
delstr = PyString_InternFromString("__del__");
if ((del = instance_getattr2(inst, delstr)) != NULL) {
PyObject *res = PyEval_CallObject(del, (PyObject *)NULL);
if (res == NULL)
PyErr_WriteUnraisable(del);
else
Py_DECREF(res);
Py_DECREF(del);
}
/* Restore the saved exception. */
PyErr_Restore(error_type, error_value, error_traceback);
/* Undo the temporary resurrection; can't use DECREF here, it would
* cause a recursive call.
*/
#ifdef Py_REF_DEBUG
/* _Py_RefTotal was boosted either by _Py_NewReference or
* Py_INCREF above.
*/
_Py_RefTotal--;
#endif
if (--inst->ob_refcnt > 0) {
#ifdef COUNT_ALLOCS
inst->ob_type->tp_frees--;
#endif
_PyObject_GC_TRACK(inst);
return; /* __del__ added a reference; don't delete now */
}
#ifdef Py_TRACE_REFS
_Py_ForgetReference((PyObject *)inst);
#ifdef COUNT_ALLOCS
/* compensate for increment in _Py_ForgetReference */
inst->ob_type->tp_frees--;
#endif
#ifndef WITH_CYCLE_GC
inst->ob_type = NULL;
#endif
#endif
Py_DECREF(inst->in_class);
Py_XDECREF(inst->in_dict);
PyObject_GC_Del(inst);
}
static PyObject *
instance_getattr1(register PyInstanceObject *inst, PyObject *name)
{
register PyObject *v;
register char *sname = PyString_AsString(name);
if (sname[0] == '_' && sname[1] == '_') {
if (strcmp(sname, "__dict__") == 0) {
if (PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
"instance.__dict__ not accessible in restricted mode");
return NULL;
}
Py_INCREF(inst->in_dict);
return inst->in_dict;
}
if (strcmp(sname, "__class__") == 0) {
Py_INCREF(inst->in_class);
return (PyObject *)inst->in_class;
}
}
v = instance_getattr2(inst, name);
if (v == NULL) {
PyErr_Format(PyExc_AttributeError,
"%.50s instance has no attribute '%.400s'",
PyString_AS_STRING(inst->in_class->cl_name), sname);
}
return v;
}
static PyObject *
instance_getattr2(register PyInstanceObject *inst, PyObject *name)
{
register PyObject *v;
PyClassObject *class;
descrgetfunc f;
v = PyDict_GetItem(inst->in_dict, name);
if (v != NULL) {
Py_INCREF(v);
return v;
}
v = class_lookup(inst->in_class, name, &class);
if (v != NULL) {
Py_INCREF(v);
f = TP_DESCR_GET(v->ob_type);
if (f != NULL) {
PyObject *w = f(v, (PyObject *)inst,
(PyObject *)(inst->in_class));
Py_DECREF(v);
v = w;
}
}
return v;
}
static PyObject *
instance_getattr(register PyInstanceObject *inst, PyObject *name)
{
register PyObject *func, *res;
res = instance_getattr1(inst, name);
if (res == NULL && (func = inst->in_class->cl_getattr) != NULL) {
PyObject *args;
PyErr_Clear();
args = Py_BuildValue("(OO)", inst, name);
if (args == NULL)
return NULL;
res = PyEval_CallObject(func, args);
Py_DECREF(args);
}
return res;
}
static int
instance_setattr1(PyInstanceObject *inst, PyObject *name, PyObject *v)
{
if (v == NULL) {
int rv = PyDict_DelItem(inst->in_dict, name);
if (rv < 0)
PyErr_Format(PyExc_AttributeError,
"%.50s instance has no attribute '%.400s'",
PyString_AS_STRING(inst->in_class->cl_name),
PyString_AS_STRING(name));
return rv;
}
else
return PyDict_SetItem(inst->in_dict, name, v);
}
static int
instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v)
{
PyObject *func, *args, *res, *tmp;
char *sname = PyString_AsString(name);
if (sname[0] == '_' && sname[1] == '_') {
int n = PyString_Size(name);
if (sname[n-1] == '_' && sname[n-2] == '_') {
if (strcmp(sname, "__dict__") == 0) {
if (PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
"__dict__ not accessible in restricted mode");
return -1;
}
if (v == NULL || !PyDict_Check(v)) {
PyErr_SetString(PyExc_TypeError,
"__dict__ must be set to a dictionary");
return -1;
}
tmp = inst->in_dict;
Py_INCREF(v);
inst->in_dict = v;
Py_DECREF(tmp);
return 0;
}
if (strcmp(sname, "__class__") == 0) {
if (PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
"__class__ not accessible in restricted mode");
return -1;
}
if (v == NULL || !PyClass_Check(v)) {
PyErr_SetString(PyExc_TypeError,
"__class__ must be set to a class");
return -1;
}
tmp = (PyObject *)(inst->in_class);
Py_INCREF(v);
inst->in_class = (PyClassObject *)v;
Py_DECREF(tmp);
return 0;
}
}
}
if (v == NULL)
func = inst->in_class->cl_delattr;
else
func = inst->in_class->cl_setattr;
if (func == NULL)
return instance_setattr1(inst, name, v);
if (v == NULL)
args = Py_BuildValue("(OO)", inst, name);
else
args = Py_BuildValue("(OOO)", inst, name, v);
if (args == NULL)
return -1;
res = PyEval_CallObject(func, args);
Py_DECREF(args);
if (res == NULL)
return -1;
Py_DECREF(res);
return 0;
}
static PyObject *
instance_repr(PyInstanceObject *inst)
{
PyObject *func;
PyObject *res;
#ifndef SYMBIAN
static PyObject *reprstr;
#else
SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#define reprstr (pyglobals->reprstr)
#endif
if (reprstr == NULL)
reprstr = PyString_InternFromString("__repr__");
func = instance_getattr(inst, reprstr);
if (func == NULL) {
PyObject *classname = inst->in_class->cl_name;
PyObject *mod = PyDict_GetItemString(
inst->in_class->cl_dict, "__module__");
char *cname;
if (classname != NULL && PyString_Check(classname))
cname = PyString_AsString(classname);
else
cname = "?";
PyErr_Clear();
if (mod == NULL || !PyString_Check(mod))
return PyString_FromFormat("<?.%s instance at %p>",
cname, inst);
else
return PyString_FromFormat("<%s.%s instance at %p>",
PyString_AsString(mod),
cname, inst);
}
res = PyEval_CallObject(func, (PyObject *)NULL);
Py_DECREF(func);
return res;
}
static PyObject *
instance_str(PyInstanceObject *inst)
{
PyObject *func;
PyObject *res;
#ifndef SYMBIAN
static PyObject *strstr;
#else
SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#define strstr (pyglobals->strstr)
#endif
if (strstr == NULL)
strstr = PyString_InternFromString("__str__");
func = instance_getattr(inst, strstr);
if (func == NULL) {
PyErr_Clear();
return instance_repr(inst);
}
res = PyEval_CallObject(func, (PyObject *)NULL);
Py_DECREF(func);
return res;
}
static long
instance_hash(PyInstanceObject *inst)
{
PyObject *func;
PyObject *res;
long outcome;
#ifndef SYMBIAN
static PyObject *hashstr, *eqstr, *cmpstr;
#else
SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#define hashstr (pyglobals->hashstr)
#define eqstr (pyglobals->eqstr)
#define cmpstr (pyglobals->cmpstr)
#endif
if (hashstr == NULL)
hashstr = PyString_InternFromString("__hash__");
func = instance_getattr(inst, hashstr);
if (func == NULL) {
/* If there is no __eq__ and no __cmp__ method, we hash on the
address. If an __eq__ or __cmp__ method exists, there must
be a __hash__. */
PyErr_Clear();
if (eqstr == NULL)
eqstr = PyString_InternFromString("__eq__");
func = instance_getattr(inst, eqstr);
if (func == NULL) {
PyErr_Clear();
if (cmpstr == NULL)
cmpstr = PyString_InternFromString("__cmp__");
func = instance_getattr(inst, cmpstr);
if (func == NULL) {
PyErr_Clear();
return _Py_HashPointer(inst);
}
}
PyErr_SetString(PyExc_TypeError, "unhashable instance");
return -1;
}
res = PyEval_CallObject(func, (PyObject *)NULL);
Py_DECREF(func);
if (res == NULL)
return -1;
if (PyInt_Check(res)) {
outcome = PyInt_AsLong(res);
if (outcome == -1)
outcome = -2;
}
else {
PyErr_SetString(PyExc_TypeError,
"__hash__() should return an int");
outcome = -1;
}
Py_DECREF(res);
return outcome;
}
static int
instance_traverse(PyInstanceObject *o, visitproc visit, void *arg)
{
int err;
if (o->in_class) {
err = visit((PyObject *)(o->in_class), arg);
if (err)
return err;
}
if (o->in_dict) {
err = visit(o->in_dict, arg);
if (err)
return err;
}
return 0;
}
#ifndef SYMBIAN
static PyObject *getitemstr, *setitemstr, *delitemstr, *lenstr;
static PyObject *iterstr, *nextstr;
#else
#define getitemstr (pyglobals->getitemstr)
#define setitemstr (pyglobals->setitemstr)
#define delitemstr (pyglobals->delitemstr)
#define lenstr (pyglobals->lenstr)
#define iterstr (pyglobals->iterstr)
#define nextstr (pyglobals->nextstr)
#endif
static int
instance_length(PyInstanceObject *inst)
{
PyObject *func;
PyObject *res;
int outcome;
#ifdef SYMBIAN
SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#endif
if (lenstr == NULL)
lenstr = PyString_InternFromString("__len__");
func = instance_getattr(inst, lenstr);
if (func == NULL)
return -1;
res = PyEval_CallObject(func, (PyObject *)NULL);
Py_DECREF(func);
if (res == NULL)
return -1;
if (PyInt_Check(res)) {
outcome = PyInt_AsLong(res);
if (outcome < 0)
PyErr_SetString(PyExc_ValueError,
"__len__() should return >= 0");
}
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -