⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classobject.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		PyErr_Format(PyExc_AttributeError,
			     "%.200s instance has no __call__ method",
			     PyString_AsString(inst->in_class->cl_name));
		return NULL;
	}
	/* We must check and increment the recursion depth here. Scenario:
	       class A:
	           pass
	       A.__call__ = A() # that's right
	       a = A() # ok
	       a() # infinite recursion
	   This bounces between instance_call() and PyObject_Call() without
	   ever hitting eval_frame() (which has the main recursion check). */
	if (tstate->recursion_depth++ > Py_GetRecursionLimit()) {
		PyErr_SetString(PyExc_RuntimeError,
				"maximum __call__ recursion depth exceeded");
		res = NULL;
	}
	else
		res = PyObject_Call(call, arg, kw);
	tstate->recursion_depth--;
	Py_DECREF(call);
	return res;
}


const static PyNumberMethods instance_as_number = {
	(binaryfunc)instance_add,		/* nb_add */
	(binaryfunc)instance_sub,		/* nb_subtract */
	(binaryfunc)instance_mul,		/* nb_multiply */
	(binaryfunc)instance_div,		/* nb_divide */
	(binaryfunc)instance_mod,		/* nb_remainder */
	(binaryfunc)instance_divmod,		/* nb_divmod */
	(ternaryfunc)instance_pow,		/* nb_power */
	(unaryfunc)instance_neg,		/* nb_negative */
	(unaryfunc)instance_pos,		/* nb_positive */
	(unaryfunc)instance_abs,		/* nb_absolute */
	(inquiry)instance_nonzero,		/* nb_nonzero */
	(unaryfunc)instance_invert,		/* nb_invert */
	(binaryfunc)instance_lshift,		/* nb_lshift */
	(binaryfunc)instance_rshift,		/* nb_rshift */
	(binaryfunc)instance_and,		/* nb_and */
	(binaryfunc)instance_xor,		/* nb_xor */
	(binaryfunc)instance_or,		/* nb_or */
	(coercion)instance_coerce,		/* nb_coerce */
	(unaryfunc)instance_int,		/* nb_int */
	(unaryfunc)instance_long,		/* nb_long */
	(unaryfunc)instance_float,		/* nb_float */
	(unaryfunc)instance_oct,		/* nb_oct */
	(unaryfunc)instance_hex,		/* nb_hex */
	(binaryfunc)instance_iadd,		/* nb_inplace_add */
	(binaryfunc)instance_isub,		/* nb_inplace_subtract */
	(binaryfunc)instance_imul,		/* nb_inplace_multiply */
	(binaryfunc)instance_idiv,		/* nb_inplace_divide */
	(binaryfunc)instance_imod,		/* nb_inplace_remainder */
	(ternaryfunc)instance_ipow,		/* nb_inplace_power */
	(binaryfunc)instance_ilshift,		/* nb_inplace_lshift */
	(binaryfunc)instance_irshift,		/* nb_inplace_rshift */
	(binaryfunc)instance_iand,		/* nb_inplace_and */
	(binaryfunc)instance_ixor,		/* nb_inplace_xor */
	(binaryfunc)instance_ior,		/* nb_inplace_or */
	(binaryfunc)instance_floordiv,		/* nb_floor_divide */
	(binaryfunc)instance_truediv,		/* nb_true_divide */
	(binaryfunc)instance_ifloordiv,		/* nb_inplace_floor_divide */
	(binaryfunc)instance_itruediv,		/* nb_inplace_true_divide */
};

