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

📄 abstract.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:

/* Operations on mappings */

DL_EXPORT(int)
PyMapping_Check(PyObject *o)
{
	return o && o->ob_type->tp_as_mapping &&
		o->ob_type->tp_as_mapping->mp_subscript;
}

DL_EXPORT(int)
PyMapping_Size(PyObject *o)
{
	PyMappingMethods *m;

	if (o == NULL) {
		null_error();
		return -1;
	}

  	// XXX:CW32
	m = (PyMappingMethods *)o->ob_type->tp_as_mapping;
	if (m && m->mp_length)
		return m->mp_length(o);

	type_error("len() of unsized object");
	return -1;
}

#undef PyMapping_Length
DL_EXPORT(int)
PyMapping_Length(PyObject *o)
{
	return PyMapping_Size(o);
}
#define PyMapping_Length PyMapping_Size

DL_EXPORT(PyObject *)
PyMapping_GetItemString(PyObject *o, char *key)
{
	PyObject *okey, *r;

	if (key == NULL)
		return null_error();

	okey = PyString_FromString(key);
	if (okey == NULL)
		return NULL;
	r = PyObject_GetItem(o, okey);
	Py_DECREF(okey);
	return r;
}

DL_EXPORT(int)
PyMapping_SetItemString(PyObject *o, char *key, PyObject *value)
{
	PyObject *okey;
	int r;

	if (key == NULL) {
		null_error();
		return -1;
	}

	okey = PyString_FromString(key);
	if (okey == NULL)
		return -1;
	r = PyObject_SetItem(o, okey, value);
	Py_DECREF(okey);
	return r;
}

DL_EXPORT(int)
PyMapping_HasKeyString(PyObject *o, char *key)
{
	PyObject *v;

	v = PyMapping_GetItemString(o, key);
	if (v) {
		Py_DECREF(v);
		return 1;
	}
	PyErr_Clear();
	return 0;
}

DL_EXPORT(int)
PyMapping_HasKey(PyObject *o, PyObject *key)
{
	PyObject *v;

	v = PyObject_GetItem(o, key);
	if (v) {
		Py_DECREF(v);
		return 1;
	}
	PyErr_Clear();
	return 0;
}

/* Operations on callable objects */

/* XXX PyCallable_Check() is in object.c */

DL_EXPORT(PyObject *)
PyObject_CallObject(PyObject *o, PyObject *a)
{
	return PyEval_CallObjectWithKeywords(o, a, NULL);
}

DL_EXPORT(PyObject *)
PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
{
        ternaryfunc call;

	if ((call = func->ob_type->tp_call) != NULL) {
		PyObject *result = (*call)(func, arg, kw);
		if (result == NULL && !PyErr_Occurred())
			PyErr_SetString(
				PyExc_SystemError,
				"NULL result without error in PyObject_Call");
		return result;
	}
	PyErr_Format(PyExc_TypeError, "'%s' object is not callable",
		     func->ob_type->tp_name);
	return NULL;
}

DL_EXPORT(PyObject *)
PyObject_CallFunction(PyObject *callable, char *format, ...)
{
	va_list va;
	PyObject *args, *retval;

	if (callable == NULL)
		return null_error();

	if (format && *format) {
		va_start(va, format);
		args = Py_VaBuildValue(format, va);
		va_end(va);
	}
	else
		args = PyTuple_New(0);

	if (args == NULL)
		return NULL;

	if (!PyTuple_Check(args)) {
		PyObject *a;

		a = PyTuple_New(1);
		if (a == NULL)
			return NULL;
		if (PyTuple_SetItem(a, 0, args) < 0)
			return NULL;
		args = a;
	}
	retval = PyObject_CallObject(callable, args);

	Py_DECREF(args);

	return retval;
}

DL_EXPORT(PyObject *)
PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
{
	va_list va;
	PyObject *args, *func = 0, *retval;

	if (o == NULL || name == NULL)
		return null_error();

	func = PyObject_GetAttrString(o, name);
	if (func == NULL) {
		PyErr_SetString(PyExc_AttributeError, name);
		return 0;
	}

	if (!PyCallable_Check(func))
		return type_error("call of non-callable attribute");

	if (format && *format) {
		va_start(va, format);
		args = Py_VaBuildValue(format, va);
		va_end(va);
	}
	else
		args = PyTuple_New(0);

	if (!args)
		return NULL;

	if (!PyTuple_Check(args)) {
		PyObject *a;

		a = PyTuple_New(1);
		if (a == NULL)
			return NULL;
		if (PyTuple_SetItem(a, 0, args) < 0)
			return NULL;
		args = a;
	}

	retval = PyObject_CallObject(func, args);

	Py_DECREF(args);
	Py_DECREF(func);

	return retval;
}


