+++ /dev/null
-\r
-/* Function object implementation */\r
-\r
-#include "Python.h"\r
-#include "code.h"\r
-#include "eval.h"\r
-#include "structmember.h"\r
-\r
-PyObject *\r
-PyFunction_New(PyObject *code, PyObject *globals)\r
-{\r
- PyFunctionObject *op = PyObject_GC_New(PyFunctionObject,\r
- &PyFunction_Type);\r
- static PyObject *__name__ = 0;\r
- if (op != NULL) {\r
- PyObject *doc;\r
- PyObject *consts;\r
- PyObject *module;\r
- op->func_weakreflist = NULL;\r
- Py_INCREF(code);\r
- op->func_code = code;\r
- Py_INCREF(globals);\r
- op->func_globals = globals;\r
- op->func_name = ((PyCodeObject *)code)->co_name;\r
- Py_INCREF(op->func_name);\r
- op->func_defaults = NULL; /* No default arguments */\r
- op->func_closure = NULL;\r
- consts = ((PyCodeObject *)code)->co_consts;\r
- if (PyTuple_Size(consts) >= 1) {\r
- doc = PyTuple_GetItem(consts, 0);\r
- if (!PyString_Check(doc) && !PyUnicode_Check(doc))\r
- doc = Py_None;\r
- }\r
- else\r
- doc = Py_None;\r
- Py_INCREF(doc);\r
- op->func_doc = doc;\r
- op->func_dict = NULL;\r
- op->func_module = NULL;\r
-\r
- /* __module__: If module name is in globals, use it.\r
- Otherwise, use None.\r
- */\r
- if (!__name__) {\r
- __name__ = PyString_InternFromString("__name__");\r
- if (!__name__) {\r
- Py_DECREF(op);\r
- return NULL;\r
- }\r
- }\r
- module = PyDict_GetItem(globals, __name__);\r
- if (module) {\r
- Py_INCREF(module);\r
- op->func_module = module;\r
- }\r
- }\r
- else\r
- return NULL;\r
- _PyObject_GC_TRACK(op);\r
- return (PyObject *)op;\r
-}\r
-\r
-PyObject *\r
-PyFunction_GetCode(PyObject *op)\r
-{\r
- if (!PyFunction_Check(op)) {\r
- PyErr_BadInternalCall();\r
- return NULL;\r
- }\r
- return ((PyFunctionObject *) op) -> func_code;\r
-}\r
-\r
-PyObject *\r
-PyFunction_GetGlobals(PyObject *op)\r
-{\r
- if (!PyFunction_Check(op)) {\r
- PyErr_BadInternalCall();\r
- return NULL;\r
- }\r
- return ((PyFunctionObject *) op) -> func_globals;\r
-}\r
-\r
-PyObject *\r
-PyFunction_GetModule(PyObject *op)\r
-{\r
- if (!PyFunction_Check(op)) {\r
- PyErr_BadInternalCall();\r
- return NULL;\r
- }\r
- return ((PyFunctionObject *) op) -> func_module;\r
-}\r
-\r
-PyObject *\r
-PyFunction_GetDefaults(PyObject *op)\r
-{\r
- if (!PyFunction_Check(op)) {\r
- PyErr_BadInternalCall();\r
- return NULL;\r
- }\r
- return ((PyFunctionObject *) op) -> func_defaults;\r
-}\r
-\r
-int\r
-PyFunction_SetDefaults(PyObject *op, PyObject *defaults)\r
-{\r
- if (!PyFunction_Check(op)) {\r
- PyErr_BadInternalCall();\r
- return -1;\r
- }\r
- if (defaults == Py_None)\r
- defaults = NULL;\r
- else if (defaults && PyTuple_Check(defaults)) {\r
- Py_INCREF(defaults);\r
- }\r
- else {\r
- PyErr_SetString(PyExc_SystemError, "non-tuple default args");\r
- return -1;\r
- }\r
- Py_XDECREF(((PyFunctionObject *) op) -> func_defaults);\r
- ((PyFunctionObject *) op) -> func_defaults = defaults;\r
- return 0;\r
-}\r
-\r
-PyObject *\r
-PyFunction_GetClosure(PyObject *op)\r
-{\r
- if (!PyFunction_Check(op)) {\r
- PyErr_BadInternalCall();\r
- return NULL;\r
- }\r
- return ((PyFunctionObject *) op) -> func_closure;\r
-}\r
-\r
-int\r
-PyFunction_SetClosure(PyObject *op, PyObject *closure)\r
-{\r
- if (!PyFunction_Check(op)) {\r
- PyErr_BadInternalCall();\r
- return -1;\r
- }\r
- if (closure == Py_None)\r
- closure = NULL;\r
- else if (PyTuple_Check(closure)) {\r
- Py_INCREF(closure);\r
- }\r
- else {\r
- PyErr_Format(PyExc_SystemError,\r
- "expected tuple for closure, got '%.100s'",\r
- closure->ob_type->tp_name);\r
- return -1;\r
- }\r
- Py_XDECREF(((PyFunctionObject *) op) -> func_closure);\r
- ((PyFunctionObject *) op) -> func_closure = closure;\r
- return 0;\r
-}\r
-\r
-/* Methods */\r
-\r
-#define OFF(x) offsetof(PyFunctionObject, x)\r
-\r
-static PyMemberDef func_memberlist[] = {\r
- {"func_closure", T_OBJECT, OFF(func_closure),\r
- RESTRICTED|READONLY},\r
- {"__closure__", T_OBJECT, OFF(func_closure),\r
- RESTRICTED|READONLY},\r
- {"func_doc", T_OBJECT, OFF(func_doc), PY_WRITE_RESTRICTED},\r
- {"__doc__", T_OBJECT, OFF(func_doc), PY_WRITE_RESTRICTED},\r
- {"func_globals", T_OBJECT, OFF(func_globals),\r
- RESTRICTED|READONLY},\r
- {"__globals__", T_OBJECT, OFF(func_globals),\r
- RESTRICTED|READONLY},\r
- {"__module__", T_OBJECT, OFF(func_module), PY_WRITE_RESTRICTED},\r
- {NULL} /* Sentinel */\r
-};\r
-\r
-static int\r
-restricted(void)\r
-{\r
- if (!PyEval_GetRestricted())\r
- return 0;\r
- PyErr_SetString(PyExc_RuntimeError,\r
- "function attributes not accessible in restricted mode");\r
- return 1;\r
-}\r
-\r
-static PyObject *\r
-func_get_dict(PyFunctionObject *op)\r
-{\r
- if (restricted())\r
- return NULL;\r
- if (op->func_dict == NULL) {\r
- op->func_dict = PyDict_New();\r
- if (op->func_dict == NULL)\r
- return NULL;\r
- }\r
- Py_INCREF(op->func_dict);\r
- return op->func_dict;\r
-}\r
-\r
-static int\r
-func_set_dict(PyFunctionObject *op, PyObject *value)\r
-{\r
- PyObject *tmp;\r
-\r
- if (restricted())\r
- return -1;\r
- /* It is illegal to del f.func_dict */\r
- if (value == NULL) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "function's dictionary may not be deleted");\r
- return -1;\r
- }\r
- /* Can only set func_dict to a dictionary */\r
- if (!PyDict_Check(value)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "setting function's dictionary to a non-dict");\r
- return -1;\r
- }\r
- tmp = op->func_dict;\r
- Py_INCREF(value);\r
- op->func_dict = value;\r
- Py_XDECREF(tmp);\r
- return 0;\r
-}\r
-\r
-static PyObject *\r
-func_get_code(PyFunctionObject *op)\r
-{\r
- if (restricted())\r
- return NULL;\r
- Py_INCREF(op->func_code);\r
- return op->func_code;\r
-}\r
-\r
-static int\r
-func_set_code(PyFunctionObject *op, PyObject *value)\r
-{\r
- PyObject *tmp;\r
- Py_ssize_t nfree, nclosure;\r
-\r
- if (restricted())\r
- return -1;\r
- /* Not legal to del f.func_code or to set it to anything\r
- * other than a code object. */\r
- if (value == NULL || !PyCode_Check(value)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "__code__ must be set to a code object");\r
- return -1;\r
- }\r
- nfree = PyCode_GetNumFree((PyCodeObject *)value);\r
- nclosure = (op->func_closure == NULL ? 0 :\r
- PyTuple_GET_SIZE(op->func_closure));\r
- if (nclosure != nfree) {\r
- PyErr_Format(PyExc_ValueError,\r
- "%s() requires a code object with %zd free vars,"\r
- " not %zd",\r
- PyString_AsString(op->func_name),\r
- nclosure, nfree);\r
- return -1;\r
- }\r
- tmp = op->func_code;\r
- Py_INCREF(value);\r
- op->func_code = value;\r
- Py_DECREF(tmp);\r
- return 0;\r
-}\r
-\r
-static PyObject *\r
-func_get_name(PyFunctionObject *op)\r
-{\r
- Py_INCREF(op->func_name);\r
- return op->func_name;\r
-}\r
-\r
-static int\r
-func_set_name(PyFunctionObject *op, PyObject *value)\r
-{\r
- PyObject *tmp;\r
-\r
- if (restricted())\r
- return -1;\r
- /* Not legal to del f.func_name or to set it to anything\r
- * other than a string object. */\r
- if (value == NULL || !PyString_Check(value)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "__name__ must be set to a string object");\r
- return -1;\r
- }\r
- tmp = op->func_name;\r
- Py_INCREF(value);\r
- op->func_name = value;\r
- Py_DECREF(tmp);\r
- return 0;\r
-}\r
-\r
-static PyObject *\r
-func_get_defaults(PyFunctionObject *op)\r
-{\r
- if (restricted())\r
- return NULL;\r
- if (op->func_defaults == NULL) {\r
- Py_INCREF(Py_None);\r
- return Py_None;\r
- }\r
- Py_INCREF(op->func_defaults);\r
- return op->func_defaults;\r
-}\r
-\r
-static int\r
-func_set_defaults(PyFunctionObject *op, PyObject *value)\r
-{\r
- PyObject *tmp;\r
-\r
- if (restricted())\r
- return -1;\r
- /* Legal to del f.func_defaults.\r
- * Can only set func_defaults to NULL or a tuple. */\r
- if (value == Py_None)\r
- value = NULL;\r
- if (value != NULL && !PyTuple_Check(value)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "__defaults__ must be set to a tuple object");\r
- return -1;\r
- }\r
- tmp = op->func_defaults;\r
- Py_XINCREF(value);\r
- op->func_defaults = value;\r
- Py_XDECREF(tmp);\r
- return 0;\r
-}\r
-\r
-static PyGetSetDef func_getsetlist[] = {\r
- {"func_code", (getter)func_get_code, (setter)func_set_code},\r
- {"__code__", (getter)func_get_code, (setter)func_set_code},\r
- {"func_defaults", (getter)func_get_defaults,\r
- (setter)func_set_defaults},\r
- {"__defaults__", (getter)func_get_defaults,\r
- (setter)func_set_defaults},\r
- {"func_dict", (getter)func_get_dict, (setter)func_set_dict},\r
- {"__dict__", (getter)func_get_dict, (setter)func_set_dict},\r
- {"func_name", (getter)func_get_name, (setter)func_set_name},\r
- {"__name__", (getter)func_get_name, (setter)func_set_name},\r
- {NULL} /* Sentinel */\r
-};\r
-\r
-PyDoc_STRVAR(func_doc,\r
-"function(code, globals[, name[, argdefs[, closure]]])\n\\r
-\n\\r
-Create a function object from a code object and a dictionary.\n\\r
-The optional name string overrides the name from the code object.\n\\r
-The optional argdefs tuple specifies the default argument values.\n\\r
-The optional closure tuple supplies the bindings for free variables.");\r
-\r
-/* func_new() maintains the following invariants for closures. The\r
- closure must correspond to the free variables of the code object.\r
-\r
- if len(code.co_freevars) == 0:\r
- closure = NULL\r
- else:\r
- len(closure) == len(code.co_freevars)\r
- for every elt in closure, type(elt) == cell\r
-*/\r
-\r
-static PyObject *\r
-func_new(PyTypeObject* type, PyObject* args, PyObject* kw)\r
-{\r
- PyCodeObject *code;\r
- PyObject *globals;\r
- PyObject *name = Py_None;\r
- PyObject *defaults = Py_None;\r
- PyObject *closure = Py_None;\r
- PyFunctionObject *newfunc;\r
- Py_ssize_t nfree, nclosure;\r
- static char *kwlist[] = {"code", "globals", "name",\r
- "argdefs", "closure", 0};\r
-\r
- if (!PyArg_ParseTupleAndKeywords(args, kw, "O!O!|OOO:function",\r
- kwlist,\r
- &PyCode_Type, &code,\r
- &PyDict_Type, &globals,\r
- &name, &defaults, &closure))\r
- return NULL;\r
- if (name != Py_None && !PyString_Check(name)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "arg 3 (name) must be None or string");\r
- return NULL;\r
- }\r
- if (defaults != Py_None && !PyTuple_Check(defaults)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "arg 4 (defaults) must be None or tuple");\r
- return NULL;\r
- }\r
- nfree = PyTuple_GET_SIZE(code->co_freevars);\r
- if (!PyTuple_Check(closure)) {\r
- if (nfree && closure == Py_None) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "arg 5 (closure) must be tuple");\r
- return NULL;\r
- }\r
- else if (closure != Py_None) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "arg 5 (closure) must be None or tuple");\r
- return NULL;\r
- }\r
- }\r
-\r
- /* check that the closure is well-formed */\r
- nclosure = closure == Py_None ? 0 : PyTuple_GET_SIZE(closure);\r
- if (nfree != nclosure)\r
- return PyErr_Format(PyExc_ValueError,\r
- "%s requires closure of length %zd, not %zd",\r
- PyString_AS_STRING(code->co_name),\r
- nfree, nclosure);\r
- if (nclosure) {\r
- Py_ssize_t i;\r
- for (i = 0; i < nclosure; i++) {\r
- PyObject *o = PyTuple_GET_ITEM(closure, i);\r
- if (!PyCell_Check(o)) {\r
- return PyErr_Format(PyExc_TypeError,\r
- "arg 5 (closure) expected cell, found %s",\r
- o->ob_type->tp_name);\r
- }\r
- }\r
- }\r
-\r
- newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code,\r
- globals);\r
- if (newfunc == NULL)\r
- return NULL;\r
-\r
- if (name != Py_None) {\r
- Py_INCREF(name);\r
- Py_DECREF(newfunc->func_name);\r
- newfunc->func_name = name;\r
- }\r
- if (defaults != Py_None) {\r
- Py_INCREF(defaults);\r
- newfunc->func_defaults = defaults;\r
- }\r
- if (closure != Py_None) {\r
- Py_INCREF(closure);\r
- newfunc->func_closure = closure;\r
- }\r
-\r
- return (PyObject *)newfunc;\r
-}\r
-\r
-static void\r
-func_dealloc(PyFunctionObject *op)\r
-{\r
- _PyObject_GC_UNTRACK(op);\r
- if (op->func_weakreflist != NULL)\r
- PyObject_ClearWeakRefs((PyObject *) op);\r
- Py_DECREF(op->func_code);\r
- Py_DECREF(op->func_globals);\r
- Py_XDECREF(op->func_module);\r
- Py_DECREF(op->func_name);\r
- Py_XDECREF(op->func_defaults);\r
- Py_XDECREF(op->func_doc);\r
- Py_XDECREF(op->func_dict);\r
- Py_XDECREF(op->func_closure);\r
- PyObject_GC_Del(op);\r
-}\r
-\r
-static PyObject*\r
-func_repr(PyFunctionObject *op)\r
-{\r
- return PyString_FromFormat("<function %s at %p>",\r
- PyString_AsString(op->func_name),\r
- op);\r
-}\r
-\r
-static int\r
-func_traverse(PyFunctionObject *f, visitproc visit, void *arg)\r
-{\r
- Py_VISIT(f->func_code);\r
- Py_VISIT(f->func_globals);\r
- Py_VISIT(f->func_module);\r
- Py_VISIT(f->func_defaults);\r
- Py_VISIT(f->func_doc);\r
- Py_VISIT(f->func_name);\r
- Py_VISIT(f->func_dict);\r
- Py_VISIT(f->func_closure);\r
- return 0;\r
-}\r
-\r
-static PyObject *\r
-function_call(PyObject *func, PyObject *arg, PyObject *kw)\r
-{\r
- PyObject *result;\r
- PyObject *argdefs;\r
- PyObject *kwtuple = NULL;\r
- PyObject **d, **k;\r
- Py_ssize_t nk, nd;\r
-\r
- argdefs = PyFunction_GET_DEFAULTS(func);\r
- if (argdefs != NULL && PyTuple_Check(argdefs)) {\r
- d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0);\r
- nd = PyTuple_GET_SIZE(argdefs);\r
- }\r
- else {\r
- d = NULL;\r
- nd = 0;\r
- }\r
-\r
- if (kw != NULL && PyDict_Check(kw)) {\r
- Py_ssize_t pos, i;\r
- nk = PyDict_Size(kw);\r
- kwtuple = PyTuple_New(2*nk);\r
- if (kwtuple == NULL)\r
- return NULL;\r
- k = &PyTuple_GET_ITEM(kwtuple, 0);\r
- pos = i = 0;\r
- while (PyDict_Next(kw, &pos, &k[i], &k[i+1])) {\r
- Py_INCREF(k[i]);\r
- Py_INCREF(k[i+1]);\r
- i += 2;\r
- }\r
- nk = i/2;\r
- }\r
- else {\r
- k = NULL;\r
- nk = 0;\r
- }\r
-\r
- result = PyEval_EvalCodeEx(\r
- (PyCodeObject *)PyFunction_GET_CODE(func),\r
- PyFunction_GET_GLOBALS(func), (PyObject *)NULL,\r
- &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg),\r
- k, nk, d, nd,\r
- PyFunction_GET_CLOSURE(func));\r
-\r
- Py_XDECREF(kwtuple);\r
-\r
- return result;\r
-}\r
-\r
-/* Bind a function to an object */\r
-static PyObject *\r
-func_descr_get(PyObject *func, PyObject *obj, PyObject *type)\r
-{\r
- if (obj == Py_None)\r
- obj = NULL;\r
- return PyMethod_New(func, obj, type);\r
-}\r
-\r
-PyTypeObject PyFunction_Type = {\r
- PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
- "function",\r
- sizeof(PyFunctionObject),\r
- 0,\r
- (destructor)func_dealloc, /* tp_dealloc */\r
- 0, /* tp_print */\r
- 0, /* tp_getattr */\r
- 0, /* tp_setattr */\r
- 0, /* tp_compare */\r
- (reprfunc)func_repr, /* tp_repr */\r
- 0, /* tp_as_number */\r
- 0, /* tp_as_sequence */\r
- 0, /* tp_as_mapping */\r
- 0, /* tp_hash */\r
- function_call, /* tp_call */\r
- 0, /* tp_str */\r
- PyObject_GenericGetAttr, /* tp_getattro */\r
- PyObject_GenericSetAttr, /* tp_setattro */\r
- 0, /* tp_as_buffer */\r
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */\r
- func_doc, /* tp_doc */\r
- (traverseproc)func_traverse, /* tp_traverse */\r
- 0, /* tp_clear */\r
- 0, /* tp_richcompare */\r
- offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */\r
- 0, /* tp_iter */\r
- 0, /* tp_iternext */\r
- 0, /* tp_methods */\r
- func_memberlist, /* tp_members */\r
- func_getsetlist, /* tp_getset */\r
- 0, /* tp_base */\r
- 0, /* tp_dict */\r
- func_descr_get, /* tp_descr_get */\r
- 0, /* tp_descr_set */\r
- offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */\r
- 0, /* tp_init */\r
- 0, /* tp_alloc */\r
- func_new, /* tp_new */\r
-};\r
-\r
-\r
-/* Class method object */\r
-\r
-/* A class method receives the class as implicit first argument,\r
- just like an instance method receives the instance.\r
- To declare a class method, use this idiom:\r
-\r
- class C:\r
- def f(cls, arg1, arg2, ...): ...\r
- f = classmethod(f)\r
-\r
- It can be called either on the class (e.g. C.f()) or on an instance\r
- (e.g. C().f()); the instance is ignored except for its class.\r
- If a class method is called for a derived class, the derived class\r
- object is passed as the implied first argument.\r
-\r
- Class methods are different than C++ or Java static methods.\r
- If you want those, see static methods below.\r
-*/\r
-\r
-typedef struct {\r
- PyObject_HEAD\r
- PyObject *cm_callable;\r
-} classmethod;\r
-\r
-static void\r
-cm_dealloc(classmethod *cm)\r
-{\r
- _PyObject_GC_UNTRACK((PyObject *)cm);\r
- Py_XDECREF(cm->cm_callable);\r
- Py_TYPE(cm)->tp_free((PyObject *)cm);\r
-}\r
-\r
-static int\r
-cm_traverse(classmethod *cm, visitproc visit, void *arg)\r
-{\r
- Py_VISIT(cm->cm_callable);\r
- return 0;\r
-}\r
-\r
-static int\r
-cm_clear(classmethod *cm)\r
-{\r
- Py_CLEAR(cm->cm_callable);\r
- return 0;\r
-}\r
-\r
-\r
-static PyObject *\r
-cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)\r
-{\r
- classmethod *cm = (classmethod *)self;\r
-\r
- if (cm->cm_callable == NULL) {\r
- PyErr_SetString(PyExc_RuntimeError,\r
- "uninitialized classmethod object");\r
- return NULL;\r
- }\r
- if (type == NULL)\r
- type = (PyObject *)(Py_TYPE(obj));\r
- return PyMethod_New(cm->cm_callable,\r
- type, (PyObject *)(Py_TYPE(type)));\r
-}\r
-\r
-static int\r
-cm_init(PyObject *self, PyObject *args, PyObject *kwds)\r
-{\r
- classmethod *cm = (classmethod *)self;\r
- PyObject *callable;\r
-\r
- if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable))\r
- return -1;\r
- if (!_PyArg_NoKeywords("classmethod", kwds))\r
- return -1;\r
- Py_INCREF(callable);\r
- cm->cm_callable = callable;\r
- return 0;\r
-}\r
-\r
-static PyMemberDef cm_memberlist[] = {\r
- {"__func__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY},\r
- {NULL} /* Sentinel */\r
-};\r
-\r
-PyDoc_STRVAR(classmethod_doc,\r
-"classmethod(function) -> method\n\\r
-\n\\r
-Convert a function to be a class method.\n\\r
-\n\\r
-A class method receives the class as implicit first argument,\n\\r
-just like an instance method receives the instance.\n\\r
-To declare a class method, use this idiom:\n\\r
-\n\\r
- class C:\n\\r
- def f(cls, arg1, arg2, ...): ...\n\\r
- f = classmethod(f)\n\\r
-\n\\r
-It can be called either on the class (e.g. C.f()) or on an instance\n\\r
-(e.g. C().f()). The instance is ignored except for its class.\n\\r
-If a class method is called for a derived class, the derived class\n\\r
-object is passed as the implied first argument.\n\\r
-\n\\r
-Class methods are different than C++ or Java static methods.\n\\r
-If you want those, see the staticmethod builtin.");\r
-\r
-PyTypeObject PyClassMethod_Type = {\r
- PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
- "classmethod",\r
- sizeof(classmethod),\r
- 0,\r
- (destructor)cm_dealloc, /* tp_dealloc */\r
- 0, /* tp_print */\r
- 0, /* tp_getattr */\r
- 0, /* tp_setattr */\r
- 0, /* tp_compare */\r
- 0, /* tp_repr */\r
- 0, /* tp_as_number */\r
- 0, /* tp_as_sequence */\r
- 0, /* tp_as_mapping */\r
- 0, /* tp_hash */\r
- 0, /* tp_call */\r
- 0, /* tp_str */\r
- PyObject_GenericGetAttr, /* tp_getattro */\r
- 0, /* tp_setattro */\r
- 0, /* tp_as_buffer */\r
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,\r
- classmethod_doc, /* tp_doc */\r
- (traverseproc)cm_traverse, /* tp_traverse */\r
- (inquiry)cm_clear, /* tp_clear */\r
- 0, /* tp_richcompare */\r
- 0, /* tp_weaklistoffset */\r
- 0, /* tp_iter */\r
- 0, /* tp_iternext */\r
- 0, /* tp_methods */\r
- cm_memberlist, /* tp_members */\r
- 0, /* tp_getset */\r
- 0, /* tp_base */\r
- 0, /* tp_dict */\r
- cm_descr_get, /* tp_descr_get */\r
- 0, /* tp_descr_set */\r
- 0, /* tp_dictoffset */\r
- cm_init, /* tp_init */\r
- PyType_GenericAlloc, /* tp_alloc */\r
- PyType_GenericNew, /* tp_new */\r
- PyObject_GC_Del, /* tp_free */\r
-};\r
-\r
-PyObject *\r
-PyClassMethod_New(PyObject *callable)\r
-{\r
- classmethod *cm = (classmethod *)\r
- PyType_GenericAlloc(&PyClassMethod_Type, 0);\r
- if (cm != NULL) {\r
- Py_INCREF(callable);\r
- cm->cm_callable = callable;\r
- }\r
- return (PyObject *)cm;\r
-}\r
-\r
-\r
-/* Static method object */\r
-\r
-/* A static method does not receive an implicit first argument.\r
- To declare a static method, use this idiom:\r
-\r
- class C:\r
- def f(arg1, arg2, ...): ...\r
- f = staticmethod(f)\r
-\r
- It can be called either on the class (e.g. C.f()) or on an instance\r
- (e.g. C().f()); the instance is ignored except for its class.\r
-\r
- Static methods in Python are similar to those found in Java or C++.\r
- For a more advanced concept, see class methods above.\r
-*/\r
-\r
-typedef struct {\r
- PyObject_HEAD\r
- PyObject *sm_callable;\r
-} staticmethod;\r
-\r
-static void\r
-sm_dealloc(staticmethod *sm)\r
-{\r
- _PyObject_GC_UNTRACK((PyObject *)sm);\r
- Py_XDECREF(sm->sm_callable);\r
- Py_TYPE(sm)->tp_free((PyObject *)sm);\r
-}\r
-\r
-static int\r
-sm_traverse(staticmethod *sm, visitproc visit, void *arg)\r
-{\r
- Py_VISIT(sm->sm_callable);\r
- return 0;\r
-}\r
-\r
-static int\r
-sm_clear(staticmethod *sm)\r
-{\r
- Py_CLEAR(sm->sm_callable);\r
- return 0;\r
-}\r
-\r
-static PyObject *\r
-sm_descr_get(PyObject *self, PyObject *obj, PyObject *type)\r
-{\r
- staticmethod *sm = (staticmethod *)self;\r
-\r
- if (sm->sm_callable == NULL) {\r
- PyErr_SetString(PyExc_RuntimeError,\r
- "uninitialized staticmethod object");\r
- return NULL;\r
- }\r
- Py_INCREF(sm->sm_callable);\r
- return sm->sm_callable;\r
-}\r
-\r
-static int\r
-sm_init(PyObject *self, PyObject *args, PyObject *kwds)\r
-{\r
- staticmethod *sm = (staticmethod *)self;\r
- PyObject *callable;\r
-\r
- if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable))\r
- return -1;\r
- if (!_PyArg_NoKeywords("staticmethod", kwds))\r
- return -1;\r
- Py_INCREF(callable);\r
- sm->sm_callable = callable;\r
- return 0;\r
-}\r
-\r
-static PyMemberDef sm_memberlist[] = {\r
- {"__func__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY},\r
- {NULL} /* Sentinel */\r
-};\r
-\r
-PyDoc_STRVAR(staticmethod_doc,\r
-"staticmethod(function) -> method\n\\r
-\n\\r
-Convert a function to be a static method.\n\\r
-\n\\r
-A static method does not receive an implicit first argument.\n\\r
-To declare a static method, use this idiom:\n\\r
-\n\\r
- class C:\n\\r
- def f(arg1, arg2, ...): ...\n\\r
- f = staticmethod(f)\n\\r
-\n\\r
-It can be called either on the class (e.g. C.f()) or on an instance\n\\r
-(e.g. C().f()). The instance is ignored except for its class.\n\\r
-\n\\r
-Static methods in Python are similar to those found in Java or C++.\n\\r
-For a more advanced concept, see the classmethod builtin.");\r
-\r
-PyTypeObject PyStaticMethod_Type = {\r
- PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
- "staticmethod",\r
- sizeof(staticmethod),\r
- 0,\r
- (destructor)sm_dealloc, /* tp_dealloc */\r
- 0, /* tp_print */\r
- 0, /* tp_getattr */\r
- 0, /* tp_setattr */\r
- 0, /* tp_compare */\r
- 0, /* tp_repr */\r
- 0, /* tp_as_number */\r
- 0, /* tp_as_sequence */\r
- 0, /* tp_as_mapping */\r
- 0, /* tp_hash */\r
- 0, /* tp_call */\r
- 0, /* tp_str */\r
- PyObject_GenericGetAttr, /* tp_getattro */\r
- 0, /* tp_setattro */\r
- 0, /* tp_as_buffer */\r
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,\r
- staticmethod_doc, /* tp_doc */\r
- (traverseproc)sm_traverse, /* tp_traverse */\r
- (inquiry)sm_clear, /* tp_clear */\r
- 0, /* tp_richcompare */\r
- 0, /* tp_weaklistoffset */\r
- 0, /* tp_iter */\r
- 0, /* tp_iternext */\r
- 0, /* tp_methods */\r
- sm_memberlist, /* tp_members */\r
- 0, /* tp_getset */\r
- 0, /* tp_base */\r
- 0, /* tp_dict */\r
- sm_descr_get, /* tp_descr_get */\r
- 0, /* tp_descr_set */\r
- 0, /* tp_dictoffset */\r
- sm_init, /* tp_init */\r
- PyType_GenericAlloc, /* tp_alloc */\r
- PyType_GenericNew, /* tp_new */\r
- PyObject_GC_Del, /* tp_free */\r
-};\r
-\r
-PyObject *\r
-PyStaticMethod_New(PyObject *callable)\r
-{\r
- staticmethod *sm = (staticmethod *)\r
- PyType_GenericAlloc(&PyStaticMethod_Type, 0);\r
- if (sm != NULL) {\r
- Py_INCREF(callable);\r
- sm->sm_callable = callable;\r
- }\r
- return (PyObject *)sm;\r
-}\r