8000 cpython/Objects/funcobject.c at 3.3 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

Latest commit

 

History

History
1056 lines (957 loc) · 30.9 KB

File metadata and controls

1056 lines (957 loc) · 30.9 KB
i += 2;
}
nk = i/2;
}
else {
k = NULL;
nk = 0;
}
result = PyEval_EvalCodeEx(
PyFunction_GET_CODE(func),
PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
&PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg),
k, nk, d, nd,
PyFunction_GET_KW_DEFAULTS(func),
PyFunction_GET_CLOSURE(func));
Py_XDECREF(kwtuple);
return result;
}
/* Bind a function to an object */
static PyObject *
func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
{
if (obj == Py_None || obj == NULL) {
Py_INCREF(func);
return func;
}
return PyMethod_New(func, obj);
}
PyTypeObject PyFunction_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"function",
sizeof(PyFunctionObject),
0,
(destructor)func_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
(reprfunc)func_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
function_call, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
func_doc, /* tp_doc */
(traverseproc)func_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
func_memberlist, /* tp_members */
func_getsetlist, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
func_descr_get, /* tp_descr_get */
0, /* tp_descr_set */
offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
func_new, /* tp_new */
};
/* Class method object */
/* A class method receives the class as implicit first argument,
just like an instance method receives the instance.
To declare a class method, use this idiom:
class C:
def f(cls, arg1, arg2, ...): ...
f = classmethod(f)
It can be called either on the class (e.g. C.f()) or on an instance
(e.g. C().f()); the instance is ignored except for its class.
If a class method is called for a derived class, the derived class
object is passed as the implied first argument.
Class methods are different than C++ or Java static methods.
If you want those, see static methods below.
*/
typedef struct {
PyObject_HEAD
PyObject *cm_callable;
PyObject *cm_dict;
} classmethod;
static void
cm_dealloc(classmethod *cm)
{
_PyObject_GC_UNTRACK((PyObject *)cm);
Py_XDECREF(cm->cm_callable);
Py_XDECREF(cm->cm_dict);
Py_TYPE(cm)->tp_free((PyObject *)cm);
}
static int
cm_traverse(classmethod *cm, visitproc visit, void *arg)
{
Py_VISIT(cm->cm_callable);
Py_VISIT(cm->cm_dict);
return 0;
}
static int
cm_clear(classmethod *cm)
{
Py_CLEAR(cm->cm_callable);
Py_CLEAR(cm->cm_dict);
return 0;
}
static PyObject *
cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
{
classmethod *cm = (classmethod *)self;
if (cm->cm_callable == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"uninitialized classmethod object");
return NULL;
}
if (type == NULL)
type = (PyObject *)(Py_TYPE(obj));
return PyMethod_New(cm->cm_callable, type);
}
static int
cm_init(PyObject *self, PyObject *args, PyObject *kwds)
{
classmethod *cm = (classmethod *)self;
PyObject *callable;
if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable))
return -1;
if (!_PyArg_NoKeywords("classmethod", kwds))
return -1;
Py_INCREF(callable);
cm->cm_callable = callable;
return 0;
}
static PyMemberDef cm_memberlist[] = {
{"__func__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY},
{NULL} /* Sentinel */
};
static PyObject *
cm_get___isabstractmethod__(classmethod *cm, void *closure)
{
int res = _PyObject_IsAbstract(cm->cm_callable);
if (res == -1) {
return NULL;
}
else if (res) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
}
static PyGetSetDef cm_getsetlist[] = {
{"__isabstractmethod__",
(getter)cm_get___isabstractmethod__, NULL,
NULL,
NULL},
{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, NULL, NULL},
{NULL} /* Sentinel */
};
PyDoc_STRVAR(classmethod_doc,
"classmethod(function) -> method\n\
\n\
Convert a function to be a class method.\n\
\n\
A class method receives the class as implicit first argument,\n\
just like an instance method receives the instance.\n\
To declare a class method, use this idiom:\n\
\n\
class C:\n\
def f(cls, arg1, arg2, ...): ...\n\
f = classmethod(f)\n\
\n\
It can be called either on the class (e.g. C.f()) or on an instance\n\
(e.g. C().f()). The instance is ignored except for its class.\n\
If a class method is called for a derived class, the derived class\n\
object is passed as the implied first argument.\n\
\n\
Class methods are different than C++ or Java static methods.\n\
If you want those, see the staticmethod builtin.");
PyTypeObject PyClassMethod_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"classmethod",
sizeof(classmethod),
0,
(destructor)cm_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
classmethod_doc, /* tp_doc */
(traverseproc)cm_traverse, /* tp_traverse */
(inquiry)cm_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
cm_memberlist, /* tp_members */
cm_getsetlist, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
cm_descr_get, /* tp_descr_get */
0, /* tp_descr_set */
offsetof(classmethod, cm_dict), /* tp_dictoffset */
cm_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
PyObject *
PyClassMethod_New(PyObject *callable)
{
classmethod *cm = (classmethod *)
PyType_GenericAlloc(&PyClassMethod_Type, 0);
if (cm != NULL) {
Py_INCREF(callable);
cm->cm_callable = callable;
}
return (PyObject *)cm;
}
/* Static method object */
/* A static method does not receive an implicit first argument.
To declare a static method, use this idiom:
class C:
def f(arg1, arg2, ...): ...
f = staticmethod(f)
It can be called either on the class (e.g. C.f()) or on an instance
(e.g. C().f()); the instance is ignored except for its class.
Static methods in Python are similar to those found in Java or C++.
For a more advanced concept, see class methods above.
*/
typedef struct {
PyObject_HEAD
PyObject *sm_callable;
PyObject *sm_dict;
} staticmethod;
static void
sm_dealloc(staticmethod *sm)
{
_PyObject_GC_UNTRACK((PyObject *)sm);
Py_XDECREF(sm->sm_callable);
Py_XDECREF(sm->sm_dict);
Py_TYPE(sm)->tp_free((PyObject *)sm);
}
static int
sm_traverse(staticmethod *sm, visitproc visit, void *arg)
{
Py_VISIT(sm->sm_callable);
Py_VISIT(sm->sm_dict);
return 0;
}
static int
sm_clear(staticmethod *sm)
{
Py_CLEAR(sm->sm_callable);
Py_CLEAR(sm->sm_dict);
return 0;
}
static PyObject *
sm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
{
staticmethod *sm = (staticmethod *)self;
if (sm->sm_callable == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"uninitialized staticmethod object");
return NULL;
}
Py_INCREF(sm->sm_callable);
return sm->sm_callable;
}
static int
sm_init(PyObject *self, PyObject *args, PyObject *kwds)
{
staticmethod *sm = (staticmethod *)self;
PyObject *callable;
if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable))
return -1;
if (!_PyArg_NoKeywords("staticmethod", kwds))
return -1;
Py_INCREF(callable);
sm->sm_callable = callable;
return 0;
}
static PyMemberDef sm_memberlist[] = {
{"__func__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY},
{NULL} /* Sentinel */
};
static PyObject *
sm_get___isabstractmethod__(staticmethod *sm, void *closure)
{
int res = _PyObject_IsAbstract(sm->sm_callable);
if (res == -1) {
return NULL;
}
else if (res) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
}
static PyGetSetDef sm_getsetlist[] = {
{"__isabstractmethod__",
(getter)sm_get___isabstractmethod__, NULL,
NULL,
NULL},
{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, NULL, NULL},
{NULL} /* Sentinel */
};
PyDoc_STRVAR(staticmethod_doc,
"staticmethod(function) -> method\n\
\n\
Convert a function to be a static method.\n\
\n\
A static method does not receive an implicit first argument.\n\
To declare a static method, use this idiom:\n\
\n\
class C:\n\
def f(arg1, arg2, ...): ...\n\
f = staticmethod(f)\n\
\n\
It can be called either on the class (e.g. C.f()) or on an instance\n\
(e.g. C().f()). The instance is ignored except for its class.\n\
\n\
0