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

📄 classobject.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}
	/* __coerce__ returned two new values */
	*pv = PyTuple_GetItem(coerced, 0);
	*pw = PyTuple_GetItem(coerced, 1);
	Py_INCREF(*pv);
	Py_INCREF(*pw);
	Py_DECREF(coerced);
	return 0;
}

#ifndef SYMBIAN
#define UNARY(funcname, methodname) \
static PyObject *funcname(PyInstanceObject *self) { \
	static PyObject *o; \
	if (o == NULL) o = PyString_InternFromString(methodname); \
	return generic_unary_op(self, o); \
}
#else
#define UNARY(funcname, methodname) \
static PyObject *funcname(PyInstanceObject *self) { \
        SPy_Python_globals* pyglobals = PYTHON_GLOBALS; \
	if ((pyglobals->funcname##_o) == NULL) \
          (pyglobals->funcname##_o) = PyString_InternFromString(methodname); \
	return generic_unary_op(self, (pyglobals->funcname##_o)); \
}
#endif /* SYMBIAN */

#define BINARY(f, m, n) \
static PyObject *f(PyObject *v, PyObject *w) { \
	return do_binop(v, w, "__" m "__", "__r" m "__", n); \
}

#define BINARY_INPLACE(f, m, n) \
static PyObject *f(PyObject *v, PyObject *w) { \
	return do_binop_inplace(v, w, "__i" m "__", "__" m "__", \
			"__r" m "__", n); \
}

UNARY(instance_neg, "__neg__")
UNARY(instance_pos, "__pos__")
UNARY(instance_abs, "__abs__")
BINARY(instance_or, "or", PyNumber_Or)
BINARY(instance_and, "and", PyNumber_And)
BINARY(instance_xor, "xor", PyNumber_Xor)
BINARY(instance_lshift, "lshift", PyNumber_Lshift)
BINARY(instance_rshift, "rshift", PyNumber_Rshift)
BINARY(instance_add, "add", PyNumber_Add)
BINARY(instance_sub, "sub", PyNumber_Subtract)
BINARY(instance_mul, "mul", PyNumber_Multiply)
BINARY(instance_div, "div", PyNumber_Divide)
BINARY(instance_mod, "mod", PyNumber_Remainder)
BINARY(instance_divmod, "divmod", PyNumber_Divmod)
BINARY(instance_floordiv, "floordiv", PyNumber_FloorDivide)
BINARY(instance_truediv, "truediv", PyNumber_TrueDivide)

BINARY_INPLACE(instance_ior, "or", PyNumber_InPlaceOr)
BINARY_INPLACE(instance_ixor, "xor", PyNumber_InPlaceXor)
BINARY_INPLACE(instance_iand, "and", PyNumber_InPlaceAnd)
BINARY_INPLACE(instance_ilshift, "lshift", PyNumber_InPlaceLshift)
BINARY_INPLACE(instance_irshift, "rshift", PyNumber_InPlaceRshift)
BINARY_INPLACE(instance_iadd, "add", PyNumber_InPlaceAdd)
BINARY_INPLACE(instance_isub, "sub", PyNumber_InPlaceSubtract)
BINARY_INPLACE(instance_imul, "mul", PyNumber_InPlaceMultiply)
BINARY_INPLACE(instance_idiv, "div", PyNumber_InPlaceDivide)
BINARY_INPLACE(instance_imod, "mod", PyNumber_InPlaceRemainder)
BINARY_INPLACE(instance_ifloordiv, "floordiv", PyNumber_InPlaceFloorDivide)
BINARY_INPLACE(instance_itruediv, "truediv", PyNumber_InPlaceTrueDivide)

/* Try a 3-way comparison, returning an int; v is an instance.  Return:
   -2 for an exception;
   -1 if v < w;
   0 if v == w;
   1 if v > w;
   2 if this particular 3-way comparison is not implemented or undefined.
*/
static int
half_cmp(PyObject *v, PyObject *w)
{
	PyObject *args;
	PyObject *cmp_func;
	PyObject *result;
	long l;
#ifndef SYMBIAN
  	static PyObject *cmp_obj;
#else
	SPy_Python_globals* pyglobals = PYTHON_GLOBALS; //  avoid TLS reads
#define cmp_obj (pyglobals->cmp_obj)
#endif
	assert(PyInstance_Check(v));

	if (cmp_obj == NULL) {
		cmp_obj = PyString_InternFromString("__cmp__");
		if (cmp_obj == NULL)
			return -2;
	}

	cmp_func = PyObject_GetAttr(v, cmp_obj);
	if (cmp_func == NULL) {
		PyErr_Clear();
		return 2;
	}

	args = Py_BuildValue("(O)", w);
	if (args == NULL)
		return -2;

	result = PyEval_CallObject(cmp_func, args);
	Py_DECREF(args);
	Py_DECREF(cmp_func);

	if (result == NULL)
		return -2;

	if (result == Py_NotImplemented) {
		Py_DECREF(result);
		return 2;
	}

	l = PyInt_AsLong(result);
	Py_DECREF(result);
	if (l == -1 && PyErr_Occurred()) {
		PyErr_SetString(PyExc_TypeError,
			     "comparison did not return an int");
		return -2;
	}

	return l < 0 ? -1 : l > 0 ? 1 : 0;
}

/* Try a 3-way comparison, returning an int; either v or w is an instance.
   We first try a coercion.  Return:
   -2 for an exception;
   -1 if v < w;
   0 if v == w;
   1 if v > w;
   2 if this particular 3-way comparison is not implemented or undefined.
   THIS IS ONLY CALLED FROM object.c!
*/
static int
instance_compare(PyObject *v, PyObject *w)
{
	int c;

	c = PyNumber_CoerceEx(&v, &w);
	if (c < 0)
		return -2;
	if (c == 0) {
		/* If neither is now an instance, use regular comparison */
		if (!PyInstance_Check(v) && !PyInstance_Check(w)) {
			c = PyObject_Compare(v, w);
			Py_DECREF(v);
			Py_DECREF(w);
			if (PyErr_Occurred())
				return -2;
			return c < 0 ? -1 : c > 0 ? 1 : 0;
		}
	}
	else {
		/* The coercion didn't do anything.
		   Treat this the same as returning v and w unchanged. */
		Py_INCREF(v);
		Py_INCREF(w);
	}

	if (PyInstance_Check(v)) {
		c = half_cmp(v, w);
		if (c <= 1) {
			Py_DECREF(v);
			Py_DECREF(w);
			return c;
		}
	}
	if (PyInstance_Check(w)) {
		c = half_cmp(w, v);
		if (c <= 1) {
			Py_DECREF(v);
			Py_DECREF(w);
			if (c >= -1)
				c = -c;
			return c;
		}
	}
	Py_DECREF(v);
	Py_DECREF(w);
	return 2;
}

static int
instance_nonzero(PyInstanceObject *self)
{
	PyObject *func, *res;
	long outcome;
#ifndef SYMBIAN
	static PyObject *nonzerostr;
#else
	SPy_Python_globals* pyglobals = PYTHON_GLOBALS; //  avoid TLS reads
#define nonzerostr (pyglobals->nonzerostr)
#endif

	if (nonzerostr == NULL)
		nonzerostr = PyString_InternFromString("__nonzero__");
	if ((func = instance_getattr(self, nonzerostr)) == NULL) {
		PyErr_Clear();
		if (lenstr == NULL)
			lenstr = PyString_InternFromString("__len__");
		if ((func = instance_getattr(self, lenstr)) == NULL) {
			PyErr_Clear();
			/* Fall back to the default behavior:
			   all instances are nonzero */
			return 1;
		}
	}
	res = PyEval_CallObject(func, (PyObject *)NULL);
	Py_DECREF(func);
	if (res == NULL)
		return -1;
	if (!PyInt_Check(res)) {
		Py_DECREF(res);
		PyErr_SetString(PyExc_TypeError,
				"__nonzero__ should return an int");
		return -1;
	}
	outcome = PyInt_AsLong(res);
	Py_DECREF(res);
	if (outcome < 0) {
		PyErr_SetString(PyExc_ValueError,
				"__nonzero__ should return >= 0");
		return -1;
	}
	return outcome > 0;
}

UNARY(instance_invert, "__invert__")
UNARY(instance_int, "__int__")
UNARY(instance_long, "__long__")
UNARY(instance_float, "__float__")
UNARY(instance_oct, "__oct__")
UNARY(instance_hex, "__hex__")

static PyObject *
bin_power(PyObject *v, PyObject *w)
{
	return PyNumber_Power(v, w, Py_None);
}

/* This version is for ternary calls only (z != None) */
static PyObject *
instance_pow(PyObject *v, PyObject *w, PyObject *z)
{
	if (z == Py_None) {
		return do_binop(v, w, "__pow__", "__rpow__", bin_power);
	}
	else {
		PyObject *func;
		PyObject *args;
		PyObject *result;

		/* XXX Doesn't do coercions... */
		func = PyObject_GetAttrString(v, "__pow__");
		if (func == NULL)
			return NULL;
		args = Py_BuildValue("(OO)", w, z);
		if (args == NULL) {
			Py_DECREF(func);
			return NULL;
		}
		result = PyEval_CallObject(func, args);
		Py_DECREF(func);
		Py_DECREF(args);
		return result;
	}
}

static PyObject *
bin_inplace_power(PyObject *v, PyObject *w)
{
	return PyNumber_InPlacePower(v, w, Py_None);
}


static PyObject *
instance_ipow(PyObject *v, PyObject *w, PyObject *z)
{
	if (z == Py_None) {
		return do_binop_inplace(v, w, "__ipow__", "__pow__",
			"__rpow__", bin_inplace_power);
	}
	else {
		/* XXX Doesn't do coercions... */
		PyObject *func;
		PyObject *args;
		PyObject *result;

		func = PyObject_GetAttrString(v, "__ipow__");
		if (func == NULL) {
			if (!PyErr_ExceptionMatches(PyExc_AttributeError))
				return NULL;
			PyErr_Clear();
			return instance_pow(v, w, z);
		}
		args = Py_BuildValue("(OO)", w, z);
		if (args == NULL) {
			Py_DECREF(func);
			return NULL;
		}
		result = PyEval_CallObject(func, args);
		Py_DECREF(func);
		Py_DECREF(args);
		return result;
	}
}


/* Map rich comparison operators to their __xx__ namesakes */
#define NAME_OPS 6
#ifndef SYMBIAN
static PyObject **name_op = NULL;
#else
#define name_op (pyglobals->name_op)
#endif

static int
init_name_op(void)
{
	int i;
	char *_name_op[] = {
		"__lt__",
		"__le__",
		"__eq__",
		"__ne__",
		"__gt__",
		"__ge__",
	};

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

	name_op = (PyObject **)PyCore_MALLOC(sizeof(PyObject *) * NAME_OPS);
	if (name_op == NULL)
		return -1;
	for (i = 0; i < NAME_OPS; ++i) {
		name_op[i] = PyString_InternFromString(_name_op[i]);
		if (name_op[i] == NULL)
			return -1;
	}
	return 0;
}

static PyObject *
half_richcompare(PyObject *v, PyObject *w, int op)
{
	PyObject *method;
	PyObject *args;
	PyObject *res;

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

	assert(PyInstance_Check(v));

	if (name_op == NULL) {
		if (init_name_op() < 0)
			return NULL;
	}
	/* If the instance doesn't define an __getattr__ method, use
	   instance_getattr2 directly because it will not set an
	   exception on failure. */
	if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL) {
		method = instance_getattr2((PyInstanceObject *)v,
					   name_op[op]);
		if (method == NULL) {
			assert(!PyErr_Occurred());
			res = Py_NotImplemented;
			Py_INCREF(res);
			return res;
		}
	} else {
		method = PyObject_GetAttr(v, name_op[op]);
		if (method == NULL) {
			if (!PyErr_ExceptionMatches(PyExc_AttributeError))
				return NULL;
			PyErr_Clear();
			res = Py_NotImplemented;
			Py_INCREF(res);
			return res;
		}
	}

	args = Py_BuildValue("(O)", w);
	if (args == NULL) {
		Py_DECREF(method);
		return NULL;
	}

	res = PyEval_CallObject(method, args);
	Py_DECREF(args);
	Py_DECREF(method);

	return res;
}

/* Map rich comparison operators to their swapped version, e.g. LT --> GT */
static const int swapped_op[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE};

static PyObject *
instance_richcompare(PyObject *v, PyObject *w, int op)
{
	PyObject *res;

	if (PyInstance_Check(v)) {
		res = half_richcompare(v, w, op);
		if (res != Py_NotImplemented)
			return res;
		Py_DECREF(res);
	}

	if (PyInstance_Check(w)) {
		res = half_richcompare(w, v, swapped_op[op]);
		if (res != Py_NotImplemented)
			return res;
		Py_DECREF(res);
	}

	Py_INCREF(Py_NotImplemented);
	return Py_NotImplemented;
}


/* Get the iterator */
static PyObject *
instance_getiter(PyInstanceObject *self)
{
	PyObject *func;

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

	if (iterstr == NULL)
		iterstr = PyString_InternFromString("__iter__");
	if (getitemstr == NULL)
		getitemstr = PyString_InternFromString("__getitem__");

	if ((func = instance_getattr(self, iterstr)) != NULL) {
		PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
		Py_DECREF(func);
		if (res != NULL && !PyIter_Check(res)) {
			PyErr_Format(PyExc_TypeError,
				     "__iter__ returned non-iterator "
				     "of type '%.100s'",
				     res->ob_type->tp_name);
			Py_DECREF(res);
			res = NULL;
		}
		return res;
	}
	PyErr_Clear();
	if ((func = instance_getattr(self, getitemstr)) == NULL) {
		PyErr_SetString(PyExc_TypeError, "iteration over non-sequence");
		return NULL;
	}
	Py_DECREF(func);
	return PySeqIter_New((PyObject *)self);
}


/* Call the iterator's next */
static PyObject *
instance_iternext(PyInstanceObject *self)
{
	PyObject *func;

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

	if (nextstr == NULL)
		nextstr = PyString_InternFromString("next");

	if ((func = instance_getattr(self, nextstr)) != NULL) {
		PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
		Py_DECREF(func);
		if (res != NULL) {
			return res;
		}
		if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
			PyErr_Clear();
			return NULL;
		}
		return NULL;
	}
	PyErr_SetString(PyExc_TypeError, "instance has no next() method");
	return NULL;
}

static PyObject *
instance_call(PyObject *func, PyObject *arg, PyObject *kw)
{
	PyThreadState *tstate = PyThreadState_GET();
	PyObject *res, *call = PyObject_GetAttrString(func, "__call__");
	if (call == NULL) {
		PyInstanceObject *inst = (PyInstanceObject*) func;
		PyErr_Clear();

⌨️ 快捷键说明

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