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

📄 object.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	PyErr_Clear();
	return 0;
}

DL_EXPORT(int)
PyObject_SetAttrString(PyObject *v, char *name, PyObject *w)
{
	PyObject *s;
	int res;

	if (v->ob_type->tp_setattr != NULL)
		return (*v->ob_type->tp_setattr)(v, name, w);
	s = PyString_InternFromString(name);
	if (s == NULL)
		return -1;
	res = PyObject_SetAttr(v, s, w);
	Py_XDECREF(s);
	return res;
}

DL_EXPORT(PyObject *)
PyObject_GetAttr(PyObject *v, PyObject *name)
{
	PyTypeObject *tp = v->ob_type;

#ifdef Py_USING_UNICODE
	/* The Unicode to string conversion is done here because the
	   existing tp_getattro slots expect a string object as name
	   and we wouldn't want to break those. */
	if (PyUnicode_Check(name)) {
		name = _PyUnicode_AsDefaultEncodedString(name, NULL);
		if (name == NULL)
			return NULL;
	}
	else
#endif
	if (!PyString_Check(name)) {
		PyErr_SetString(PyExc_TypeError,
				"attribute name must be string");
		return NULL;
	}
	if (tp->tp_getattro != NULL)
		return (*tp->tp_getattro)(v, name);
	if (tp->tp_getattr != NULL)
		return (*tp->tp_getattr)(v, PyString_AS_STRING(name));
	PyErr_Format(PyExc_AttributeError,
		     "'%.50s' object has no attribute '%.400s'",
		     tp->tp_name, PyString_AS_STRING(name));
	return NULL;
}

DL_EXPORT(int)
PyObject_HasAttr(PyObject *v, PyObject *name)
{
	PyObject *res = PyObject_GetAttr(v, name);
	if (res != NULL) {
		Py_DECREF(res);
		return 1;
	}
	PyErr_Clear();
	return 0;
}

DL_EXPORT(int)
PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
{
	PyTypeObject *tp = v->ob_type;
	int err;

#ifdef Py_USING_UNICODE
	/* The Unicode to string conversion is done here because the
	   existing tp_setattro slots expect a string object as name
	   and we wouldn't want to break those. */
	if (PyUnicode_Check(name)) {
		name = PyUnicode_AsEncodedString(name, NULL, NULL);
		if (name == NULL)
			return -1;
	}
	else
#endif
	if (!PyString_Check(name)){
		PyErr_SetString(PyExc_TypeError,
				"attribute name must be string");
		return -1;
	}
	else
		Py_INCREF(name);

	PyString_InternInPlace(&name);
	if (tp->tp_setattro != NULL) {
		err = (*tp->tp_setattro)(v, name, value);
		Py_DECREF(name);
		return err;
	}
	if (tp->tp_setattr != NULL) {
		err = (*tp->tp_setattr)(v, PyString_AS_STRING(name), value);
		Py_DECREF(name);
		return err;
	}
	Py_DECREF(name);
	if (tp->tp_getattr == NULL && tp->tp_getattro == NULL)
		PyErr_Format(PyExc_TypeError,
			     "'%.100s' object has no attributes "
			     "(%s .%.100s)",
			     tp->tp_name,
			     value==NULL ? "del" : "assign to",
			     PyString_AS_STRING(name));
	else
		PyErr_Format(PyExc_TypeError,
			     "'%.100s' object has only read-only attributes "
			     "(%s .%.100s)",
			     tp->tp_name,
			     value==NULL ? "del" : "assign to",
			     PyString_AS_STRING(name));
	return -1;
}

/* Helper to get a pointer to an object's __dict__ slot, if any */