#ifndef SYMBIAN
PyTypeObject PyInstance_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_PyInstance_Type = {
	PyObject_HEAD_INIT(NULL)
#endif
	0,
	"instance",
	sizeof(PyInstanceObject),
	0,
	(destructor)instance_dealloc,		/* tp_dealloc */
	0,					/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	instance_compare,			/* tp_compare */
	(reprfunc)instance_repr,		/* tp_repr */
	&instance_as_number,			/* tp_as_number */
	&instance_as_sequence,			/* tp_as_sequence */
	&instance_as_mapping,			/* tp_as_mapping */
	(hashfunc)instance_hash,		/* tp_hash */
	instance_call,				/* tp_call */
	(reprfunc)instance_str,			/* tp_str */
	(getattrofunc)instance_getattr,		/* tp_getattro */
	(setattrofunc)instance_setattr,		/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES,/*tp_flags*/
	0,					/* tp_doc */
	(traverseproc)instance_traverse,	/* tp_traverse */
	0,					/* tp_clear */
	instance_richcompare,			/* tp_richcompare */
 	offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */
	(getiterfunc)instance_getiter,		/* tp_iter */
	(iternextfunc)instance_iternext,	/* tp_iternext */
};


/* Instance method objects are used for two purposes:
   (a) as bound instance methods (returned by instancename.methodname)
   (b) as unbound methods (returned by ClassName.methodname)
   In case (b), im_self is NULL
*/

#ifndef SYMBIAN
static PyMethodObject *free_list;
#else
#define free_list (pyglobals->classobj_free_list)
#endif 

DL_EXPORT(PyObject *)
PyMethod_New(PyObject *func, PyObject *self, PyObject *class)
{
	register PyMethodObject *im;

#ifdef SYMBIAN
	SPy_Python_globals* pyglobals = PYTHON_GLOBALS; //  avoid TLS reads
#endif

	if (!PyCallable_Check(func)) {
		PyErr_BadInternalCall();
		return NULL;
	}
	im = free_list;
	if (im != NULL) {
		free_list = (PyMethodObject *)(im->im_self);
		PyObject_INIT(im, &PyMethod_Type);
	}
	else {
		im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
		if (im == NULL)
			return NULL;
	}
	im->im_weakreflist = NULL;
	Py_INCREF(func);
	im->im_func = func;
	Py_XINCREF(self);
	im->im_self = self;
	Py_XINCREF(class);
	im->im_class = class;
	_PyObject_GC_TRACK(im);
	return (PyObject *)im;
}

/* Descriptors for PyMethod attributes */

/* im_class, im_func and im_self are stored in the PyMethod object */

#define OFF(x) offsetof(PyMethodObject, x)

const static PyMemberDef instancemethod_memberlist[] = {
	{"im_class",	T_OBJECT,	OFF(im_class),	READONLY|RESTRICTED,
	 "the class associated with a method"},
	{"im_func",	T_OBJECT,	OFF(im_func),	READONLY|RESTRICTED,
	 "the function (or other callable) implementing a method"},
	{"im_self",	T_OBJECT,	OFF(im_self),	READONLY|RESTRICTED,
	 "the instance to which a method is bound; None for unbound methods"},
	{NULL}	/* Sentinel */
};

/* The getattr() implementation for PyMethod objects is similar to
   PyObject_GenericGetAttr(), but instead of looking in __dict__ it
   asks im_self for the attribute.  Then the error handling is a bit
   different because we want to preserve the exception raised by the
   delegate, unless we have an alternative from our class. */

static PyObject *
instancemethod_getattro(PyObject *obj, PyObject *name)
{
	PyMethodObject *im = (PyMethodObject *)obj;
	PyTypeObject *tp = obj->ob_type;
	PyObject *descr = NULL, *res;
	descrgetfunc f = NULL;

	if (PyType_HasFeature(tp, Py_TPFLAGS_HAVE_CLASS)) {
		if (tp->tp_dict == NULL) {
			if (PyType_Ready(tp) < 0)
				return NULL;
		}
		descr = _PyType_Lookup(tp, name);
	}

	f = NULL;
	if (descr != NULL) {
		f = TP_DESCR_GET(descr->ob_type);
		if (f != NULL && PyDescr_IsData(descr))
			return f(descr, obj, (PyObject *)obj->ob_type);
	}

	res = PyObject_GetAttr(im->im_func, name);
	if (res != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError))
		return res;

	if (f != NULL) {
		PyErr_Clear();
		return f(descr, obj, (PyObject *)obj->ob_type);
	}

	if (descr != NULL) {
		PyErr_Clear();
		Py_INCREF(descr);
		return descr;
	}

	assert(PyErr_Occurred());
	return NULL;
}