static PyObject *
objargs_mktuple(va_list va)
{
	int i, n = 0;
	va_list countva;
	PyObject *result, *tmp;

#ifdef VA_LIST_IS_ARRAY
	memcpy(countva, va, sizeof(va_list));
#else
#ifdef __va_copy
	__va_copy(countva, va);
#else
	countva = va;
#endif
#endif

	while (((PyObject *)va_arg(countva, PyObject *)) != NULL)
		++n;
	result = PyTuple_New(n);
	if (result != NULL && n > 0) {
		for (i = 0; i < n; ++i) {
			tmp = (PyObject *)va_arg(va, PyObject *);
			PyTuple_SET_ITEM(result, i, tmp);
			Py_INCREF(tmp);
		}
	}
	return result;
}

DL_EXPORT(PyObject *)
PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
{
	PyObject *args, *tmp;
	va_list vargs;

	if (callable == NULL || name == NULL)
		return null_error();

	callable = PyObject_GetAttr(callable, name);
	if (callable == NULL)
		return NULL;

	/* count the args */
	va_start(vargs, name);
	args = objargs_mktuple(vargs);
	va_end(vargs);
	if (args == NULL) {
		Py_DECREF(callable);
		return NULL;
	}
	tmp = PyObject_Call(callable, args, NULL);
	Py_DECREF(args);
	Py_DECREF(callable);

	return tmp;
}

DL_EXPORT(PyObject *)
PyObject_CallFunctionObjArgs(PyObject *callable, ...)
{
	PyObject *args, *tmp;
	va_list vargs;

	if (callable == NULL)
		return null_error();

	/* count the args */
	va_start(vargs, callable);
	args = objargs_mktuple(vargs);
	va_end(vargs);
	if (args == NULL)
		return NULL;
	tmp = PyObject_Call(callable, args, NULL);
	Py_DECREF(args);

	return tmp;
}


/* isinstance(), issubclass() */

/* abstract_get_bases() has logically 4 return states, with a sort of 0th
 * state that will almost never happen.
 *
 * 0. creating the __bases__ static string could get a MemoryError
 * 1. getattr(cls, '__bases__') could raise an AttributeError
 * 2. getattr(cls, '__bases__') could raise some other exception
 * 3. getattr(cls, '__bases__') could return a tuple
 * 4. getattr(cls, '__bases__') could return something other than a tuple
 *
 * Only state #3 is a non-error state and only it returns a non-NULL object
 * (it returns the retrieved tuple).
 *
 * Any raised AttributeErrors are masked by clearing the exception and
 * returning NULL.  If an object other than a tuple comes out of __bases__,
 * then again, the return value is NULL.  So yes, these two situations
 * produce exactly the same results: NULL is returned and no error is set.
 *
 * If some exception other than AttributeError is raised, then NULL is also
 * returned, but the exception is not cleared.  That's because we want the
 * exception to be propagated along.
 *
 * Callers are expected to test for PyErr_Occurred() when the return value
 * is NULL to decide whether a valid exception should be propagated or not.
 * When there's no exception to propagate, it's customary for the caller to
 * set a TypeError.
 */
static PyObject *
abstract_get_bases(PyObject *cls)
{
#ifndef SYMBIAN
        static PyObject *s__bases__ = NULL;
#else 
#define s__bases__ (PYTHON_GLOBALS->__bases__)
#endif
	PyObject *bases;

	if (s__bases__ == NULL) {
		s__bases__ = PyString_FromString("__bases__");
		if (s__bases__ == NULL)
			return NULL;
	}
	bases = PyObject_GetAttr(cls, s__bases__);
	if (bases == NULL) {
		if (PyErr_ExceptionMatches(PyExc_AttributeError))
			PyErr_Clear();
		return NULL;
	}
	if (!PyTuple_Check(bases)) {
	        Py_DECREF(bases);
		return NULL;
	}
	return bases;
}


static int
abstract_issubclass(PyObject *derived, PyObject *cls)
{
	PyObject *bases;
	int i, n;
	int r = 0;


	if (derived == cls)
		return 1;

	bases = abstract_get_bases(derived);
	if (bases == NULL) {
		if (PyErr_Occurred())
			return -1;
		return 0;
	}
	n = PyTuple_GET_SIZE(bases);
	for (i = 0; i < n; i++) {
		r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls);
		if (r != 0)
			break;
	}

	Py_DECREF(bases);

	return r;
}