DL_EXPORT(PyObject **)
_PyObject_GetDictPtr(PyObject *obj)
{
	long dictoffset;
	PyTypeObject *tp = obj->ob_type;

	if (!(tp->tp_flags & Py_TPFLAGS_HAVE_CLASS))
		return NULL;
	dictoffset = tp->tp_dictoffset;
	if (dictoffset == 0)
		return NULL;
	if (dictoffset < 0) {
		int tsize;
		size_t size;

		tsize = ((PyVarObject *)obj)->ob_size;
		if (tsize < 0)
			tsize = -tsize;
		size = _PyObject_VAR_SIZE(tp, tsize);

		dictoffset += (long)size;
		assert(dictoffset > 0);
		assert(dictoffset % SIZEOF_VOID_P == 0);
	}
	return (PyObject **) ((char *)obj + dictoffset);
}

/* Generic GetAttr functions - put these in your tp_[gs]etattro slot */

DL_EXPORT(PyObject *)
PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
{
	PyTypeObject *tp = obj->ob_type;
	PyObject *descr;
	PyObject *res = NULL;
	descrgetfunc f;
	PyObject **dictptr;

#ifdef Py_USING_UNICODE
	/* The Unicode to string conversion is done here because the
	   existing tp_setattro slots expect a string object as name
	   and we wouldn't want to break those. */
	if (PyUnicode_Check(name)) {
		name = PyUnicode_AsEncodedString(name, NULL, NULL);
		if (name == NULL)
			return NULL;
	}
	else
#endif
	if (!PyString_Check(name)){
		PyErr_SetString(PyExc_TypeError,
				"attribute name must be string");
		return NULL;
	}
	else
		Py_INCREF(name);

	if (tp->tp_dict == NULL) {
		if (PyType_Ready(tp) < 0)
			goto done;
	}

	descr = _PyType_Lookup(tp, name);
	f = NULL;
	if (descr != NULL) {
		f = descr->ob_type->tp_descr_get;
		if (f != NULL && PyDescr_IsData(descr)) {
			res = f(descr, obj, (PyObject *)obj->ob_type);
			goto done;
		}
	}

	dictptr = _PyObject_GetDictPtr(obj);
	if (dictptr != NULL) {
		PyObject *dict = *dictptr;
		if (dict != NULL) {
			res = PyDict_GetItem(dict, name);
			if (res != NULL) {
				Py_INCREF(res);
				goto done;
			}
		}
	}

	if (f != NULL) {
		res = f(descr, obj, (PyObject *)obj->ob_type);
		goto done;
	}

	if (descr != NULL) {
		Py_INCREF(descr);
		res = descr;
		goto done;
	}

	PyErr_Format(PyExc_AttributeError,
		     "'%.50s' object has no attribute '%.400s'",
		     tp->tp_name, PyString_AS_STRING(name));
  done:
	Py_DECREF(name);
	return res;
}

DL_EXPORT(int)
PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
{
	PyTypeObject *tp = obj->ob_type;
	PyObject *descr;
	descrsetfunc f;
	PyObject **dictptr;
	int res = -1;

#ifdef Py_USING_UNICODE
	/* The Unicode to string conversion is done here because the
	   existing tp_setattro slots expect a string object as name
	   and we wouldn't want to break those. */
	if (PyUnicode_Check(name)) {
		name = PyUnicode_AsEncodedString(name, NULL, NULL);
		if (name == NULL)
			return -1;
	}
	else
#endif
	if (!PyString_Check(name)){
		PyErr_SetString(PyExc_TypeError,
				"attribute name must be string");
		return -1;
	}
	else
		Py_INCREF(name);

	if (tp->tp_dict == NULL) {
		if (PyType_Ready(tp) < 0)
			goto done;
	}

	descr = _PyType_Lookup(tp, name);
	f = NULL;
	if (descr != NULL) {
		f = descr->ob_type->tp_descr_set;
		if (f != NULL && PyDescr_IsData(descr)) {
			res = f(descr, obj, value);
			goto done;
		}
	}

	dictptr = _PyObject_GetDictPtr(obj);
	if (dictptr != NULL) {
		PyObject *dict = *dictptr;
		if (dict == NULL && value != NULL) {
			dict = PyDict_New();
			if (dict == NULL)
				goto done;
			*dictptr = dict;
		}
		if (dict != NULL) {
			if (value == NULL)
				res = PyDict_DelItem(dict, name);
			else
				res = PyDict_SetItem(dict, name, value);
			if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
				PyErr_SetObject(PyExc_AttributeError, name);
			goto done;
		}
	}

	if (f != NULL) {
		res = f(descr, obj, value);
		goto done;
	}

	if (descr == NULL) {
		PyErr_Format(PyExc_AttributeError,
			     "'%.50s' object has no attribute '%.400s'",
			     tp->tp_name, PyString_AS_STRING(name));
		goto done;
	}

	PyErr_Format(PyExc_AttributeError,
		     "'%.50s' object attribute '%.400s' is read-only",
		     tp->tp_name, PyString_AS_STRING(name));
  done:
	Py_DECREF(name);
	return res;
}

