+++ /dev/null
-\r
-/* Class object implementation */\r
-\r
-#include "Python.h"\r
-#include "structmember.h"\r
-\r
-/* Free list for method objects to save malloc/free overhead\r
- * The im_self element is used to chain the elements.\r
- */\r
-static PyMethodObject *free_list;\r
-static int numfree = 0;\r
-#ifndef PyMethod_MAXFREELIST\r
-#define PyMethod_MAXFREELIST 256\r
-#endif\r
-\r
-#define TP_DESCR_GET(t) \\r
- (PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL)\r
-\r
-/* Forward */\r
-static PyObject *class_lookup(PyClassObject *, PyObject *,\r
- PyClassObject **);\r
-static PyObject *instance_getattr1(PyInstanceObject *, PyObject *);\r
-static PyObject *instance_getattr2(PyInstanceObject *, PyObject *);\r
-\r
-static PyObject *getattrstr, *setattrstr, *delattrstr;\r
-\r
-\r
-PyObject *\r
-PyClass_New(PyObject *bases, PyObject *dict, PyObject *name)\r
- /* bases is NULL or tuple of classobjects! */\r
-{\r
- PyClassObject *op, *dummy;\r
- static PyObject *docstr, *modstr, *namestr;\r
- if (docstr == NULL) {\r
- docstr= PyString_InternFromString("__doc__");\r
- if (docstr == NULL)\r
- return NULL;\r
- }\r
- if (modstr == NULL) {\r
- modstr= PyString_InternFromString("__module__");\r
- if (modstr == NULL)\r
- return NULL;\r
- }\r
- if (namestr == NULL) {\r
- namestr= PyString_InternFromString("__name__");\r
- if (namestr == NULL)\r
- return NULL;\r
- }\r
- if (name == NULL || !PyString_Check(name)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "PyClass_New: name must be a string");\r
- return NULL;\r
- }\r
- if (dict == NULL || !PyDict_Check(dict)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "PyClass_New: dict must be a dictionary");\r
- return NULL;\r
- }\r
- if (PyDict_GetItem(dict, docstr) == NULL) {\r
- if (PyDict_SetItem(dict, docstr, Py_None) < 0)\r
- return NULL;\r
- }\r
- if (PyDict_GetItem(dict, modstr) == NULL) {\r
- PyObject *globals = PyEval_GetGlobals();\r
- if (globals != NULL) {\r
- PyObject *modname = PyDict_GetItem(globals, namestr);\r
- if (modname != NULL) {\r
- if (PyDict_SetItem(dict, modstr, modname) < 0)\r
- return NULL;\r
- }\r
- }\r
- }\r
- if (bases == NULL) {\r
- bases = PyTuple_New(0);\r
- if (bases == NULL)\r
- return NULL;\r
- }\r
- else {\r
- Py_ssize_t i, n;\r
- PyObject *base;\r
- if (!PyTuple_Check(bases)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "PyClass_New: bases must be a tuple");\r
- return NULL;\r
- }\r
- n = PyTuple_Size(bases);\r
- for (i = 0; i < n; i++) {\r
- base = PyTuple_GET_ITEM(bases, i);\r
- if (!PyClass_Check(base)) {\r
- if (PyCallable_Check(\r
- (PyObject *) base->ob_type))\r
- return PyObject_CallFunctionObjArgs(\r
- (PyObject *) base->ob_type,\r
- name, bases, dict, NULL);\r
- PyErr_SetString(PyExc_TypeError,\r
- "PyClass_New: base must be a class");\r
- return NULL;\r
- }\r
- }\r
- Py_INCREF(bases);\r
- }\r
-\r
- if (getattrstr == NULL) {\r
- getattrstr = PyString_InternFromString("__getattr__");\r
- if (getattrstr == NULL)\r
- goto alloc_error;\r
- setattrstr = PyString_InternFromString("__setattr__");\r
- if (setattrstr == NULL)\r
- goto alloc_error;\r
- delattrstr = PyString_InternFromString("__delattr__");\r
- if (delattrstr == NULL)\r
- goto alloc_error;\r
- }\r
-\r
- op = PyObject_GC_New(PyClassObject, &PyClass_Type);\r
- if (op == NULL) {\r
-alloc_error:\r
- Py_DECREF(bases);\r
- return NULL;\r
- }\r
- op->cl_bases = bases;\r
- Py_INCREF(dict);\r
- op->cl_dict = dict;\r
- Py_XINCREF(name);\r
- op->cl_name = name;\r
- op->cl_weakreflist = NULL;\r
-\r
- op->cl_getattr = class_lookup(op, getattrstr, &dummy);\r
- op->cl_setattr = class_lookup(op, setattrstr, &dummy);\r
- op->cl_delattr = class_lookup(op, delattrstr, &dummy);\r
- Py_XINCREF(op->cl_getattr);\r
- Py_XINCREF(op->cl_setattr);\r
- Py_XINCREF(op->cl_delattr);\r
- _PyObject_GC_TRACK(op);\r
- return (PyObject *) op;\r
-}\r
-\r
-PyObject *\r
-PyMethod_Function(PyObject *im)\r
-{\r
- if (!PyMethod_Check(im)) {\r
- PyErr_BadInternalCall();\r
- return NULL;\r
- }\r
- return ((PyMethodObject *)im)->im_func;\r
-}\r
-\r
-PyObject *\r
-PyMethod_Self(PyObject *im)\r
-{\r
- if (!PyMethod_Check(im)) {\r
- PyErr_BadInternalCall();\r
- return NULL;\r
- }\r
- return ((PyMethodObject *)im)->im_self;\r
-}\r
-\r
-PyObject *\r
-PyMethod_Class(PyObject *im)\r
-{\r
- if (!PyMethod_Check(im)) {\r
- PyErr_BadInternalCall();\r
- return NULL;\r
- }\r
- return ((PyMethodObject *)im)->im_class;\r
-}\r
-\r
-PyDoc_STRVAR(class_doc,\r
-"classobj(name, bases, dict)\n\\r
-\n\\r
-Create a class object. The name must be a string; the second argument\n\\r
-a tuple of classes, and the third a dictionary.");\r
-\r
-static PyObject *\r
-class_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
- PyObject *name, *bases, *dict;\r
- static char *kwlist[] = {"name", "bases", "dict", 0};\r
-\r
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist,\r
- &name, &bases, &dict))\r
- return NULL;\r
- return PyClass_New(bases, dict, name);\r
-}\r
-\r
-/* Class methods */\r
-\r
-static void\r
-class_dealloc(PyClassObject *op)\r
-{\r
- _PyObject_GC_UNTRACK(op);\r
- if (op->cl_weakreflist != NULL)\r
- PyObject_ClearWeakRefs((PyObject *) op);\r
- Py_DECREF(op->cl_bases);\r
- Py_DECREF(op->cl_dict);\r
- Py_XDECREF(op->cl_name);\r
- Py_XDECREF(op->cl_getattr);\r
- Py_XDECREF(op->cl_setattr);\r
- Py_XDECREF(op->cl_delattr);\r
- PyObject_GC_Del(op);\r
-}\r
-\r
-static PyObject *\r
-class_lookup(PyClassObject *cp, PyObject *name, PyClassObject **pclass)\r
-{\r
- Py_ssize_t i, n;\r
- PyObject *value = PyDict_GetItem(cp->cl_dict, name);\r
- if (value != NULL) {\r
- *pclass = cp;\r
- return value;\r
- }\r
- n = PyTuple_Size(cp->cl_bases);\r
- for (i = 0; i < n; i++) {\r
- /* XXX What if one of the bases is not a class? */\r
- PyObject *v = class_lookup(\r
- (PyClassObject *)\r
- PyTuple_GetItem(cp->cl_bases, i), name, pclass);\r
- if (v != NULL)\r
- return v;\r
- }\r
- return NULL;\r
-}\r
-\r
-static PyObject *\r
-class_getattr(register PyClassObject *op, PyObject *name)\r
-{\r
- register PyObject *v;\r
- register char *sname;\r
- PyClassObject *klass;\r
- descrgetfunc f;\r
-\r
- if (!PyString_Check(name)) {\r
- PyErr_SetString(PyExc_TypeError, "attribute name must be a string");\r
- return NULL;\r
- }\r
-\r
- sname = PyString_AsString(name);\r
- if (sname[0] == '_' && sname[1] == '_') {\r
- if (strcmp(sname, "__dict__") == 0) {\r
- if (PyEval_GetRestricted()) {\r
- PyErr_SetString(PyExc_RuntimeError,\r
- "class.__dict__ not accessible in restricted mode");\r
- return NULL;\r
- }\r
- Py_INCREF(op->cl_dict);\r
- return op->cl_dict;\r
- }\r
- if (strcmp(sname, "__bases__") == 0) {\r
- Py_INCREF(op->cl_bases);\r
- return op->cl_bases;\r
- }\r
- if (strcmp(sname, "__name__") == 0) {\r
- if (op->cl_name == NULL)\r
- v = Py_None;\r
- else\r
- v = op->cl_name;\r
- Py_INCREF(v);\r
- return v;\r
- }\r
- }\r
- v = class_lookup(op, name, &klass);\r
- if (v == NULL) {\r
- PyErr_Format(PyExc_AttributeError,\r
- "class %.50s has no attribute '%.400s'",\r
- PyString_AS_STRING(op->cl_name), sname);\r
- return NULL;\r
- }\r
- f = TP_DESCR_GET(v->ob_type);\r
- if (f == NULL)\r
- Py_INCREF(v);\r
- else\r
- v = f(v, (PyObject *)NULL, (PyObject *)op);\r
- return v;\r
-}\r
-\r
-static void\r
-set_slot(PyObject **slot, PyObject *v)\r
-{\r
- PyObject *temp = *slot;\r
- Py_XINCREF(v);\r
- *slot = v;\r
- Py_XDECREF(temp);\r
-}\r
-\r
-static void\r
-set_attr_slots(PyClassObject *c)\r
-{\r
- PyClassObject *dummy;\r
-\r
- set_slot(&c->cl_getattr, class_lookup(c, getattrstr, &dummy));\r
- set_slot(&c->cl_setattr, class_lookup(c, setattrstr, &dummy));\r
- set_slot(&c->cl_delattr, class_lookup(c, delattrstr, &dummy));\r
-}\r
-\r
-static char *\r
-set_dict(PyClassObject *c, PyObject *v)\r
-{\r
- if (v == NULL || !PyDict_Check(v))\r
- return "__dict__ must be a dictionary object";\r
- set_slot(&c->cl_dict, v);\r
- set_attr_slots(c);\r
- return "";\r
-}\r
-\r
-static char *\r
-set_bases(PyClassObject *c, PyObject *v)\r
-{\r
- Py_ssize_t i, n;\r
-\r
- if (v == NULL || !PyTuple_Check(v))\r
- return "__bases__ must be a tuple object";\r
- n = PyTuple_Size(v);\r
- for (i = 0; i < n; i++) {\r
- PyObject *x = PyTuple_GET_ITEM(v, i);\r
- if (!PyClass_Check(x))\r
- return "__bases__ items must be classes";\r
- if (PyClass_IsSubclass(x, (PyObject *)c))\r
- return "a __bases__ item causes an inheritance cycle";\r
- }\r
- set_slot(&c->cl_bases, v);\r
- set_attr_slots(c);\r
- return "";\r
-}\r
-\r
-static char *\r
-set_name(PyClassObject *c, PyObject *v)\r
-{\r
- if (v == NULL || !PyString_Check(v))\r
- return "__name__ must be a string object";\r
- if (strlen(PyString_AS_STRING(v)) != (size_t)PyString_GET_SIZE(v))\r
- return "__name__ must not contain null bytes";\r
- set_slot(&c->cl_name, v);\r
- return "";\r
-}\r
-\r
-static int\r
-class_setattr(PyClassObject *op, PyObject *name, PyObject *v)\r
-{\r
- char *sname;\r
- if (PyEval_GetRestricted()) {\r
- PyErr_SetString(PyExc_RuntimeError,\r
- "classes are read-only in restricted mode");\r
- return -1;\r
- }\r
- if (!PyString_Check(name)) {\r
- PyErr_SetString(PyExc_TypeError, "attribute name must be a string");\r
- return -1;\r
- }\r
- sname = PyString_AsString(name);\r
- if (sname[0] == '_' && sname[1] == '_') {\r
- Py_ssize_t n = PyString_Size(name);\r
- if (sname[n-1] == '_' && sname[n-2] == '_') {\r
- char *err = NULL;\r
- if (strcmp(sname, "__dict__") == 0)\r
- err = set_dict(op, v);\r
- else if (strcmp(sname, "__bases__") == 0)\r
- err = set_bases(op, v);\r
- else if (strcmp(sname, "__name__") == 0)\r
- err = set_name(op, v);\r
- else if (strcmp(sname, "__getattr__") == 0)\r
- set_slot(&op->cl_getattr, v);\r
- else if (strcmp(sname, "__setattr__") == 0)\r
- set_slot(&op->cl_setattr, v);\r
- else if (strcmp(sname, "__delattr__") == 0)\r
- set_slot(&op->cl_delattr, v);\r
- /* For the last three, we fall through to update the\r
- dictionary as well. */\r
- if (err != NULL) {\r
- if (*err == '\0')\r
- return 0;\r
- PyErr_SetString(PyExc_TypeError, err);\r
- return -1;\r
- }\r
- }\r
- }\r
- if (v == NULL) {\r
- int rv = PyDict_DelItem(op->cl_dict, name);\r
- if (rv < 0)\r
- PyErr_Format(PyExc_AttributeError,\r
- "class %.50s has no attribute '%.400s'",\r
- PyString_AS_STRING(op->cl_name), sname);\r
- return rv;\r
- }\r
- else\r
- return PyDict_SetItem(op->cl_dict, name, v);\r
-}\r
-\r
-static PyObject *\r
-class_repr(PyClassObject *op)\r
-{\r
- PyObject *mod = PyDict_GetItemString(op->cl_dict, "__module__");\r
- char *name;\r
- if (op->cl_name == NULL || !PyString_Check(op->cl_name))\r
- name = "?";\r
- else\r
- name = PyString_AsString(op->cl_name);\r
- if (mod == NULL || !PyString_Check(mod))\r
- return PyString_FromFormat("<class ?.%s at %p>", name, op);\r
- else\r
- return PyString_FromFormat("<class %s.%s at %p>",\r
- PyString_AsString(mod),\r
- name, op);\r
-}\r
-\r
-static PyObject *\r
-class_str(PyClassObject *op)\r
-{\r
- PyObject *mod = PyDict_GetItemString(op->cl_dict, "__module__");\r
- PyObject *name = op->cl_name;\r
- PyObject *res;\r
- Py_ssize_t m, n;\r
-\r
- if (name == NULL || !PyString_Check(name))\r
- return class_repr(op);\r
- if (mod == NULL || !PyString_Check(mod)) {\r
- Py_INCREF(name);\r
- return name;\r
- }\r
- m = PyString_GET_SIZE(mod);\r
- n = PyString_GET_SIZE(name);\r
- res = PyString_FromStringAndSize((char *)NULL, m+1+n);\r
- if (res != NULL) {\r
- char *s = PyString_AS_STRING(res);\r
- memcpy(s, PyString_AS_STRING(mod), m);\r
- s += m;\r
- *s++ = '.';\r
- memcpy(s, PyString_AS_STRING(name), n);\r
- }\r
- return res;\r
-}\r
-\r
-static int\r
-class_traverse(PyClassObject *o, visitproc visit, void *arg)\r
-{\r
- Py_VISIT(o->cl_bases);\r
- Py_VISIT(o->cl_dict);\r
- Py_VISIT(o->cl_name);\r
- Py_VISIT(o->cl_getattr);\r
- Py_VISIT(o->cl_setattr);\r
- Py_VISIT(o->cl_delattr);\r
- return 0;\r
-}\r
-\r
-PyTypeObject PyClass_Type = {\r
- PyObject_HEAD_INIT(&PyType_Type)\r
- 0,\r
- "classobj",\r
- sizeof(PyClassObject),\r
- 0,\r
- (destructor)class_dealloc, /* tp_dealloc */\r
- 0, /* tp_print */\r
- 0, /* tp_getattr */\r
- 0, /* tp_setattr */\r
- 0, /* tp_compare */\r
- (reprfunc)class_repr, /* tp_repr */\r
- 0, /* tp_as_number */\r
- 0, /* tp_as_sequence */\r
- 0, /* tp_as_mapping */\r
- 0, /* tp_hash */\r
- PyInstance_New, /* tp_call */\r
- (reprfunc)class_str, /* tp_str */\r
- (getattrofunc)class_getattr, /* tp_getattro */\r
- (setattrofunc)class_setattr, /* tp_setattro */\r
- 0, /* tp_as_buffer */\r
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */\r
- class_doc, /* tp_doc */\r
- (traverseproc)class_traverse, /* tp_traverse */\r
- 0, /* tp_clear */\r
- 0, /* tp_richcompare */\r
- offsetof(PyClassObject, cl_weakreflist), /* tp_weaklistoffset */\r
- 0, /* tp_iter */\r
- 0, /* tp_iternext */\r
- 0, /* tp_methods */\r
- 0, /* tp_members */\r
- 0, /* tp_getset */\r
- 0, /* tp_base */\r
- 0, /* tp_dict */\r
- 0, /* tp_descr_get */\r
- 0, /* tp_descr_set */\r
- 0, /* tp_dictoffset */\r
- 0, /* tp_init */\r
- 0, /* tp_alloc */\r
- class_new, /* tp_new */\r
-};\r
-\r
-int\r
-PyClass_IsSubclass(PyObject *klass, PyObject *base)\r
-{\r
- Py_ssize_t i, n;\r
- PyClassObject *cp;\r
- if (klass == base)\r
- return 1;\r
- if (PyTuple_Check(base)) {\r
- n = PyTuple_GET_SIZE(base);\r
- for (i = 0; i < n; i++) {\r
- if (PyClass_IsSubclass(klass, PyTuple_GET_ITEM(base, i)))\r
- return 1;\r
- }\r
- return 0;\r
- }\r
- if (klass == NULL || !PyClass_Check(klass))\r
- return 0;\r
- cp = (PyClassObject *)klass;\r
- n = PyTuple_Size(cp->cl_bases);\r
- for (i = 0; i < n; i++) {\r
- if (PyClass_IsSubclass(PyTuple_GetItem(cp->cl_bases, i), base))\r
- return 1;\r
- }\r
- return 0;\r
-}\r
-\r
-\r
-/* Instance objects */\r
-\r
-PyObject *\r
-PyInstance_NewRaw(PyObject *klass, PyObject *dict)\r
-{\r
- PyInstanceObject *inst;\r
-\r
- if (!PyClass_Check(klass)) {\r
- PyErr_BadInternalCall();\r
- return NULL;\r
- }\r
- if (dict == NULL) {\r
- dict = PyDict_New();\r
- if (dict == NULL)\r
- return NULL;\r
- }\r
- else {\r
- if (!PyDict_Check(dict)) {\r
- PyErr_BadInternalCall();\r
- return NULL;\r
- }\r
- Py_INCREF(dict);\r
- }\r
- inst = PyObject_GC_New(PyInstanceObject, &PyInstance_Type);\r
- if (inst == NULL) {\r
- Py_DECREF(dict);\r
- return NULL;\r
- }\r
- inst->in_weakreflist = NULL;\r
- Py_INCREF(klass);\r
- inst->in_class = (PyClassObject *)klass;\r
- inst->in_dict = dict;\r
- _PyObject_GC_TRACK(inst);\r
- return (PyObject *)inst;\r
-}\r
-\r
-PyObject *\r
-PyInstance_New(PyObject *klass, PyObject *arg, PyObject *kw)\r
-{\r
- register PyInstanceObject *inst;\r
- PyObject *init;\r
- static PyObject *initstr;\r
-\r
- if (initstr == NULL) {\r
- initstr = PyString_InternFromString("__init__");\r
- if (initstr == NULL)\r
- return NULL;\r
- }\r
- inst = (PyInstanceObject *) PyInstance_NewRaw(klass, NULL);\r
- if (inst == NULL)\r
- return NULL;\r
- init = instance_getattr2(inst, initstr);\r
- if (init == NULL) {\r
- if (PyErr_Occurred()) {\r
- Py_DECREF(inst);\r
- return NULL;\r
- }\r
- if ((arg != NULL && (!PyTuple_Check(arg) ||\r
- PyTuple_Size(arg) != 0))\r
- || (kw != NULL && (!PyDict_Check(kw) ||\r
- PyDict_Size(kw) != 0))) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "this constructor takes no arguments");\r
- Py_DECREF(inst);\r
- inst = NULL;\r
- }\r
- }\r
- else {\r
- PyObject *res = PyEval_CallObjectWithKeywords(init, arg, kw);\r
- Py_DECREF(init);\r
- if (res == NULL) {\r
- Py_DECREF(inst);\r
- inst = NULL;\r
- }\r
- else {\r
- if (res != Py_None) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "__init__() should return None");\r
- Py_DECREF(inst);\r
- inst = NULL;\r
- }\r
- Py_DECREF(res);\r
- }\r
- }\r
- return (PyObject *)inst;\r
-}\r
-\r
-/* Instance methods */\r
-\r
-PyDoc_STRVAR(instance_doc,\r
-"instance(class[, dict])\n\\r
-\n\\r
-Create an instance without calling its __init__() method.\n\\r
-The class must be a classic class.\n\\r
-If present, dict must be a dictionary or None.");\r
-\r
-static PyObject *\r
-instance_new(PyTypeObject* type, PyObject* args, PyObject *kw)\r
-{\r
- PyObject *klass;\r
- PyObject *dict = Py_None;\r
-\r
- if (!PyArg_ParseTuple(args, "O!|O:instance",\r
- &PyClass_Type, &klass, &dict))\r
- return NULL;\r
-\r
- if (dict == Py_None)\r
- dict = NULL;\r
- else if (!PyDict_Check(dict)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "instance() second arg must be dictionary or None");\r
- return NULL;\r
- }\r
- return PyInstance_NewRaw(klass, dict);\r
-}\r
-\r
-\r
-static void\r
-instance_dealloc(register PyInstanceObject *inst)\r
-{\r
- PyObject *error_type, *error_value, *error_traceback;\r
- PyObject *del;\r
- static PyObject *delstr;\r
-\r
- _PyObject_GC_UNTRACK(inst);\r
- if (inst->in_weakreflist != NULL)\r
- PyObject_ClearWeakRefs((PyObject *) inst);\r
-\r
- /* Temporarily resurrect the object. */\r
- assert(inst->ob_type == &PyInstance_Type);\r
- assert(inst->ob_refcnt == 0);\r
- inst->ob_refcnt = 1;\r
-\r
- /* Save the current exception, if any. */\r
- PyErr_Fetch(&error_type, &error_value, &error_traceback);\r
- /* Execute __del__ method, if any. */\r
- if (delstr == NULL) {\r
- delstr = PyString_InternFromString("__del__");\r
- if (delstr == NULL)\r
- PyErr_WriteUnraisable((PyObject*)inst);\r
- }\r
- if (delstr && (del = instance_getattr2(inst, delstr)) != NULL) {\r
- PyObject *res = PyEval_CallObject(del, (PyObject *)NULL);\r
- if (res == NULL)\r
- PyErr_WriteUnraisable(del);\r
- else\r
- Py_DECREF(res);\r
- Py_DECREF(del);\r
- }\r
- /* Restore the saved exception. */\r
- PyErr_Restore(error_type, error_value, error_traceback);\r
-\r
- /* Undo the temporary resurrection; can't use DECREF here, it would\r
- * cause a recursive call.\r
- */\r
- assert(inst->ob_refcnt > 0);\r
- if (--inst->ob_refcnt == 0) {\r
-\r
- /* New weakrefs could be created during the finalizer call.\r
- If this occurs, clear them out without calling their\r
- finalizers since they might rely on part of the object\r
- being finalized that has already been destroyed. */\r
- while (inst->in_weakreflist != NULL) {\r
- _PyWeakref_ClearRef((PyWeakReference *)\r
- (inst->in_weakreflist));\r
- }\r
-\r
- Py_DECREF(inst->in_class);\r
- Py_XDECREF(inst->in_dict);\r
- PyObject_GC_Del(inst);\r
- }\r
- else {\r
- Py_ssize_t refcnt = inst->ob_refcnt;\r
- /* __del__ resurrected it! Make it look like the original\r
- * Py_DECREF never happened.\r
- */\r
- _Py_NewReference((PyObject *)inst);\r
- inst->ob_refcnt = refcnt;\r
- _PyObject_GC_TRACK(inst);\r
- /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so\r
- * we need to undo that. */\r
- _Py_DEC_REFTOTAL;\r
- /* If Py_TRACE_REFS, _Py_NewReference re-added self to the\r
- * object chain, so no more to do there.\r
- * If COUNT_ALLOCS, the original decref bumped tp_frees, and\r
- * _Py_NewReference bumped tp_allocs: both of those need to be\r
- * undone.\r
- */\r
-#ifdef COUNT_ALLOCS\r
- --inst->ob_type->tp_frees;\r
- --inst->ob_type->tp_allocs;\r
-#endif\r
- }\r
-}\r
-\r
-static PyObject *\r
-instance_getattr1(register PyInstanceObject *inst, PyObject *name)\r
-{\r
- register PyObject *v;\r
- register char *sname;\r
-\r
- if (!PyString_Check(name)) {\r
- PyErr_SetString(PyExc_TypeError, "attribute name must be a string");\r
- return NULL;\r
- }\r
-\r
- sname = PyString_AsString(name);\r
- if (sname[0] == '_' && sname[1] == '_') {\r
- if (strcmp(sname, "__dict__") == 0) {\r
- if (PyEval_GetRestricted()) {\r
- PyErr_SetString(PyExc_RuntimeError,\r
- "instance.__dict__ not accessible in restricted mode");\r
- return NULL;\r
- }\r
- Py_INCREF(inst->in_dict);\r
- return inst->in_dict;\r
- }\r
- if (strcmp(sname, "__class__") == 0) {\r
- Py_INCREF(inst->in_class);\r
- return (PyObject *)inst->in_class;\r
- }\r
- }\r
- v = instance_getattr2(inst, name);\r
- if (v == NULL && !PyErr_Occurred()) {\r
- PyErr_Format(PyExc_AttributeError,\r
- "%.50s instance has no attribute '%.400s'",\r
- PyString_AS_STRING(inst->in_class->cl_name), sname);\r
- }\r
- return v;\r
-}\r
-\r
-static PyObject *\r
-instance_getattr2(register PyInstanceObject *inst, PyObject *name)\r
-{\r
- register PyObject *v;\r
- PyClassObject *klass;\r
- descrgetfunc f;\r
-\r
- v = PyDict_GetItem(inst->in_dict, name);\r
- if (v != NULL) {\r
- Py_INCREF(v);\r
- return v;\r
- }\r
- v = class_lookup(inst->in_class, name, &klass);\r
- if (v != NULL) {\r
- Py_INCREF(v);\r
- f = TP_DESCR_GET(v->ob_type);\r
- if (f != NULL) {\r
- PyObject *w = f(v, (PyObject *)inst,\r
- (PyObject *)(inst->in_class));\r
- Py_DECREF(v);\r
- v = w;\r
- }\r
- }\r
- return v;\r
-}\r
-\r
-static PyObject *\r
-instance_getattr(register PyInstanceObject *inst, PyObject *name)\r
-{\r
- register PyObject *func, *res;\r
- res = instance_getattr1(inst, name);\r
- if (res == NULL && (func = inst->in_class->cl_getattr) != NULL) {\r
- PyObject *args;\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- args = PyTuple_Pack(2, inst, name);\r
- if (args == NULL)\r
- return NULL;\r
- res = PyEval_CallObject(func, args);\r
- Py_DECREF(args);\r
- }\r
- return res;\r
-}\r
-\r
-/* See classobject.h comments: this only does dict lookups, and is always\r
- * safe to call.\r
- */\r
-PyObject *\r
-_PyInstance_Lookup(PyObject *pinst, PyObject *name)\r
-{\r
- PyObject *v;\r
- PyClassObject *klass;\r
- PyInstanceObject *inst; /* pinst cast to the right type */\r
-\r
- assert(PyInstance_Check(pinst));\r
- inst = (PyInstanceObject *)pinst;\r
-\r
- assert(PyString_Check(name));\r
-\r
- v = PyDict_GetItem(inst->in_dict, name);\r
- if (v == NULL)\r
- v = class_lookup(inst->in_class, name, &klass);\r
- return v;\r
-}\r
-\r
-static int\r
-instance_setattr1(PyInstanceObject *inst, PyObject *name, PyObject *v)\r
-{\r
- if (v == NULL) {\r
- int rv = PyDict_DelItem(inst->in_dict, name);\r
- if (rv < 0)\r
- PyErr_Format(PyExc_AttributeError,\r
- "%.50s instance has no attribute '%.400s'",\r
- PyString_AS_STRING(inst->in_class->cl_name),\r
- PyString_AS_STRING(name));\r
- return rv;\r
- }\r
- else\r
- return PyDict_SetItem(inst->in_dict, name, v);\r
-}\r
-\r
-static int\r
-instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v)\r
-{\r
- PyObject *func, *args, *res, *tmp;\r
- char *sname;\r
-\r
- if (!PyString_Check(name)) {\r
- PyErr_SetString(PyExc_TypeError, "attribute name must be a string");\r
- return -1;\r
- }\r
-\r
- sname = PyString_AsString(name);\r
- if (sname[0] == '_' && sname[1] == '_') {\r
- Py_ssize_t n = PyString_Size(name);\r
- if (sname[n-1] == '_' && sname[n-2] == '_') {\r
- if (strcmp(sname, "__dict__") == 0) {\r
- if (PyEval_GetRestricted()) {\r
- PyErr_SetString(PyExc_RuntimeError,\r
- "__dict__ not accessible in restricted mode");\r
- return -1;\r
- }\r
- if (v == NULL || !PyDict_Check(v)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "__dict__ must be set to a dictionary");\r
- return -1;\r
- }\r
- tmp = inst->in_dict;\r
- Py_INCREF(v);\r
- inst->in_dict = v;\r
- Py_DECREF(tmp);\r
- return 0;\r
- }\r
- if (strcmp(sname, "__class__") == 0) {\r
- if (PyEval_GetRestricted()) {\r
- PyErr_SetString(PyExc_RuntimeError,\r
- "__class__ not accessible in restricted mode");\r
- return -1;\r
- }\r
- if (v == NULL || !PyClass_Check(v)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "__class__ must be set to a class");\r
- return -1;\r
- }\r
- tmp = (PyObject *)(inst->in_class);\r
- Py_INCREF(v);\r
- inst->in_class = (PyClassObject *)v;\r
- Py_DECREF(tmp);\r
- return 0;\r
- }\r
- }\r
- }\r
- if (v == NULL)\r
- func = inst->in_class->cl_delattr;\r
- else\r
- func = inst->in_class->cl_setattr;\r
- if (func == NULL)\r
- return instance_setattr1(inst, name, v);\r
- if (v == NULL)\r
- args = PyTuple_Pack(2, inst, name);\r
- else\r
- args = PyTuple_Pack(3, inst, name, v);\r
- if (args == NULL)\r
- return -1;\r
- res = PyEval_CallObject(func, args);\r
- Py_DECREF(args);\r
- if (res == NULL)\r
- return -1;\r
- Py_DECREF(res);\r
- return 0;\r
-}\r
-\r
-static PyObject *\r
-instance_repr(PyInstanceObject *inst)\r
-{\r
- PyObject *func;\r
- PyObject *res;\r
- static PyObject *reprstr;\r
-\r
- if (reprstr == NULL) {\r
- reprstr = PyString_InternFromString("__repr__");\r
- if (reprstr == NULL)\r
- return NULL;\r
- }\r
- func = instance_getattr(inst, reprstr);\r
- if (func == NULL) {\r
- PyObject *classname, *mod;\r
- char *cname;\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- classname = inst->in_class->cl_name;\r
- mod = PyDict_GetItemString(inst->in_class->cl_dict,\r
- "__module__");\r
- if (classname != NULL && PyString_Check(classname))\r
- cname = PyString_AsString(classname);\r
- else\r
- cname = "?";\r
- if (mod == NULL || !PyString_Check(mod))\r
- return PyString_FromFormat("<?.%s instance at %p>",\r
- cname, inst);\r
- else\r
- return PyString_FromFormat("<%s.%s instance at %p>",\r
- PyString_AsString(mod),\r
- cname, inst);\r
- }\r
- res = PyEval_CallObject(func, (PyObject *)NULL);\r
- Py_DECREF(func);\r
- return res;\r
-}\r
-\r
-static PyObject *\r
-instance_str(PyInstanceObject *inst)\r
-{\r
- PyObject *func;\r
- PyObject *res;\r
- static PyObject *strstr;\r
-\r
- if (strstr == NULL) {\r
- strstr = PyString_InternFromString("__str__");\r
- if (strstr == NULL)\r
- return NULL;\r
- }\r
- func = instance_getattr(inst, strstr);\r
- if (func == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- return instance_repr(inst);\r
- }\r
- res = PyEval_CallObject(func, (PyObject *)NULL);\r
- Py_DECREF(func);\r
- return res;\r
-}\r
-\r
-static long\r
-instance_hash(PyInstanceObject *inst)\r
-{\r
- PyObject *func;\r
- PyObject *res;\r
- long outcome;\r
- static PyObject *hashstr, *eqstr, *cmpstr;\r
-\r
- if (hashstr == NULL) {\r
- hashstr = PyString_InternFromString("__hash__");\r
- if (hashstr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, hashstr);\r
- if (func == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return -1;\r
- PyErr_Clear();\r
- /* If there is no __eq__ and no __cmp__ method, we hash on the\r
- address. If an __eq__ or __cmp__ method exists, there must\r
- be a __hash__. */\r
- if (eqstr == NULL) {\r
- eqstr = PyString_InternFromString("__eq__");\r
- if (eqstr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, eqstr);\r
- if (func == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return -1;\r
- PyErr_Clear();\r
- if (cmpstr == NULL) {\r
- cmpstr = PyString_InternFromString("__cmp__");\r
- if (cmpstr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, cmpstr);\r
- if (func == NULL) {\r
- if (!PyErr_ExceptionMatches(\r
- PyExc_AttributeError))\r
- return -1;\r
- PyErr_Clear();\r
- return _Py_HashPointer(inst);\r
- }\r
- }\r
- Py_XDECREF(func);\r
- PyErr_SetString(PyExc_TypeError, "unhashable instance");\r
- return -1;\r
- }\r
- res = PyEval_CallObject(func, (PyObject *)NULL);\r
- Py_DECREF(func);\r
- if (res == NULL)\r
- return -1;\r
- if (PyInt_Check(res) || PyLong_Check(res))\r
- /* This already converts a -1 result to -2. */\r
- outcome = res->ob_type->tp_hash(res);\r
- else {\r
- PyErr_SetString(PyExc_TypeError,\r
- "__hash__() should return an int");\r
- outcome = -1;\r
- }\r
- Py_DECREF(res);\r
- return outcome;\r
-}\r
-\r
-static int\r
-instance_traverse(PyInstanceObject *o, visitproc visit, void *arg)\r
-{\r
- Py_VISIT(o->in_class);\r
- Py_VISIT(o->in_dict);\r
- return 0;\r
-}\r
-\r
-static PyObject *getitemstr, *setitemstr, *delitemstr, *lenstr;\r
-static PyObject *iterstr, *nextstr;\r
-\r
-static Py_ssize_t\r
-instance_length(PyInstanceObject *inst)\r
-{\r
- PyObject *func;\r
- PyObject *res;\r
- Py_ssize_t outcome;\r
-\r
- if (lenstr == NULL) {\r
- lenstr = PyString_InternFromString("__len__");\r
- if (lenstr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, lenstr);\r
- if (func == NULL)\r
- return -1;\r
- res = PyEval_CallObject(func, (PyObject *)NULL);\r
- Py_DECREF(func);\r
- if (res == NULL)\r
- return -1;\r
- if (PyInt_Check(res)) {\r
- outcome = PyInt_AsSsize_t(res);\r
- if (outcome == -1 && PyErr_Occurred()) {\r
- Py_DECREF(res);\r
- return -1;\r
- }\r
-#if SIZEOF_SIZE_T < SIZEOF_INT\r
- /* Overflow check -- range of PyInt is more than C int */\r
- if (outcome != (int)outcome) {\r
- PyErr_SetString(PyExc_OverflowError,\r
- "__len__() should return 0 <= outcome < 2**31");\r
- outcome = -1;\r
- }\r
- else\r
-#endif\r
- if (outcome < 0) {\r
- PyErr_SetString(PyExc_ValueError,\r
- "__len__() should return >= 0");\r
- outcome = -1;\r
- }\r
- }\r
- else {\r
- PyErr_SetString(PyExc_TypeError,\r
- "__len__() should return an int");\r
- outcome = -1;\r
- }\r
- Py_DECREF(res);\r
- return outcome;\r
-}\r
-\r
-static PyObject *\r
-instance_subscript(PyInstanceObject *inst, PyObject *key)\r
-{\r
- PyObject *func;\r
- PyObject *arg;\r
- PyObject *res;\r
-\r
- if (getitemstr == NULL) {\r
- getitemstr = PyString_InternFromString("__getitem__");\r
- if (getitemstr == NULL)\r
- return NULL;\r
- }\r
- func = instance_getattr(inst, getitemstr);\r
- if (func == NULL)\r
- return NULL;\r
- arg = PyTuple_Pack(1, key);\r
- if (arg == NULL) {\r
- Py_DECREF(func);\r
- return NULL;\r
- }\r
- res = PyEval_CallObject(func, arg);\r
- Py_DECREF(func);\r
- Py_DECREF(arg);\r
- return res;\r
-}\r
-\r
-static int\r
-instance_ass_subscript(PyInstanceObject *inst, PyObject *key, PyObject *value)\r
-{\r
- PyObject *func;\r
- PyObject *arg;\r
- PyObject *res;\r
-\r
- if (value == NULL) {\r
- if (delitemstr == NULL) {\r
- delitemstr = PyString_InternFromString("__delitem__");\r
- if (delitemstr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, delitemstr);\r
- }\r
- else {\r
- if (setitemstr == NULL) {\r
- setitemstr = PyString_InternFromString("__setitem__");\r
- if (setitemstr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, setitemstr);\r
- }\r
- if (func == NULL)\r
- return -1;\r
- if (value == NULL)\r
- arg = PyTuple_Pack(1, key);\r
- else\r
- arg = PyTuple_Pack(2, key, value);\r
- if (arg == NULL) {\r
- Py_DECREF(func);\r
- return -1;\r
- }\r
- res = PyEval_CallObject(func, arg);\r
- Py_DECREF(func);\r
- Py_DECREF(arg);\r
- if (res == NULL)\r
- return -1;\r
- Py_DECREF(res);\r
- return 0;\r
-}\r
-\r
-static PyMappingMethods instance_as_mapping = {\r
- (lenfunc)instance_length, /* mp_length */\r
- (binaryfunc)instance_subscript, /* mp_subscript */\r
- (objobjargproc)instance_ass_subscript, /* mp_ass_subscript */\r
-};\r
-\r
-static PyObject *\r
-instance_item(PyInstanceObject *inst, Py_ssize_t i)\r
-{\r
- PyObject *func, *res;\r
-\r
- if (getitemstr == NULL) {\r
- getitemstr = PyString_InternFromString("__getitem__");\r
- if (getitemstr == NULL)\r
- return NULL;\r
- }\r
- func = instance_getattr(inst, getitemstr);\r
- if (func == NULL)\r
- return NULL;\r
- res = PyObject_CallFunction(func, "n", i);\r
- Py_DECREF(func);\r
- return res;\r
-}\r
-\r
-static PyObject *\r
-instance_slice(PyInstanceObject *inst, Py_ssize_t i, Py_ssize_t j)\r
-{\r
- PyObject *func, *arg, *res;\r
- static PyObject *getslicestr;\r
-\r
- if (getslicestr == NULL) {\r
- getslicestr = PyString_InternFromString("__getslice__");\r
- if (getslicestr == NULL)\r
- return NULL;\r
- }\r
- func = instance_getattr(inst, getslicestr);\r
-\r
- if (func == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
-\r
- if (getitemstr == NULL) {\r
- getitemstr = PyString_InternFromString("__getitem__");\r
- if (getitemstr == NULL)\r
- return NULL;\r
- }\r
- func = instance_getattr(inst, getitemstr);\r
- if (func == NULL)\r
- return NULL;\r
- arg = Py_BuildValue("(N)", _PySlice_FromIndices(i, j));\r
- }\r
- else {\r
- if (PyErr_WarnPy3k("in 3.x, __getslice__ has been removed; "\r
- "use __getitem__", 1) < 0) {\r
- Py_DECREF(func);\r
- return NULL;\r
- }\r
- arg = Py_BuildValue("(nn)", i, j);\r
- }\r
-\r
- if (arg == NULL) {\r
- Py_DECREF(func);\r
- return NULL;\r
- }\r
- res = PyEval_CallObject(func, arg);\r
- Py_DECREF(func);\r
- Py_DECREF(arg);\r
- return res;\r
-}\r
-\r
-static int\r
-instance_ass_item(PyInstanceObject *inst, Py_ssize_t i, PyObject *item)\r
-{\r
- PyObject *func, *arg, *res;\r
-\r
- if (item == NULL) {\r
- if (delitemstr == NULL) {\r
- delitemstr = PyString_InternFromString("__delitem__");\r
- if (delitemstr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, delitemstr);\r
- }\r
- else {\r
- if (setitemstr == NULL) {\r
- setitemstr = PyString_InternFromString("__setitem__");\r
- if (setitemstr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, setitemstr);\r
- }\r
- if (func == NULL)\r
- return -1;\r
- if (item == NULL)\r
- arg = Py_BuildValue("(n)", i);\r
- else\r
- arg = Py_BuildValue("(nO)", i, item);\r
- if (arg == NULL) {\r
- Py_DECREF(func);\r
- return -1;\r
- }\r
- res = PyEval_CallObject(func, arg);\r
- Py_DECREF(func);\r
- Py_DECREF(arg);\r
- if (res == NULL)\r
- return -1;\r
- Py_DECREF(res);\r
- return 0;\r
-}\r
-\r
-static int\r
-instance_ass_slice(PyInstanceObject *inst, Py_ssize_t i, Py_ssize_t j, PyObject *value)\r
-{\r
- PyObject *func, *arg, *res;\r
- static PyObject *setslicestr, *delslicestr;\r
-\r
- if (value == NULL) {\r
- if (delslicestr == NULL) {\r
- delslicestr =\r
- PyString_InternFromString("__delslice__");\r
- if (delslicestr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, delslicestr);\r
- if (func == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return -1;\r
- PyErr_Clear();\r
- if (delitemstr == NULL) {\r
- delitemstr =\r
- PyString_InternFromString("__delitem__");\r
- if (delitemstr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, delitemstr);\r
- if (func == NULL)\r
- return -1;\r
-\r
- arg = Py_BuildValue("(N)",\r
- _PySlice_FromIndices(i, j));\r
- }\r
- else {\r
- if (PyErr_WarnPy3k("in 3.x, __delslice__ has been "\r
- "removed; use __delitem__", 1) < 0) {\r
- Py_DECREF(func);\r
- return -1;\r
- }\r
- arg = Py_BuildValue("(nn)", i, j);\r
- }\r
- }\r
- else {\r
- if (setslicestr == NULL) {\r
- setslicestr =\r
- PyString_InternFromString("__setslice__");\r
- if (setslicestr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, setslicestr);\r
- if (func == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return -1;\r
- PyErr_Clear();\r
- if (setitemstr == NULL) {\r
- setitemstr =\r
- PyString_InternFromString("__setitem__");\r
- if (setitemstr == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, setitemstr);\r
- if (func == NULL)\r
- return -1;\r
-\r
- arg = Py_BuildValue("(NO)",\r
- _PySlice_FromIndices(i, j), value);\r
- }\r
- else {\r
- if (PyErr_WarnPy3k("in 3.x, __setslice__ has been "\r
- "removed; use __setitem__", 1) < 0) {\r
- Py_DECREF(func);\r
- return -1;\r
- }\r
- arg = Py_BuildValue("(nnO)", i, j, value);\r
- }\r
- }\r
- if (arg == NULL) {\r
- Py_DECREF(func);\r
- return -1;\r
- }\r
- res = PyEval_CallObject(func, arg);\r
- Py_DECREF(func);\r
- Py_DECREF(arg);\r
- if (res == NULL)\r
- return -1;\r
- Py_DECREF(res);\r
- return 0;\r
-}\r
-\r
-static int\r
-instance_contains(PyInstanceObject *inst, PyObject *member)\r
-{\r
- static PyObject *__contains__;\r
- PyObject *func;\r
-\r
- /* Try __contains__ first.\r
- * If that can't be done, try iterator-based searching.\r
- */\r
-\r
- if(__contains__ == NULL) {\r
- __contains__ = PyString_InternFromString("__contains__");\r
- if(__contains__ == NULL)\r
- return -1;\r
- }\r
- func = instance_getattr(inst, __contains__);\r
- if (func) {\r
- PyObject *res;\r
- int ret;\r
- PyObject *arg = PyTuple_Pack(1, member);\r
- if(arg == NULL) {\r
- Py_DECREF(func);\r
- return -1;\r
- }\r
- res = PyEval_CallObject(func, arg);\r
- Py_DECREF(func);\r
- Py_DECREF(arg);\r
- if(res == NULL)\r
- return -1;\r
- ret = PyObject_IsTrue(res);\r
- Py_DECREF(res);\r
- return ret;\r
- }\r
-\r
- /* Couldn't find __contains__. */\r
- if (PyErr_ExceptionMatches(PyExc_AttributeError)) {\r
- Py_ssize_t rc;\r
- /* Assume the failure was simply due to that there is no\r
- * __contains__ attribute, and try iterating instead.\r
- */\r
- PyErr_Clear();\r
- rc = _PySequence_IterSearch((PyObject *)inst, member,\r
- PY_ITERSEARCH_CONTAINS);\r
- if (rc >= 0)\r
- return rc > 0;\r
- }\r
- return -1;\r
-}\r
-\r
-static PySequenceMethods\r
-instance_as_sequence = {\r
- (lenfunc)instance_length, /* sq_length */\r
- 0, /* sq_concat */\r
- 0, /* sq_repeat */\r
- (ssizeargfunc)instance_item, /* sq_item */\r
- (ssizessizeargfunc)instance_slice, /* sq_slice */\r
- (ssizeobjargproc)instance_ass_item, /* sq_ass_item */\r
- (ssizessizeobjargproc)instance_ass_slice,/* sq_ass_slice */\r
- (objobjproc)instance_contains, /* sq_contains */\r
-};\r
-\r
-static PyObject *\r
-generic_unary_op(PyInstanceObject *self, PyObject *methodname)\r
-{\r
- PyObject *func, *res;\r
-\r
- if ((func = instance_getattr(self, methodname)) == NULL)\r
- return NULL;\r
- res = PyEval_CallObject(func, (PyObject *)NULL);\r
- Py_DECREF(func);\r
- return res;\r
-}\r
-\r
-static PyObject *\r
-generic_binary_op(PyObject *v, PyObject *w, char *opname)\r
-{\r
- PyObject *result;\r
- PyObject *args;\r
- PyObject *func = PyObject_GetAttrString(v, opname);\r
- if (func == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- Py_INCREF(Py_NotImplemented);\r
- return Py_NotImplemented;\r
- }\r
- args = PyTuple_Pack(1, w);\r
- if (args == NULL) {\r
- Py_DECREF(func);\r
- return NULL;\r
- }\r
- result = PyEval_CallObject(func, args);\r
- Py_DECREF(args);\r
- Py_DECREF(func);\r
- return result;\r
-}\r
-\r
-\r
-static PyObject *coerce_obj;\r
-\r
-/* Try one half of a binary operator involving a class instance. */\r
-static PyObject *\r
-half_binop(PyObject *v, PyObject *w, char *opname, binaryfunc thisfunc,\r
- int swapped)\r
-{\r
- PyObject *args;\r
- PyObject *coercefunc;\r
- PyObject *coerced = NULL;\r
- PyObject *v1;\r
- PyObject *result;\r
-\r
- if (!PyInstance_Check(v)) {\r
- Py_INCREF(Py_NotImplemented);\r
- return Py_NotImplemented;\r
- }\r
-\r
- if (coerce_obj == NULL) {\r
- coerce_obj = PyString_InternFromString("__coerce__");\r
- if (coerce_obj == NULL)\r
- return NULL;\r
- }\r
- coercefunc = PyObject_GetAttr(v, coerce_obj);\r
- if (coercefunc == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- return generic_binary_op(v, w, opname);\r
- }\r
-\r
- args = PyTuple_Pack(1, w);\r
- if (args == NULL) {\r
- Py_DECREF(coercefunc);\r
- return NULL;\r
- }\r
- coerced = PyEval_CallObject(coercefunc, args);\r
- Py_DECREF(args);\r
- Py_DECREF(coercefunc);\r
- if (coerced == NULL) {\r
- return NULL;\r
- }\r
- if (coerced == Py_None || coerced == Py_NotImplemented) {\r
- Py_DECREF(coerced);\r
- return generic_binary_op(v, w, opname);\r
- }\r
- if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) {\r
- Py_DECREF(coerced);\r
- PyErr_SetString(PyExc_TypeError,\r
- "coercion should return None or 2-tuple");\r
- return NULL;\r
- }\r
- v1 = PyTuple_GetItem(coerced, 0);\r
- w = PyTuple_GetItem(coerced, 1);\r
- if (v1->ob_type == v->ob_type && PyInstance_Check(v)) {\r
- /* prevent recursion if __coerce__ returns self as the first\r
- * argument */\r
- result = generic_binary_op(v1, w, opname);\r
- } else {\r
- if (Py_EnterRecursiveCall(" after coercion"))\r
- return NULL;\r
- if (swapped)\r
- result = (thisfunc)(w, v1);\r
- else\r
- result = (thisfunc)(v1, w);\r
- Py_LeaveRecursiveCall();\r
- }\r
- Py_DECREF(coerced);\r
- return result;\r
-}\r
-\r
-/* Implement a binary operator involving at least one class instance. */\r
-static PyObject *\r
-do_binop(PyObject *v, PyObject *w, char *opname, char *ropname,\r
- binaryfunc thisfunc)\r
-{\r
- PyObject *result = half_binop(v, w, opname, thisfunc, 0);\r
- if (result == Py_NotImplemented) {\r
- Py_DECREF(result);\r
- result = half_binop(w, v, ropname, thisfunc, 1);\r
- }\r
- return result;\r
-}\r
-\r
-static PyObject *\r
-do_binop_inplace(PyObject *v, PyObject *w, char *iopname, char *opname,\r
- char *ropname, binaryfunc thisfunc)\r
-{\r
- PyObject *result = half_binop(v, w, iopname, thisfunc, 0);\r
- if (result == Py_NotImplemented) {\r
- Py_DECREF(result);\r
- result = do_binop(v, w, opname, ropname, thisfunc);\r
- }\r
- return result;\r
-}\r
-\r
-static int\r
-instance_coerce(PyObject **pv, PyObject **pw)\r
-{\r
- PyObject *v = *pv;\r
- PyObject *w = *pw;\r
- PyObject *coercefunc;\r
- PyObject *args;\r
- PyObject *coerced;\r
-\r
- if (coerce_obj == NULL) {\r
- coerce_obj = PyString_InternFromString("__coerce__");\r
- if (coerce_obj == NULL)\r
- return -1;\r
- }\r
- coercefunc = PyObject_GetAttr(v, coerce_obj);\r
- if (coercefunc == NULL) {\r
- /* No __coerce__ method */\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return -1;\r
- PyErr_Clear();\r
- return 1;\r
- }\r
- /* Has __coerce__ method: call it */\r
- args = PyTuple_Pack(1, w);\r
- if (args == NULL) {\r
- return -1;\r
- }\r
- coerced = PyEval_CallObject(coercefunc, args);\r
- Py_DECREF(args);\r
- Py_DECREF(coercefunc);\r
- if (coerced == NULL) {\r
- /* __coerce__ call raised an exception */\r
- return -1;\r
- }\r
- if (coerced == Py_None || coerced == Py_NotImplemented) {\r
- /* __coerce__ says "I can't do it" */\r
- Py_DECREF(coerced);\r
- return 1;\r
- }\r
- if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) {\r
- /* __coerce__ return value is malformed */\r
- Py_DECREF(coerced);\r
- PyErr_SetString(PyExc_TypeError,\r
- "coercion should return None or 2-tuple");\r
- return -1;\r
- }\r
- /* __coerce__ returned two new values */\r
- *pv = PyTuple_GetItem(coerced, 0);\r
- *pw = PyTuple_GetItem(coerced, 1);\r
- Py_INCREF(*pv);\r
- Py_INCREF(*pw);\r
- Py_DECREF(coerced);\r
- return 0;\r
-}\r
-\r
-#define UNARY(funcname, methodname) \\r
-static PyObject *funcname(PyInstanceObject *self) { \\r
- static PyObject *o; \\r
- if (o == NULL) { o = PyString_InternFromString(methodname); \\r
- if (o == NULL) return NULL; } \\r
- return generic_unary_op(self, o); \\r
-}\r
-\r
-/* unary function with a fallback */\r
-#define UNARY_FB(funcname, methodname, funcname_fb) \\r
-static PyObject *funcname(PyInstanceObject *self) { \\r
- static PyObject *o; \\r
- if (o == NULL) { o = PyString_InternFromString(methodname); \\r
- if (o == NULL) return NULL; } \\r
- if (PyObject_HasAttr((PyObject*)self, o)) \\r
- return generic_unary_op(self, o); \\r
- else \\r
- return funcname_fb(self); \\r
-}\r
-\r
-#define BINARY(f, m, n) \\r
-static PyObject *f(PyObject *v, PyObject *w) { \\r
- return do_binop(v, w, "__" m "__", "__r" m "__", n); \\r
-}\r
-\r
-#define BINARY_INPLACE(f, m, n) \\r
-static PyObject *f(PyObject *v, PyObject *w) { \\r
- return do_binop_inplace(v, w, "__i" m "__", "__" m "__", \\r
- "__r" m "__", n); \\r
-}\r
-\r
-UNARY(instance_neg, "__neg__")\r
-UNARY(instance_pos, "__pos__")\r
-UNARY(instance_abs, "__abs__")\r
-\r
-BINARY(instance_or, "or", PyNumber_Or)\r
-BINARY(instance_and, "and", PyNumber_And)\r
-BINARY(instance_xor, "xor", PyNumber_Xor)\r
-BINARY(instance_lshift, "lshift", PyNumber_Lshift)\r
-BINARY(instance_rshift, "rshift", PyNumber_Rshift)\r
-BINARY(instance_add, "add", PyNumber_Add)\r
-BINARY(instance_sub, "sub", PyNumber_Subtract)\r
-BINARY(instance_mul, "mul", PyNumber_Multiply)\r
-BINARY(instance_div, "div", PyNumber_Divide)\r
-BINARY(instance_mod, "mod", PyNumber_Remainder)\r
-BINARY(instance_divmod, "divmod", PyNumber_Divmod)\r
-BINARY(instance_floordiv, "floordiv", PyNumber_FloorDivide)\r
-BINARY(instance_truediv, "truediv", PyNumber_TrueDivide)\r
-\r
-BINARY_INPLACE(instance_ior, "or", PyNumber_InPlaceOr)\r
-BINARY_INPLACE(instance_ixor, "xor", PyNumber_InPlaceXor)\r
-BINARY_INPLACE(instance_iand, "and", PyNumber_InPlaceAnd)\r
-BINARY_INPLACE(instance_ilshift, "lshift", PyNumber_InPlaceLshift)\r
-BINARY_INPLACE(instance_irshift, "rshift", PyNumber_InPlaceRshift)\r
-BINARY_INPLACE(instance_iadd, "add", PyNumber_InPlaceAdd)\r
-BINARY_INPLACE(instance_isub, "sub", PyNumber_InPlaceSubtract)\r
-BINARY_INPLACE(instance_imul, "mul", PyNumber_InPlaceMultiply)\r
-BINARY_INPLACE(instance_idiv, "div", PyNumber_InPlaceDivide)\r
-BINARY_INPLACE(instance_imod, "mod", PyNumber_InPlaceRemainder)\r
-BINARY_INPLACE(instance_ifloordiv, "floordiv", PyNumber_InPlaceFloorDivide)\r
-BINARY_INPLACE(instance_itruediv, "truediv", PyNumber_InPlaceTrueDivide)\r
-\r
-/* Try a 3-way comparison, returning an int; v is an instance. Return:\r
- -2 for an exception;\r
- -1 if v < w;\r
- 0 if v == w;\r
- 1 if v > w;\r
- 2 if this particular 3-way comparison is not implemented or undefined.\r
-*/\r
-static int\r
-half_cmp(PyObject *v, PyObject *w)\r
-{\r
- static PyObject *cmp_obj;\r
- PyObject *args;\r
- PyObject *cmp_func;\r
- PyObject *result;\r
- long l;\r
-\r
- assert(PyInstance_Check(v));\r
-\r
- if (cmp_obj == NULL) {\r
- cmp_obj = PyString_InternFromString("__cmp__");\r
- if (cmp_obj == NULL)\r
- return -2;\r
- }\r
-\r
- cmp_func = PyObject_GetAttr(v, cmp_obj);\r
- if (cmp_func == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return -2;\r
- PyErr_Clear();\r
- return 2;\r
- }\r
-\r
- args = PyTuple_Pack(1, w);\r
- if (args == NULL) {\r
- Py_DECREF(cmp_func);\r
- return -2;\r
- }\r
-\r
- result = PyEval_CallObject(cmp_func, args);\r
- Py_DECREF(args);\r
- Py_DECREF(cmp_func);\r
-\r
- if (result == NULL)\r
- return -2;\r
-\r
- if (result == Py_NotImplemented) {\r
- Py_DECREF(result);\r
- return 2;\r
- }\r
-\r
- l = PyInt_AsLong(result);\r
- Py_DECREF(result);\r
- if (l == -1 && PyErr_Occurred()) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "comparison did not return an int");\r
- return -2;\r
- }\r
-\r
- return l < 0 ? -1 : l > 0 ? 1 : 0;\r
-}\r
-\r
-/* Try a 3-way comparison, returning an int; either v or w is an instance.\r
- We first try a coercion. Return:\r
- -2 for an exception;\r
- -1 if v < w;\r
- 0 if v == w;\r
- 1 if v > w;\r
- 2 if this particular 3-way comparison is not implemented or undefined.\r
- THIS IS ONLY CALLED FROM object.c!\r
-*/\r
-static int\r
-instance_compare(PyObject *v, PyObject *w)\r
-{\r
- int c;\r
-\r
- c = PyNumber_CoerceEx(&v, &w);\r
- if (c < 0)\r
- return -2;\r
- if (c == 0) {\r
- /* If neither is now an instance, use regular comparison */\r
- if (!PyInstance_Check(v) && !PyInstance_Check(w)) {\r
- c = PyObject_Compare(v, w);\r
- Py_DECREF(v);\r
- Py_DECREF(w);\r
- if (PyErr_Occurred())\r
- return -2;\r
- return c < 0 ? -1 : c > 0 ? 1 : 0;\r
- }\r
- }\r
- else {\r
- /* The coercion didn't do anything.\r
- Treat this the same as returning v and w unchanged. */\r
- Py_INCREF(v);\r
- Py_INCREF(w);\r
- }\r
-\r
- if (PyInstance_Check(v)) {\r
- c = half_cmp(v, w);\r
- if (c <= 1) {\r
- Py_DECREF(v);\r
- Py_DECREF(w);\r
- return c;\r
- }\r
- }\r
- if (PyInstance_Check(w)) {\r
- c = half_cmp(w, v);\r
- if (c <= 1) {\r
- Py_DECREF(v);\r
- Py_DECREF(w);\r
- if (c >= -1)\r
- c = -c;\r
- return c;\r
- }\r
- }\r
- Py_DECREF(v);\r
- Py_DECREF(w);\r
- return 2;\r
-}\r
-\r
-static int\r
-instance_nonzero(PyInstanceObject *self)\r
-{\r
- PyObject *func, *res;\r
- long outcome;\r
- static PyObject *nonzerostr;\r
-\r
- if (nonzerostr == NULL) {\r
- nonzerostr = PyString_InternFromString("__nonzero__");\r
- if (nonzerostr == NULL)\r
- return -1;\r
- }\r
- if ((func = instance_getattr(self, nonzerostr)) == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return -1;\r
- PyErr_Clear();\r
- if (lenstr == NULL) {\r
- lenstr = PyString_InternFromString("__len__");\r
- if (lenstr == NULL)\r
- return -1;\r
- }\r
- if ((func = instance_getattr(self, lenstr)) == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return -1;\r
- PyErr_Clear();\r
- /* Fall back to the default behavior:\r
- all instances are nonzero */\r
- return 1;\r
- }\r
- }\r
- res = PyEval_CallObject(func, (PyObject *)NULL);\r
- Py_DECREF(func);\r
- if (res == NULL)\r
- return -1;\r
- if (!PyInt_Check(res)) {\r
- Py_DECREF(res);\r
- PyErr_SetString(PyExc_TypeError,\r
- "__nonzero__ should return an int");\r
- return -1;\r
- }\r
- outcome = PyInt_AsLong(res);\r
- Py_DECREF(res);\r
- if (outcome < 0) {\r
- PyErr_SetString(PyExc_ValueError,\r
- "__nonzero__ should return >= 0");\r
- return -1;\r
- }\r
- return outcome > 0;\r
-}\r
-\r
-static PyObject *\r
-instance_index(PyInstanceObject *self)\r
-{\r
- PyObject *func, *res;\r
- static PyObject *indexstr = NULL;\r
-\r
- if (indexstr == NULL) {\r
- indexstr = PyString_InternFromString("__index__");\r
- if (indexstr == NULL)\r
- return NULL;\r
- }\r
- if ((func = instance_getattr(self, indexstr)) == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- PyErr_SetString(PyExc_TypeError,\r
- "object cannot be interpreted as an index");\r
- return NULL;\r
- }\r
- res = PyEval_CallObject(func, (PyObject *)NULL);\r
- Py_DECREF(func);\r
- return res;\r
-}\r
-\r
-\r
-UNARY(instance_invert, "__invert__")\r
-UNARY(_instance_trunc, "__trunc__")\r
-\r
-static PyObject *\r
-instance_int(PyInstanceObject *self)\r
-{\r
- PyObject *truncated;\r
- static PyObject *int_name;\r
- if (int_name == NULL) {\r
- int_name = PyString_InternFromString("__int__");\r
- if (int_name == NULL)\r
- return NULL;\r
- }\r
- if (PyObject_HasAttr((PyObject*)self, int_name))\r
- return generic_unary_op(self, int_name);\r
-\r
- truncated = _instance_trunc(self);\r
- /* __trunc__ is specified to return an Integral type, but\r
- int() needs to return an int. */\r
- return _PyNumber_ConvertIntegralToInt(\r
- truncated,\r
- "__trunc__ returned non-Integral (type %.200s)");\r
-}\r
-\r
-UNARY_FB(instance_long, "__long__", instance_int)\r
-UNARY(instance_float, "__float__")\r
-UNARY(instance_oct, "__oct__")\r
-UNARY(instance_hex, "__hex__")\r
-\r
-static PyObject *\r
-bin_power(PyObject *v, PyObject *w)\r
-{\r
- return PyNumber_Power(v, w, Py_None);\r
-}\r
-\r
-/* This version is for ternary calls only (z != None) */\r
-static PyObject *\r
-instance_pow(PyObject *v, PyObject *w, PyObject *z)\r
-{\r
- if (z == Py_None) {\r
- return do_binop(v, w, "__pow__", "__rpow__", bin_power);\r
- }\r
- else {\r
- PyObject *func;\r
- PyObject *args;\r
- PyObject *result;\r
-\r
- /* XXX Doesn't do coercions... */\r
- func = PyObject_GetAttrString(v, "__pow__");\r
- if (func == NULL)\r
- return NULL;\r
- args = PyTuple_Pack(2, w, z);\r
- if (args == NULL) {\r
- Py_DECREF(func);\r
- return NULL;\r
- }\r
- result = PyEval_CallObject(func, args);\r
- Py_DECREF(func);\r
- Py_DECREF(args);\r
- return result;\r
- }\r
-}\r
-\r
-static PyObject *\r
-bin_inplace_power(PyObject *v, PyObject *w)\r
-{\r
- return PyNumber_InPlacePower(v, w, Py_None);\r
-}\r
-\r
-\r
-static PyObject *\r
-instance_ipow(PyObject *v, PyObject *w, PyObject *z)\r
-{\r
- if (z == Py_None) {\r
- return do_binop_inplace(v, w, "__ipow__", "__pow__",\r
- "__rpow__", bin_inplace_power);\r
- }\r
- else {\r
- /* XXX Doesn't do coercions... */\r
- PyObject *func;\r
- PyObject *args;\r
- PyObject *result;\r
-\r
- func = PyObject_GetAttrString(v, "__ipow__");\r
- if (func == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- return instance_pow(v, w, z);\r
- }\r
- args = PyTuple_Pack(2, w, z);\r
- if (args == NULL) {\r
- Py_DECREF(func);\r
- return NULL;\r
- }\r
- result = PyEval_CallObject(func, args);\r
- Py_DECREF(func);\r
- Py_DECREF(args);\r
- return result;\r
- }\r
-}\r
-\r
-\r
-/* Map rich comparison operators to their __xx__ namesakes */\r
-#define NAME_OPS 6\r
-static PyObject **name_op = NULL;\r
-\r
-static int\r
-init_name_op(void)\r
-{\r
- int i;\r
- char *_name_op[] = {\r
- "__lt__",\r
- "__le__",\r
- "__eq__",\r
- "__ne__",\r
- "__gt__",\r
- "__ge__",\r
- };\r
-\r
- name_op = (PyObject **)malloc(sizeof(PyObject *) * NAME_OPS);\r
- if (name_op == NULL)\r
- return -1;\r
- for (i = 0; i < NAME_OPS; ++i) {\r
- name_op[i] = PyString_InternFromString(_name_op[i]);\r
- if (name_op[i] == NULL)\r
- return -1;\r
- }\r
- return 0;\r
-}\r
-\r
-static PyObject *\r
-half_richcompare(PyObject *v, PyObject *w, int op)\r
-{\r
- PyObject *method;\r
- PyObject *args;\r
- PyObject *res;\r
-\r
- assert(PyInstance_Check(v));\r
-\r
- if (name_op == NULL) {\r
- if (init_name_op() < 0)\r
- return NULL;\r
- }\r
- /* If the instance doesn't define an __getattr__ method, use\r
- instance_getattr2 directly because it will not set an\r
- exception on failure. */\r
- if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL)\r
- method = instance_getattr2((PyInstanceObject *)v,\r
- name_op[op]);\r
- else\r
- method = PyObject_GetAttr(v, name_op[op]);\r
- if (method == NULL) {\r
- if (PyErr_Occurred()) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- }\r
- res = Py_NotImplemented;\r
- Py_INCREF(res);\r
- return res;\r
- }\r
-\r
- args = PyTuple_Pack(1, w);\r
- if (args == NULL) {\r
- Py_DECREF(method);\r
- return NULL;\r
- }\r
-\r
- res = PyEval_CallObject(method, args);\r
- Py_DECREF(args);\r
- Py_DECREF(method);\r
-\r
- return res;\r
-}\r
-\r
-static PyObject *\r
-instance_richcompare(PyObject *v, PyObject *w, int op)\r
-{\r
- PyObject *res;\r
-\r
- if (PyInstance_Check(v)) {\r
- res = half_richcompare(v, w, op);\r
- if (res != Py_NotImplemented)\r
- return res;\r
- Py_DECREF(res);\r
- }\r
-\r
- if (PyInstance_Check(w)) {\r
- res = half_richcompare(w, v, _Py_SwappedOp[op]);\r
- if (res != Py_NotImplemented)\r
- return res;\r
- Py_DECREF(res);\r
- }\r
-\r
- Py_INCREF(Py_NotImplemented);\r
- return Py_NotImplemented;\r
-}\r
-\r
-\r
-/* Get the iterator */\r
-static PyObject *\r
-instance_getiter(PyInstanceObject *self)\r
-{\r
- PyObject *func;\r
-\r
- if (iterstr == NULL) {\r
- iterstr = PyString_InternFromString("__iter__");\r
- if (iterstr == NULL)\r
- return NULL;\r
- }\r
- if (getitemstr == NULL) {\r
- getitemstr = PyString_InternFromString("__getitem__");\r
- if (getitemstr == NULL)\r
- return NULL;\r
- }\r
-\r
- if ((func = instance_getattr(self, iterstr)) != NULL) {\r
- PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);\r
- Py_DECREF(func);\r
- if (res != NULL && !PyIter_Check(res)) {\r
- PyErr_Format(PyExc_TypeError,\r
- "__iter__ returned non-iterator "\r
- "of type '%.100s'",\r
- res->ob_type->tp_name);\r
- Py_DECREF(res);\r
- res = NULL;\r
- }\r
- return res;\r
- }\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- if ((func = instance_getattr(self, getitemstr)) == NULL) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "iteration over non-sequence");\r
- return NULL;\r
- }\r
- Py_DECREF(func);\r
- return PySeqIter_New((PyObject *)self);\r
-}\r
-\r
-\r
-/* Call the iterator's next */\r
-static PyObject *\r
-instance_iternext(PyInstanceObject *self)\r
-{\r
- PyObject *func;\r
-\r
- if (nextstr == NULL) {\r
- nextstr = PyString_InternFromString("next");\r
- if (nextstr == NULL)\r
- return NULL;\r
- }\r
-\r
- if ((func = instance_getattr(self, nextstr)) != NULL) {\r
- PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);\r
- Py_DECREF(func);\r
- if (res != NULL) {\r
- return res;\r
- }\r
- if (PyErr_ExceptionMatches(PyExc_StopIteration)) {\r
- PyErr_Clear();\r
- return NULL;\r
- }\r
- return NULL;\r
- }\r
- PyErr_SetString(PyExc_TypeError, "instance has no next() method");\r
- return NULL;\r
-}\r
-\r
-static PyObject *\r
-instance_call(PyObject *func, PyObject *arg, PyObject *kw)\r
-{\r
- PyObject *res, *call = PyObject_GetAttrString(func, "__call__");\r
- if (call == NULL) {\r
- PyInstanceObject *inst = (PyInstanceObject*) func;\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- PyErr_Format(PyExc_AttributeError,\r
- "%.200s instance has no __call__ method",\r
- PyString_AsString(inst->in_class->cl_name));\r
- return NULL;\r
- }\r
- /* We must check and increment the recursion depth here. Scenario:\r
- class A:\r
- pass\r
- A.__call__ = A() # that's right\r
- a = A() # ok\r
- a() # infinite recursion\r
- This bounces between instance_call() and PyObject_Call() without\r
- ever hitting eval_frame() (which has the main recursion check). */\r
- if (Py_EnterRecursiveCall(" in __call__")) {\r
- res = NULL;\r
- }\r
- else {\r
- res = PyObject_Call(call, arg, kw);\r
- Py_LeaveRecursiveCall();\r
- }\r
- Py_DECREF(call);\r
- return res;\r
-}\r
-\r
-\r
-static PyNumberMethods instance_as_number = {\r
- instance_add, /* nb_add */\r
- instance_sub, /* nb_subtract */\r
- instance_mul, /* nb_multiply */\r
- instance_div, /* nb_divide */\r
- instance_mod, /* nb_remainder */\r
- instance_divmod, /* nb_divmod */\r
- instance_pow, /* nb_power */\r
- (unaryfunc)instance_neg, /* nb_negative */\r
- (unaryfunc)instance_pos, /* nb_positive */\r
- (unaryfunc)instance_abs, /* nb_absolute */\r
- (inquiry)instance_nonzero, /* nb_nonzero */\r
- (unaryfunc)instance_invert, /* nb_invert */\r
- instance_lshift, /* nb_lshift */\r
- instance_rshift, /* nb_rshift */\r
- instance_and, /* nb_and */\r
- instance_xor, /* nb_xor */\r
- instance_or, /* nb_or */\r
- instance_coerce, /* nb_coerce */\r
- (unaryfunc)instance_int, /* nb_int */\r
- (unaryfunc)instance_long, /* nb_long */\r
- (unaryfunc)instance_float, /* nb_float */\r
- (unaryfunc)instance_oct, /* nb_oct */\r
- (unaryfunc)instance_hex, /* nb_hex */\r
- instance_iadd, /* nb_inplace_add */\r
- instance_isub, /* nb_inplace_subtract */\r
- instance_imul, /* nb_inplace_multiply */\r
- instance_idiv, /* nb_inplace_divide */\r
- instance_imod, /* nb_inplace_remainder */\r
- instance_ipow, /* nb_inplace_power */\r
- instance_ilshift, /* nb_inplace_lshift */\r
- instance_irshift, /* nb_inplace_rshift */\r
- instance_iand, /* nb_inplace_and */\r
- instance_ixor, /* nb_inplace_xor */\r
- instance_ior, /* nb_inplace_or */\r
- instance_floordiv, /* nb_floor_divide */\r
- instance_truediv, /* nb_true_divide */\r
- instance_ifloordiv, /* nb_inplace_floor_divide */\r
- instance_itruediv, /* nb_inplace_true_divide */\r
- (unaryfunc)instance_index, /* nb_index */\r
-};\r
-\r
-PyTypeObject PyInstance_Type = {\r
- PyObject_HEAD_INIT(&PyType_Type)\r
- 0,\r
- "instance",\r
- sizeof(PyInstanceObject),\r
- 0,\r
- (destructor)instance_dealloc, /* tp_dealloc */\r
- 0, /* tp_print */\r
- 0, /* tp_getattr */\r
- 0, /* tp_setattr */\r
- instance_compare, /* tp_compare */\r
- (reprfunc)instance_repr, /* tp_repr */\r
- &instance_as_number, /* tp_as_number */\r
- &instance_as_sequence, /* tp_as_sequence */\r
- &instance_as_mapping, /* tp_as_mapping */\r
- (hashfunc)instance_hash, /* tp_hash */\r
- instance_call, /* tp_call */\r
- (reprfunc)instance_str, /* tp_str */\r
- (getattrofunc)instance_getattr, /* tp_getattro */\r
- (setattrofunc)instance_setattr, /* tp_setattro */\r
- 0, /* tp_as_buffer */\r
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES,/*tp_flags*/\r
- instance_doc, /* tp_doc */\r
- (traverseproc)instance_traverse, /* tp_traverse */\r
- 0, /* tp_clear */\r
- instance_richcompare, /* tp_richcompare */\r
- offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */\r
- (getiterfunc)instance_getiter, /* tp_iter */\r
- (iternextfunc)instance_iternext, /* tp_iternext */\r
- 0, /* tp_methods */\r
- 0, /* tp_members */\r
- 0, /* tp_getset */\r
- 0, /* tp_base */\r
- 0, /* tp_dict */\r
- 0, /* tp_descr_get */\r
- 0, /* tp_descr_set */\r
- 0, /* tp_dictoffset */\r
- 0, /* tp_init */\r
- 0, /* tp_alloc */\r
- instance_new, /* tp_new */\r
-};\r
-\r
-\r
-/* Instance method objects are used for two purposes:\r
- (a) as bound instance methods (returned by instancename.methodname)\r
- (b) as unbound methods (returned by ClassName.methodname)\r
- In case (b), im_self is NULL\r
-*/\r
-\r
-PyObject *\r
-PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)\r
-{\r
- register PyMethodObject *im;\r
- im = free_list;\r
- if (im != NULL) {\r
- free_list = (PyMethodObject *)(im->im_self);\r
- PyObject_INIT(im, &PyMethod_Type);\r
- numfree--;\r
- }\r
- else {\r
- im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);\r
- if (im == NULL)\r
- return NULL;\r
- }\r
- im->im_weakreflist = NULL;\r
- Py_INCREF(func);\r
- im->im_func = func;\r
- Py_XINCREF(self);\r
- im->im_self = self;\r
- Py_XINCREF(klass);\r
- im->im_class = klass;\r
- _PyObject_GC_TRACK(im);\r
- return (PyObject *)im;\r
-}\r
-\r
-/* Descriptors for PyMethod attributes */\r
-\r
-/* im_class, im_func and im_self are stored in the PyMethod object */\r
-\r
-#define OFF(x) offsetof(PyMethodObject, x)\r
-\r
-static PyMemberDef instancemethod_memberlist[] = {\r
- {"im_class", T_OBJECT, OFF(im_class), READONLY|RESTRICTED,\r
- "the class associated with a method"},\r
- {"im_func", T_OBJECT, OFF(im_func), READONLY|RESTRICTED,\r
- "the function (or other callable) implementing a method"},\r
- {"__func__", T_OBJECT, OFF(im_func), READONLY|RESTRICTED,\r
- "the function (or other callable) implementing a method"},\r
- {"im_self", T_OBJECT, OFF(im_self), READONLY|RESTRICTED,\r
- "the instance to which a method is bound; None for unbound methods"},\r
- {"__self__", T_OBJECT, OFF(im_self), READONLY|RESTRICTED,\r
- "the instance to which a method is bound; None for unbound methods"},\r
- {NULL} /* Sentinel */\r
-};\r
-\r
-/* Christian Tismer argued convincingly that method attributes should\r
- (nearly) always override function attributes.\r
- The one exception is __doc__; there's a default __doc__ which\r
- should only be used for the class, not for instances */\r
-\r
-static PyObject *\r
-instancemethod_get_doc(PyMethodObject *im, void *context)\r
-{\r
- static PyObject *docstr;\r
- if (docstr == NULL) {\r
- docstr= PyString_InternFromString("__doc__");\r
- if (docstr == NULL)\r
- return NULL;\r
- }\r
- return PyObject_GetAttr(im->im_func, docstr);\r
-}\r
-\r
-static PyGetSetDef instancemethod_getset[] = {\r
- {"__doc__", (getter)instancemethod_get_doc, NULL, NULL},\r
- {0}\r
-};\r
-\r
-static PyObject *\r
-instancemethod_getattro(PyObject *obj, PyObject *name)\r
-{\r
- PyMethodObject *im = (PyMethodObject *)obj;\r
- PyTypeObject *tp = obj->ob_type;\r
- PyObject *descr = NULL;\r
-\r
- if (PyType_HasFeature(tp, Py_TPFLAGS_HAVE_CLASS)) {\r
- if (tp->tp_dict == NULL) {\r
- if (PyType_Ready(tp) < 0)\r
- return NULL;\r
- }\r
- descr = _PyType_Lookup(tp, name);\r
- }\r
-\r
- if (descr != NULL) {\r
- descrgetfunc f = TP_DESCR_GET(descr->ob_type);\r
- if (f != NULL)\r
- return f(descr, obj, (PyObject *)obj->ob_type);\r
- else {\r
- Py_INCREF(descr);\r
- return descr;\r
- }\r
- }\r
-\r
- return PyObject_GetAttr(im->im_func, name);\r
-}\r
-\r
-PyDoc_STRVAR(instancemethod_doc,\r
-"instancemethod(function, instance, class)\n\\r
-\n\\r
-Create an instance method object.");\r
-\r
-static PyObject *\r
-instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw)\r
-{\r
- PyObject *func;\r
- PyObject *self;\r
- PyObject *classObj = NULL;\r
-\r
- if (!_PyArg_NoKeywords("instancemethod", kw))\r
- return NULL;\r
- if (!PyArg_UnpackTuple(args, "instancemethod", 2, 3,\r
- &func, &self, &classObj))\r
- return NULL;\r
- if (!PyCallable_Check(func)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "first argument must be callable");\r
- return NULL;\r
- }\r
- if (self == Py_None)\r
- self = NULL;\r
- if (self == NULL && classObj == NULL) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "unbound methods must have non-NULL im_class");\r
- return NULL;\r
- }\r
-\r
- return PyMethod_New(func, self, classObj);\r
-}\r
-\r
-static void\r
-instancemethod_dealloc(register PyMethodObject *im)\r
-{\r
- _PyObject_GC_UNTRACK(im);\r
- if (im->im_weakreflist != NULL)\r
- PyObject_ClearWeakRefs((PyObject *)im);\r
- Py_DECREF(im->im_func);\r
- Py_XDECREF(im->im_self);\r
- Py_XDECREF(im->im_class);\r
- if (numfree < PyMethod_MAXFREELIST) {\r
- im->im_self = (PyObject *)free_list;\r
- free_list = im;\r
- numfree++;\r
- }\r
- else {\r
- PyObject_GC_Del(im);\r
- }\r
-}\r
-\r
-static int\r
-instancemethod_compare(PyMethodObject *a, PyMethodObject *b)\r
-{\r
- int cmp;\r
- cmp = PyObject_Compare(a->im_func, b->im_func);\r
- if (cmp)\r
- return cmp;\r
-\r
- if (a->im_self == b->im_self)\r
- return 0;\r
- if (a->im_self == NULL || b->im_self == NULL)\r
- return (a->im_self < b->im_self) ? -1 : 1;\r
- else\r
- return PyObject_Compare(a->im_self, b->im_self);\r
-}\r
-\r
-static PyObject *\r
-instancemethod_repr(PyMethodObject *a)\r
-{\r
- PyObject *self = a->im_self;\r
- PyObject *func = a->im_func;\r
- PyObject *klass = a->im_class;\r
- PyObject *funcname = NULL, *klassname = NULL, *result = NULL;\r
- char *sfuncname = "?", *sklassname = "?";\r
-\r
- funcname = PyObject_GetAttrString(func, "__name__");\r
- if (funcname == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- }\r
- else if (!PyString_Check(funcname)) {\r
- Py_DECREF(funcname);\r
- funcname = NULL;\r
- }\r
- else\r
- sfuncname = PyString_AS_STRING(funcname);\r
- if (klass == NULL)\r
- klassname = NULL;\r
- else {\r
- klassname = PyObject_GetAttrString(klass, "__name__");\r
- if (klassname == NULL) {\r
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))\r
- return NULL;\r
- PyErr_Clear();\r
- }\r
- else if (!PyString_Check(klassname)) {\r
- Py_DECREF(klassname);\r
- klassname = NULL;\r
- }\r
- else\r
- sklassname = PyString_AS_STRING(klassname);\r
- }\r
- if (self == NULL)\r
- result = PyString_FromFormat("<unbound method %s.%s>",\r
- sklassname, sfuncname);\r
- else {\r
- /* XXX Shouldn't use repr() here! */\r
- PyObject *selfrepr = PyObject_Repr(self);\r
- if (selfrepr == NULL)\r
- goto fail;\r
- if (!PyString_Check(selfrepr)) {\r
- Py_DECREF(selfrepr);\r
- goto fail;\r
- }\r
- result = PyString_FromFormat("<bound method %s.%s of %s>",\r
- sklassname, sfuncname,\r
- PyString_AS_STRING(selfrepr));\r
- Py_DECREF(selfrepr);\r
- }\r
- fail:\r
- Py_XDECREF(funcname);\r
- Py_XDECREF(klassname);\r
- return result;\r
-}\r
-\r
-static long\r
-instancemethod_hash(PyMethodObject *a)\r
-{\r
- long x, y;\r
- if (a->im_self == NULL)\r
- x = PyObject_Hash(Py_None);\r
- else\r
- x = PyObject_Hash(a->im_self);\r
- if (x == -1)\r
- return -1;\r
- y = PyObject_Hash(a->im_func);\r
- if (y == -1)\r
- return -1;\r
- x = x ^ y;\r
- if (x == -1)\r
- x = -2;\r
- return x;\r
-}\r
-\r
-static int\r
-instancemethod_traverse(PyMethodObject *im, visitproc visit, void *arg)\r
-{\r
- Py_VISIT(im->im_func);\r
- Py_VISIT(im->im_self);\r
- Py_VISIT(im->im_class);\r
- return 0;\r
-}\r
-\r
-static void\r
-getclassname(PyObject *klass, char *buf, int bufsize)\r
-{\r
- PyObject *name;\r
-\r
- assert(bufsize > 1);\r
- strcpy(buf, "?"); /* Default outcome */\r
- if (klass == NULL)\r
- return;\r
- name = PyObject_GetAttrString(klass, "__name__");\r
- if (name == NULL) {\r
- /* This function cannot return an exception */\r
- PyErr_Clear();\r
- return;\r
- }\r
- if (PyString_Check(name)) {\r
- strncpy(buf, PyString_AS_STRING(name), bufsize);\r
- buf[bufsize-1] = '\0';\r
- }\r
- Py_DECREF(name);\r
-}\r
-\r
-static void\r
-getinstclassname(PyObject *inst, char *buf, int bufsize)\r
-{\r
- PyObject *klass;\r
-\r
- if (inst == NULL) {\r
- assert(bufsize > 0 && (size_t)bufsize > strlen("nothing"));\r
- strcpy(buf, "nothing");\r
- return;\r
- }\r
-\r
- klass = PyObject_GetAttrString(inst, "__class__");\r
- if (klass == NULL) {\r
- /* This function cannot return an exception */\r
- PyErr_Clear();\r
- klass = (PyObject *)(inst->ob_type);\r
- Py_INCREF(klass);\r
- }\r
- getclassname(klass, buf, bufsize);\r
- Py_XDECREF(klass);\r
-}\r
-\r
-static PyObject *\r
-instancemethod_call(PyObject *func, PyObject *arg, PyObject *kw)\r
-{\r
- PyObject *self = PyMethod_GET_SELF(func);\r
- PyObject *klass = PyMethod_GET_CLASS(func);\r
- PyObject *result;\r
-\r
- func = PyMethod_GET_FUNCTION(func);\r
- if (self == NULL) {\r
- /* Unbound methods must be called with an instance of\r
- the class (or a derived class) as first argument */\r
- int ok;\r
- if (PyTuple_Size(arg) >= 1)\r
- self = PyTuple_GET_ITEM(arg, 0);\r
- if (self == NULL)\r
- ok = 0;\r
- else {\r
- ok = PyObject_IsInstance(self, klass);\r
- if (ok < 0)\r
- return NULL;\r
- }\r
- if (!ok) {\r
- char clsbuf[256];\r
- char instbuf[256];\r
- getclassname(klass, clsbuf, sizeof(clsbuf));\r
- getinstclassname(self, instbuf, sizeof(instbuf));\r
- PyErr_Format(PyExc_TypeError,\r
- "unbound method %s%s must be called with "\r
- "%s instance as first argument "\r
- "(got %s%s instead)",\r
- PyEval_GetFuncName(func),\r
- PyEval_GetFuncDesc(func),\r
- clsbuf,\r
- instbuf,\r
- self == NULL ? "" : " instance");\r
- return NULL;\r
- }\r
- Py_INCREF(arg);\r
- }\r
- else {\r
- Py_ssize_t argcount = PyTuple_Size(arg);\r
- PyObject *newarg = PyTuple_New(argcount + 1);\r
- int i;\r
- if (newarg == NULL)\r
- return NULL;\r
- Py_INCREF(self);\r
- PyTuple_SET_ITEM(newarg, 0, self);\r
- for (i = 0; i < argcount; i++) {\r
- PyObject *v = PyTuple_GET_ITEM(arg, i);\r
- Py_XINCREF(v);\r
- PyTuple_SET_ITEM(newarg, i+1, v);\r
- }\r
- arg = newarg;\r
- }\r
- result = PyObject_Call((PyObject *)func, arg, kw);\r
- Py_DECREF(arg);\r
- return result;\r
-}\r
-\r
-static PyObject *\r
-instancemethod_descr_get(PyObject *meth, PyObject *obj, PyObject *cls)\r
-{\r
- /* Don't rebind an already bound method, or an unbound method\r
- of a class that's not a base class of cls. */\r
-\r
- if (PyMethod_GET_SELF(meth) != NULL) {\r
- /* Already bound */\r
- Py_INCREF(meth);\r
- return meth;\r
- }\r
- /* No, it is an unbound method */\r
- if (PyMethod_GET_CLASS(meth) != NULL && cls != NULL) {\r
- /* Do subclass test. If it fails, return meth unchanged. */\r
- int ok = PyObject_IsSubclass(cls, PyMethod_GET_CLASS(meth));\r
- if (ok < 0)\r
- return NULL;\r
- if (!ok) {\r
- Py_INCREF(meth);\r
- return meth;\r
- }\r
- }\r
- /* Bind it to obj */\r
- return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, cls);\r
-}\r
-\r
-PyTypeObject PyMethod_Type = {\r
- PyObject_HEAD_INIT(&PyType_Type)\r
- 0,\r
- "instancemethod",\r
- sizeof(PyMethodObject),\r
- 0,\r
- (destructor)instancemethod_dealloc, /* tp_dealloc */\r
- 0, /* tp_print */\r
- 0, /* tp_getattr */\r
- 0, /* tp_setattr */\r
- (cmpfunc)instancemethod_compare, /* tp_compare */\r
- (reprfunc)instancemethod_repr, /* tp_repr */\r
- 0, /* tp_as_number */\r
- 0, /* tp_as_sequence */\r
- 0, /* tp_as_mapping */\r
- (hashfunc)instancemethod_hash, /* tp_hash */\r
- instancemethod_call, /* tp_call */\r
- 0, /* tp_str */\r
- instancemethod_getattro, /* tp_getattro */\r
- PyObject_GenericSetAttr, /* tp_setattro */\r
- 0, /* tp_as_buffer */\r
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */\r
- instancemethod_doc, /* tp_doc */\r
- (traverseproc)instancemethod_traverse, /* tp_traverse */\r
- 0, /* tp_clear */\r
- 0, /* tp_richcompare */\r
- offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */\r
- 0, /* tp_iter */\r
- 0, /* tp_iternext */\r
- 0, /* tp_methods */\r
- instancemethod_memberlist, /* tp_members */\r
- instancemethod_getset, /* tp_getset */\r
- 0, /* tp_base */\r
- 0, /* tp_dict */\r
- instancemethod_descr_get, /* tp_descr_get */\r
- 0, /* tp_descr_set */\r
- 0, /* tp_dictoffset */\r
- 0, /* tp_init */\r
- 0, /* tp_alloc */\r
- instancemethod_new, /* tp_new */\r
-};\r
-\r
-/* Clear out the free list */\r
-\r
-int\r
-PyMethod_ClearFreeList(void)\r
-{\r
- int freelist_size = numfree;\r
-\r
- while (free_list) {\r
- PyMethodObject *im = free_list;\r
- free_list = (PyMethodObject *)(im->im_self);\r
- PyObject_GC_Del(im);\r
- numfree--;\r
- }\r
- assert(numfree == 0);\r
- return freelist_size;\r
-}\r
-\r
-void\r
-PyMethod_Fini(void)\r
-{\r
- (void)PyMethod_ClearFreeList();\r
-}\r