DL_EXPORT(int)
PyObject_IsInstance(PyObject *inst, PyObject *cls)
{
	PyObject *icls;
#ifndef SYMBIAN
	static PyObject *s__class__ = NULL;
#else
#define s__class__ (PYTHON_GLOBALS->__class__)
#endif
	int retval = 0;

	if (PyClass_Check(cls) && PyInstance_Check(inst)) {
		PyObject *inclass =
			(PyObject*)((PyInstanceObject*)inst)->in_class;
		retval = PyClass_IsSubclass(inclass, cls);
	}
	else if (PyType_Check(cls)) {
		retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
	}
	else if (PyTuple_Check(cls)) {
		/* Not a general sequence -- that opens up the road to
		   recursion and stack overflow. */
		int i, n;

		n = PyTuple_GET_SIZE(cls);
		for (i = 0; i < n; i++) {
			retval = PyObject_IsInstance(
				inst, PyTuple_GET_ITEM(cls, i));
			if (retval != 0)
				break;
		}
		return retval;
	}
	else {
		PyObject *cls_bases = abstract_get_bases(cls);
		if (cls_bases == NULL) {
			/* Do not mask errors. */
			if (!PyErr_Occurred())
				PyErr_SetString(PyExc_TypeError,
				"isinstance() arg 2 must be a class, type,"
				" or tuple of classes and types");
			return -1;
		}
		Py_DECREF(cls_bases);
		if (s__class__ == NULL) {
			s__class__ = PyString_FromString("__class__");
			if (s__class__ == NULL)
				return -1;
		}
		icls = PyObject_GetAttr(inst, s__class__);
		if (icls == NULL) {
			PyErr_Clear();
			retval = 0;
		}
		else {
			retval = abstract_issubclass(icls, cls);
			Py_DECREF(icls);
		}
	}

	return retval;
}

DL_EXPORT(int)
PyObject_IsSubclass(PyObject *derived, PyObject *cls)
{
	int retval;

	if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
		PyObject *derived_bases;
		PyObject *cls_bases;
	       
		derived_bases = abstract_get_bases(derived);
		if (derived_bases == NULL) {
			/* Do not mask errors */
			if (!PyErr_Occurred())
				PyErr_SetString(PyExc_TypeError,
					"issubclass() arg 1 must be a class");
			return -1;
		}
		Py_DECREF(derived_bases);

		cls_bases = abstract_get_bases(cls);
		if (cls_bases == NULL) {
			/* Do not mask errors */
			if (!PyErr_Occurred())
				PyErr_SetString(PyExc_TypeError,
					"issubclass() arg 2 must be a class");
			return -1;
		}
		Py_DECREF(cls_bases);

		retval = abstract_issubclass(derived, cls);
	}
	else {
		/* shortcut */
	  	if (!(retval = (derived == cls)))
			retval = PyClass_IsSubclass(derived, cls);
	}

	return retval;
}

DL_EXPORT(PyObject *)
PyObject_GetIter(PyObject *o)
{
	PyTypeObject *t = o->ob_type;
	getiterfunc f = NULL;
	if (PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER))
		f = t->tp_iter;
	if (f == NULL) {
		if (PySequence_Check(o))
			return PySeqIter_New(o);
		PyErr_SetString(PyExc_TypeError, 
				"iteration over non-sequence");
		return NULL;
	}
	else {
		PyObject *res = (*f)(o);
		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;
	}
}

/* Return next item.
 * If an error occurs, return NULL.  PyErr_Occurred() will be true.
 * If the iteration terminates normally, return NULL and clear the
 * PyExc_StopIteration exception (if it was set).  PyErr_Occurred()
 * will be false.
 * Else return the next object.  PyErr_Occurred() will be false.
 */
DL_EXPORT(PyObject *)
PyIter_Next(PyObject *iter)
{
	PyObject *result;
	if (!PyIter_Check(iter)) {
		PyErr_Format(PyExc_TypeError,
			     "'%.100s' object is not an iterator",
			     iter->ob_type->tp_name);
		return NULL;
	}
	result = (*iter->ob_type->tp_iternext)(iter);
	if (result == NULL &&
	    PyErr_Occurred() &&
	    PyErr_ExceptionMatches(PyExc_StopIteration))
		PyErr_Clear();
	return result;
}

⌨️ 快捷键说明

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