/* Test a value used as condition, e.g., in a for or if statement.
   Return -1 if an error occurred */

DL_EXPORT(int)
PyObject_IsTrue(PyObject *v)
{
	int res;
	if (v == Py_None)
		res = 0;
	else if (v->ob_type->tp_as_number != NULL &&
		 v->ob_type->tp_as_number->nb_nonzero != NULL)
		res = (*v->ob_type->tp_as_number->nb_nonzero)(v);
	else if (v->ob_type->tp_as_mapping != NULL &&
		 v->ob_type->tp_as_mapping->mp_length != NULL)
		res = (*v->ob_type->tp_as_mapping->mp_length)(v);
	else if (v->ob_type->tp_as_sequence != NULL &&
		 v->ob_type->tp_as_sequence->sq_length != NULL)
		res = (*v->ob_type->tp_as_sequence->sq_length)(v);
	else
		res = 1;
	if (res > 0)
		res = 1;
	return res;
}

/* equivalent of 'not v'
   Return -1 if an error occurred */

DL_EXPORT(int)
PyObject_Not(PyObject *v)
{
	int res;
	res = PyObject_IsTrue(v);
	if (res < 0)
		return res;
	return res == 0;
}

/* Coerce two numeric types to the "larger" one.
   Increment the reference count on each argument.
   Return value:
   -1 if an error occurred;
   0 if the coercion succeeded (and then the reference counts are increased);
   1 if no coercion is possible (and no error is raised).
*/
DL_EXPORT(int)
PyNumber_CoerceEx(PyObject **pv, PyObject **pw)
{
	register PyObject *v = *pv;
	register PyObject *w = *pw;
	int res;

	if (v->ob_type == w->ob_type && !PyInstance_Check(v)) {
		Py_INCREF(v);
		Py_INCREF(w);
		return 0;
	}
	if (v->ob_type->tp_as_number && v->ob_type->tp_as_number->nb_coerce) {
		res = (*v->ob_type->tp_as_number->nb_coerce)(pv, pw);
		if (res <= 0)
			return res;
	}
	if (w->ob_type->tp_as_number && w->ob_type->tp_as_number->nb_coerce) {
		res = (*w->ob_type->tp_as_number->nb_coerce)(pw, pv);
		if (res <= 0)
			return res;
	}
	return 1;
}

/* Coerce two numeric types to the "larger" one.
   Increment the reference count on each argument.
   Return -1 and raise an exception if no coercion is possible
   (and then no reference count is incremented).
*/
DL_EXPORT(int)
PyNumber_Coerce(PyObject **pv, PyObject **pw)
{
	int err = PyNumber_CoerceEx(pv, pw);
	if (err <= 0)
		return err;
	PyErr_SetString(PyExc_TypeError, "number coercion failed");
	return -1;
}


/* Test whether an object can be called */

DL_EXPORT(int)
PyCallable_Check(PyObject *x)
{
	if (x == NULL)
		return 0;
	if (PyInstance_Check(x)) {
		PyObject *call = PyObject_GetAttrString(x, "__call__");
		if (call == NULL) {
			PyErr_Clear();
			return 0;
		}
		/* Could test recursively but don't, for fear of endless
		   recursion if some joker sets self.__call__ = self */
		Py_DECREF(call);
		return 1;
	}
	else {
		return x->ob_type->tp_call != NULL;
	}
}