static void
instancemethod_dealloc(register PyMethodObject *im)
{
#ifdef SYMBIAN
	SPy_Python_globals* pyglobals = PYTHON_GLOBALS; //  avoid TLS reads
#endif
	_PyObject_GC_UNTRACK(im);
	if (im->im_weakreflist != NULL)
		PyObject_ClearWeakRefs((PyObject *)im);
	Py_DECREF(im->im_func);
	Py_XDECREF(im->im_self);
	Py_XDECREF(im->im_class);
	im->im_self = (PyObject *)free_list;
	free_list = im;
}

static int
instancemethod_compare(PyMethodObject *a, PyMethodObject *b)
{
	if (a->im_self != b->im_self)
		return (a->im_self < b->im_self) ? -1 : 1;
	return PyObject_Compare(a->im_func, b->im_func);
}

static PyObject *
instancemethod_repr(PyMethodObject *a)
{
	PyObject *self = a->im_self;
	PyObject *func = a->im_func;
	PyObject *klass = a->im_class;
	PyObject *funcname = NULL, *klassname = NULL, *result = NULL;
	char *sfuncname = "?", *sklassname = "?";

	funcname = PyObject_GetAttrString(func, "__name__");
	if (funcname == NULL)
		PyErr_Clear();
	else if (!PyString_Check(funcname)) {
		Py_DECREF(funcname);
		funcname = NULL;
	}
	else
		sfuncname = PyString_AS_STRING(funcname);
	if (klass == NULL)
		klassname = NULL;
	else {
		klassname = PyObject_GetAttrString(klass, "__name__");
		if (klassname == NULL)
			PyErr_Clear();
		else if (!PyString_Check(klassname)) {
			Py_DECREF(klassname);
			klassname = NULL;
		}
		else
			sklassname = PyString_AS_STRING(klassname);
	}
	if (self == NULL)
		result = PyString_FromFormat("<unbound method %s.%s>",
					     sklassname, sfuncname);
	else {
		/* XXX Shouldn't use repr() here! */
		PyObject *selfrepr = PyObject_Repr(self);
		if (selfrepr == NULL)
			goto fail;
		if (!PyString_Check(selfrepr)) {
			Py_DECREF(selfrepr);
			goto fail;
		}
		result = PyString_FromFormat("<bound method %s.%s of %s>",
					     sklassname, sfuncname,
					     PyString_AS_STRING(selfrepr));
		Py_DECREF(selfrepr);
	}
  fail:
	Py_XDECREF(funcname);
	Py_XDECREF(klassname);
	return result;
}

static long
instancemethod_hash(PyMethodObject *a)
{
	long x, y;
	if (a->im_self == NULL)
		x = PyObject_Hash(Py_None);
	else
		x = PyObject_Hash(a->im_self);
	if (x == -1)
		return -1;
	y = PyObject_Hash(a->im_func);
	if (y == -1)
		return -1;
	return x ^ y;
}

static int
instancemethod_traverse(PyMethodObject *im, visitproc visit, void *arg)
{
	int err;
	if (im->im_func) {
		err = visit(im->im_func, arg);
		if (err)
			return err;
	}
	if (im->im_self) {
		err = visit(im->im_self, arg);
		if (err)
			return err;
	}
	if (im->im_class) {
		err = visit(im->im_class, arg);
		if (err)
			return err;
	}
	return 0;
}

static char *
getclassname(PyObject *class)
{
	PyObject *name;

	if (class == NULL)
		name = NULL;
	else
		name = PyObject_GetAttrString(class, "__name__");
	if (name == NULL) {
		PyErr_Clear();
		return "?";
	}
	if (!PyString_Check(name)) {
		Py_DECREF(name);
		return "?";
	}
	PyString_InternInPlace(&name);
	Py_DECREF(name);
	return PyString_AS_STRING(name);
}

static char *
getinstclassname(PyObject *inst)
{
	PyObject *class;
	char *name;

	if (inst == NULL)
		return "nothing";

	class = PyObject_GetAttrString(inst, "__class__");
	if (class == NULL) {
		PyErr_Clear();
		class = (PyObject *)(inst->ob_type);
		Py_INCREF(class);
	}
	name = getclassname(class);
	Py_XDECREF(class);
	return name;
}

