/* Function object implementation */
#include "Python.h"
#include "internal/mem.h"
#include "internal/pystate.h"
#include "code.h"
#include "structmember.h"
PyObject *
PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname)
{
PyFunctionObject *op;
PyObject *doc, *consts, *module;
static PyObject *__name__ = NULL;
if (__name__ == NULL) {
__name__ = PyUnicode_InternFromString("__name__");
if (__name__ == NULL)
return NULL;
}
op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type);
if (op == NULL)
return NULL;
op->func_weakreflist = NULL;
Py_INCREF(code);
op->func_code = code;
Py_INCREF(globals);
op->func_globals = globals;
op->func_name = ((PyCodeObject *)code)->co_name;
Py_INCREF(op->func_name);
op->func_defaults = NULL; /* No default arguments */
op->func_kwdefaults = NULL; /* No keyword only defaults */
op->func_closure = NULL;
consts = ((PyCodeObject *)code)->co_consts;
if (PyTuple_Size(consts) >= 1) {
doc = PyTuple_GetItem(consts, 0);
if (!PyUnicode_Check(doc))
doc = Py_None;
}
else
doc = Py_None;
Py_INCREF(doc);
op->func_doc = doc;
op->func_dict = NULL;
op->func_module = NULL;
op->func_annotations = NULL;
/* __module__: If module name is in globals, use it.
Otherwise, use None. */
module = PyDict_GetItem(globals, __name__);
if (module) {
Py_INCREF(module);
op->func_module = module;
}
if (qualname)
op->func_qualname = qualname;
else
op->func_qualname = op->func_name;
Py_INCREF(op->func_qualname);
_PyObject_GC_TRACK(op);
return (PyObject *)op;
}
PyObject *
PyFunction_New(PyObject *code, PyObject *globals)
{
return PyFunction_NewWithQualName(code, globals, NULL);
}
PyObject *
PyFunction_GetCode(PyObject *op)
{
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
return NULL;
}
return ((PyFunctionObject *) op) -> func_code;
}
PyObject *
PyFunction_GetGlobals(PyObject *op)
{
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
return NULL;
}
return ((PyFunctionObject *) op) -> func_globals;
}
PyObject *
PyFunction_GetModule(PyObject *op)
{
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
return NULL;
}
return ((PyFunctionObject *) op) -> func_module;
}
PyObject *
PyFunction_GetDefaults(PyObject *op)
{
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
return NULL;
}
return ((PyFunctionObject *) op) -> func_defaults;
}
int
PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
{
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
return -1;
}
if (defaults == Py_None)
defaults = NULL;
else if (defaults && PyTuple_Check(defaults)) {
Py_INCREF(defaults);
}
else {
PyErr_SetString(PyExc_SystemError, "non-tuple default args");
return -1;
}
Py_XSETREF(((PyFunctionObject *)op)->func_defaults, defaults);
return 0;
}
PyObject *
PyFunction_GetKwDefaults(PyObject *op)
{
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
return NULL;
}
return ((PyFunctionObject *) op) -> func_kwdefaults;
}
int
PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults)
{
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
return -1;
}
if (defaults == Py_None)
defaults = NULL;
else if (defaults && PyDict_Check(defaults)) {
Py_INCREF(defaults);
}
else {
PyErr_SetString(PyExc_SystemError,
"non-dict keyword only default args");
return -1;
}
Py_XSETREF(((PyFunctionObject *)op)->func_kwdefaults, defaults);
return 0;
}
PyObject *
PyFunction_GetClosure(PyObject *op)
{
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
return NULL;
}
return ((PyFunctionObject *) op) -> func_closure;
}
int
PyFunction_SetClosure(PyObject *op, PyObject *closure)
{
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
return -1;
}
if (closure == Py_None)
closure = NULL;
else if (PyTuple_Check(closure)) {
Py_INCREF(closure);
}
else {
PyErr_Format(PyExc_SystemError,
"expected tuple for closure, got '%.100s'",
closure->ob_type->tp_name);
return -1;
}
Py_XSETREF(((PyFunctionObject *)op)->func_closure, closure);
return 0;
}
PyObject *
PyFunction_GetAnnotations(PyObject *op)
{
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
return NULL;
}
return ((PyFunctionObject *) op) -> func_annotations;
}
int
PyFunction_SetAnnotations(PyObject *op, PyObject *annotations)
{
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
return -1;
}
if (annotations == Py_None)
annotations = NULL;
else if (annotations && PyDict_Check(annotations)) {
Py_INCREF(annotations);
}
else {
PyErr_SetString(PyExc_SystemError,
"non-dict annotations");
return -1;
}
Py_XSETREF(((PyFunctionObject *)op)->func_annotations, annotations);
return 0;
}
/* Methods */
#define OFF(x) offsetof(PyFunctionObject, x)
static PyMemberDef func_memberlist[] = {
{"__closure__", T_OBJECT, OFF(func_closure),
RESTRICTED|READONLY},
{"__doc__", T_OBJECT, OFF(func_doc), PY_WRITE_RESTRICTED},
{"__globals__", T_OBJECT, OFF(func_globals),
RESTRICTED|READONLY},
{"__module__", T_OBJECT, OFF(func_module), PY_WRITE_RESTRICTED},
{NULL} /* Sentinel */
};
static PyObject *
func_get_code(PyFunctionObject *op)
{
Py_INCREF(op->func_code);
return op->func_code;
}
static int
func_set_code(PyFunctionObject *op, PyObject *value)
{
Py_ssize_t nfree, nclosure;
/* Not legal to del f.func_code or to set it to anything
* other than a code object. */
if (value == NULL || !PyCode_Check(value)) {
PyErr_SetString(PyExc_TypeError,
"__code__ must be set to a code object");
return -1;
}
nfree = PyCode_GetNumFree((PyCodeObject *)value);
nclosure = (op->func_closure == NULL ? 0 :
PyTuple_GET_SIZE(op->func_closure));
if (nclosure != nfree) {
PyErr_Format(PyExc_ValueError,
"%U() requires a code object with %zd free vars,"
" not %zd",
op->func_name,
nclosure, nfree);
return -1;
}
Py_INCREF(value);
Py_XSETREF(op->func_code, value);
return 0;
}
static PyObject *
func_get_name(PyFunctionObject *op)
{
Py_INCREF(op->func_name);
return op->func_name;
}
static int
func_set_name(PyFunctionObject *op, PyObject *value)
{
/* Not legal to del f.func_name or to set it to anything
* other than a string object. */
if (value == NULL || !PyUnicode_Check(value)) {
PyErr_SetString(PyExc_TypeError,
"__name__ must be set to a string object");
return -1;
}
Py_INCREF(value);
Py_XSETREF(op->func_name, value);
return 0;
}
static PyObject *
func_get_qualname(PyFunctionObject *op)
{
Py_INCREF(op->func_qualname);
return op->func_qualname;
}
static int
func_set_qualname(PyFunctionObject *op, PyObject *value)
{
/* Not legal to del f.__qualname__ or to set it to anything
* other than a string object. */
if (value == NULL || !PyUnicode_Check(value)) {
PyErr_SetString(PyExc_TypeError,
"__qualname__ must be set to a string object");
return -1;
}
Py_INCREF(value);
Py_XSETREF(op->func_qualname, value);
return 0;
}
static PyObject *
func_get_defaults(PyFunctionObject *op)
{
if (op->func_defaults == NULL) {
Py_RETURN_NONE;
}
Py_INCREF(op->func_defaults);
return op->func_defaults;
}
static int
func_set_defaults(PyFunctionObject *op, PyObject *value)
{
/* Legal to del f.func_defaults.
* Can only set func_defaults to NULL or a tuple. */
if (value == Py_None)
value = NULL;
if (value != NULL && !PyTuple_Check(value)) {
PyErr_SetString(PyExc_TypeError,
"__defaults__ must be set to a tuple object");
return -1;
}
Py_XINCREF(value);
Py_XSETREF(op->func_defaults, value);
return 0;
}
static PyObject *
func_get_kwdefaults(PyFunctionObject *op)
{
if (op->func_kwdefaults == NULL) {
Py_RETURN_NONE;
}
Py_INCREF(op->func_kwdefaults);
return op->func_kwdefaults;
}
static int
func_set_kwdefaults(PyFunctionObject *op, PyObject *value)
{
if (value == Py_None)
value = NULL;
/* Legal to del f.func_kwdefaults.
* Can only set func_kwdefaults to NULL or a dict. */
if (value != NULL && !PyDict_Check(value)) {
PyErr_SetString(PyExc_TypeError,
"__kwdefaults__ must be set to a dict object");
return -1;
}
Py_XINCREF(value);
Py_XSETREF(op->func_kwdefaults, value);
return 0;
}
static PyObject *
func_get_annotations(PyFunctionObject *op)
{
if (op->func_annotations == NULL) {
op->func_annotations = PyDict_New();
if (op->func_annotations == NULL)
return NULL;
}
Py_INCREF(op->func_annotations);
return op->func_annotations;
}
static int
func_set_annotations(PyFunctionObject *op, PyObject *value)
{
if (value == Py_None)
value = NULL;
/* Legal to del f.func_annotations.
* Can only set func_annotations to NULL (through C api)
* or a dict. */
if (value != NULL && !PyDict_Check(value)) {
PyErr_SetString(PyExc_TypeError,
"__annotations__ must be set to a dict object");
return -1;
}
Py_XINCREF(value);
Py_XSETREF(op->func_annotations, value);
return 0;
}
static PyGetSetDef func_getsetlist[] = {
{"__code__", (getter)func_get_code, (setter)func_set_code},
{"__defaults__", (getter)func_get_defaults,
(setter)func_set_defaults},
{"__kwdefaults__", (getter)func_get_kwdefaults,
(setter)func_set_kwdefaults},
{"__annotations__", (getter)func_get_annotations,
(setter)func_set_annotations},
{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
{"__name__", (getter)func_get_name, (setter)func_set_name},
{"__qualname__", (getter)func_get_qualname, (setter)func_set_qualname},
{NULL} /* Sentinel */
};
/*[clinic input]
class function "PyFunctionObject *" "&PyFunction_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=70af9c90aa2e71b0]*/
#include "clinic/funcobject.c.h"
/* function.__new__() maintains the following invariants for closures.
The closure must correspond to the free variables of the code object.
if len(code.co_freevars) == 0:
closure = NULL
else:
len(closure) == len(code.co_freevars)
for every elt in closure, type(elt) == cell
*/
/*[clinic input]
@classmethod
function.__new__ as func_new
code: object(type="PyCodeObject *", subclass_of="&PyCode_Type")
a code object
globals: object(subclass_of="&PyDict_Type")
the globals dictionary
name: object = None
a string that overrides the name from the code object
argdefs as defaults: object = None
a tuple that specifies the default argument values
closure: object = None
a tuple that supplies the bindings for free variables
Create a function object.
[clinic start generated code]*/
static PyObject *
func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals,
PyObject *name, PyObject *defaults, PyObject *closure)
/*[clinic end generated code: output=99c6d9da3a24e3be input=93611752fc2daf11]*/
{
PyFunctionObject *newfunc;
Py_ssize_t nfree, nclosure;
if (name != Py_None && !PyUnicode_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"arg 3 (name) must be None or string");
return NULL;
}
if (defaults != Py_None && !PyTuple_Check(defaults)) {
PyErr_SetString(PyExc_TypeError,
"arg 4 (defaults) must be None or tuple");
return NULL;
}
nfree = PyTuple_GET_SIZE(code->co_freevars);
if (!PyTuple_Check(closure)) {
if (nfree && closure == Py_None) {
PyErr_SetString(PyExc_TypeError,
"arg 5 (closure) must be tuple");
return NULL;
}
else if (closure != Py_None) {
PyErr_SetString(PyExc_TypeError,
"arg 5 (closure) must be None or tuple");
return NULL;
}
}
/* check that the closure is well-formed */
nclosure = closure == Py_None ? 0 : PyTuple_GET_SIZE(closure);
if (nfree != nclosure)
return PyErr_Format(PyExc_ValueError,
"%U requires closure of length %zd, not %zd",
code->co_name, nfree, nclosure);
if (nclosure) {
Py_ssize_t i;
for (i = 0; i < nclosure; i++) {
PyObject *o = PyTuple_GET_ITEM(closure, i);
if (!PyCell_Check(o)) {
return PyErr_Format(PyExc_TypeError,
"arg 5 (closure) expected cell, found %s",
o->ob_type->tp_name);
}
}
}
newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code,
globals);
if (newfunc == NULL)
return NULL;
if (name != Py_None) {
Py_INCREF(name);
Py_SETREF(newfunc->func_name, name);
}
if (defaults != Py_None) {
Py_INCREF(defaults);
newfunc->func_defaults = defaults;
}
if (closure != Py_None) {
Py_INCREF(closure);
newfunc->func_closure = closure;
}
return (PyObject *)newfunc;
}
static void
func_dealloc(PyFunctionObject *op)
{
_PyObject_GC_UNTRACK(op);
if (op->func_weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) op);
Py_DECREF(op->func_code);
Py_DECREF(op->func_globals);
Py_XDECREF(op->func_module);
Py_DECREF(op->func_name);
Py_XDECREF(op->func_defaults);
Py_XDECREF(op->func_kwdefaults);
Py_XDECREF(op->func_doc);
Py_XDECREF(op->func_dict);
Py_XDECREF(op->func_closure);
Py_XDECREF(op->func_annotations);
Py_XDECREF(op->func_qualname);
PyObject_GC_Del(op);
}
static PyObject*
func_repr(PyFunctionObject *op)
{
return PyUnicode_FromFormat("