/* Helper for PyObject_Dir.
   Merge the __dict__ of aclass into dict, and recursively also all
   the __dict__s of aclass's base classes.  The order of merging isn't
   defined, as it's expected that only the final set of dict keys is
   interesting.
   Return 0 on success, -1 on error.
*/

static int
merge_class_dict(PyObject* dict, PyObject* aclass)
{
	PyObject *classdict;
	PyObject *bases;

	assert(PyDict_Check(dict));
	assert(aclass);

	/* Merge in the type's dict (if any). */
	classdict = PyObject_GetAttrString(aclass, "__dict__");
	if (classdict == NULL)
		PyErr_Clear();
	else {
		int status = PyDict_Update(dict, classdict);
		Py_DECREF(classdict);
		if (status < 0)
			return -1;
	}

	/* Recursively merge in the base types' (if any) dicts. */
	bases = PyObject_GetAttrString(aclass, "__bases__");
	if (bases == NULL)
		PyErr_Clear();
	else {
		/* We have no guarantee that bases is a real tuple */
		int i, n;
		n = PySequence_Size(bases); /* This better be right */
		if (n < 0)
			PyErr_Clear();
		else {
			for (i = 0; i < n; i++) {
				PyObject *base = PySequence_GetItem(bases, i);
				if (base == NULL) {
					Py_DECREF(bases);
					return -1;
				}
				if (merge_class_dict(dict, base) < 0) {
					Py_DECREF(bases);
					return -1;
				}
			}
		}
		Py_DECREF(bases);
	}
	return 0;
}

/* Helper for PyObject_Dir.
   If obj has an attr named attrname that's a list, merge its string
   elements into keys of dict.
   Return 0 on success, -1 on error.  Errors due to not finding the attr,
   or the attr not being a list, are suppressed.
*/

static int
merge_list_attr(PyObject* dict, PyObject* obj, char *attrname)
{
	PyObject *list;
	int result = 0;

	assert(PyDict_Check(dict));
	assert(obj);
	assert(attrname);

	list = PyObject_GetAttrString(obj, attrname);
	if (list == NULL)
		PyErr_Clear();

	else if (PyList_Check(list)) {
		int i;
		for (i = 0; i < PyList_GET_SIZE(list); ++i) {
			PyObject *item = PyList_GET_ITEM(list, i);
			if (PyString_Check(item)) {
				result = PyDict_SetItem(dict, item, Py_None);
				if (result < 0)
					break;
			}
		}
	}

	Py_XDECREF(list);
	return result;
}

/* Like __builtin__.dir(arg).  See bltinmodule.c's builtin_dir for the
   docstring, which should be kept in synch with this implementation. */

DL_EXPORT(PyObject *)
PyObject_Dir(PyObject *arg)
{
	/* Set exactly one of these non-NULL before the end. */
	PyObject *result = NULL;	/* result list */
	PyObject *masterdict = NULL;	/* result is masterdict.keys() */

	/* If NULL arg, return the locals. */
	if (arg == NULL) {
		PyObject *locals = PyEval_GetLocals();
		if (locals == NULL)
			goto error;
		result = PyDict_Keys(locals);
		if (result == NULL)
			goto error;
	}

	/* Elif this is some form of module, we only want its dict. */
	else if (PyModule_Check(arg)) {
		masterdict = PyObject_GetAttrString(arg, "__dict__");
		if (masterdict == NULL)
			goto error;
		if (!PyDict_Check(masterdict)) {
			PyErr_SetString(PyExc_TypeError,
					"module.__dict__ is not a dictionary");
			goto error;
		}
	}

	/* Elif some form of type or class, grab its dict and its bases.
	   We deliberately don't suck up its __class__, as methods belonging
	   to the metaclass would probably be more confusing than helpful. */
	else if (PyType_Check(arg) || PyClass_Check(arg)) {
		masterdict = PyDict_New();
		if (masterdict == NULL)

⌨️ 快捷键说明

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