static PyObject *
instancemethod_call(PyObject *func, PyObject *arg, PyObject *kw)
{
	PyObject *self = PyMethod_GET_SELF(func);
	PyObject *class = PyMethod_GET_CLASS(func);
	PyObject *result;

	func = PyMethod_GET_FUNCTION(func);
	if (self == NULL) {
		/* Unbound methods must be called with an instance of
		   the class (or a derived class) as first argument */
		int ok;
		if (PyTuple_Size(arg) >= 1)
			self = PyTuple_GET_ITEM(arg, 0);
		if (self == NULL)
			ok = 0;
		else {
			ok = PyObject_IsInstance(self, class);
			if (ok < 0)
				return NULL;
		}
		if (!ok) {
			PyErr_Format(PyExc_TypeError,
				     "unbound method %s%s must be called with "
				     "%s instance as first argument "
				     "(got %s%s instead)",
				     PyEval_GetFuncName(func),
				     PyEval_GetFuncDesc(func),
				     getclassname(class),
				     getinstclassname(self),
				     self == NULL ? "" : " instance");
			return NULL;
		}
		Py_INCREF(arg);
	}
	else {
		int argcount = PyTuple_Size(arg);
		PyObject *newarg = PyTuple_New(argcount + 1);
		int i;
		if (newarg == NULL)
			return NULL;
		Py_INCREF(self);
		PyTuple_SET_ITEM(newarg, 0, self);
		for (i = 0; i < argcount; i++) {
			PyObject *v = PyTuple_GET_ITEM(arg, i);
			Py_XINCREF(v);
			PyTuple_SET_ITEM(newarg, i+1, v);
		}
		arg = newarg;
	}
	result = PyObject_Call((PyObject *)func, arg, kw);
	Py_DECREF(arg);
	return result;
}

static PyObject *
instancemethod_descr_get(PyObject *meth, PyObject *obj, PyObject *class)
{
	/* Don't rebind an already bound method, or an unbound method
	   of a class that's not a base class of class */
	if (PyMethod_GET_SELF(meth) != NULL ||
	    (PyMethod_GET_CLASS(meth) != NULL &&
	     !PyObject_IsSubclass(class,  PyMethod_GET_CLASS(meth)))) {
		Py_INCREF(meth);
		return meth;
	}
	if (obj == Py_None)
		obj = NULL;
	return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, class);
}

#ifndef SYMBIAN
PyTypeObject PyMethod_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_PyMethod_Type = {
	PyObject_HEAD_INIT(NULL)
#endif
	0,
	"instance method",
	sizeof(PyMethodObject),
	0,
	(destructor)instancemethod_dealloc,	/* tp_dealloc */
	0,					/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	(cmpfunc)instancemethod_compare,	/* tp_compare */
	(reprfunc)instancemethod_repr,		/* tp_repr */
	0,					/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	(hashfunc)instancemethod_hash,		/* tp_hash */
	instancemethod_call,			/* tp_call */
	0,					/* tp_str */
	(getattrofunc)instancemethod_getattro,	/* tp_getattro */
	PyObject_GenericSetAttr,		/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
	0,					/* tp_doc */
	(traverseproc)instancemethod_traverse,	/* tp_traverse */
	0,					/* tp_clear */
	0,					/* tp_richcompare */
 	offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */
	0,					/* tp_iter */
	0,					/* tp_iternext */
	0,					/* tp_methods */
	instancemethod_memberlist,		/* tp_members */
	0,					/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	instancemethod_descr_get,		/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
};

/* Clear out the free list */

DL_EXPORT(void)
PyMethod_Fini(void)
{
#ifdef SYMBIAN
        SPy_Python_globals* pyglobals = PYTHON_GLOBALS; //  avoid TLS reads
#endif

	while (free_list) {
		PyMethodObject *im = free_list;
		free_list = (PyMethodObject *)(im->im_self);
		PyObject_GC_Del(im);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -