cpython/Objects/funcobject.c

267 lines
6.1 KiB
C
Raw Normal View History

1991-02-19 08:39:46 -04:00
/***********************************************************
2000-06-30 20:50:40 -03:00
Copyright (c) 2000, BeOpen.com.
Copyright (c) 1995-2000, Corporation for National Research Initiatives.
Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
All rights reserved.
1996-10-25 11:44:06 -03:00
2000-06-30 20:50:40 -03:00
See the file "Misc/COPYRIGHT" for information on usage and
redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
1991-02-19 08:39:46 -04:00
******************************************************************/
1990-10-14 09:07:46 -03:00
/* Function object implementation */
1997-05-02 00:12:38 -03:00
#include "Python.h"
#include "compile.h"
1990-12-20 11:06:42 -04:00
#include "structmember.h"
1990-10-14 09:07:46 -03:00
1997-05-02 00:12:38 -03:00
PyObject *
2000-07-09 03:03:25 -03:00
PyFunction_New(PyObject *code, PyObject *globals)
1990-10-14 09:07:46 -03:00
{
1997-05-02 00:12:38 -03:00
PyFunctionObject *op = PyObject_NEW(PyFunctionObject,
&PyFunction_Type);
1990-10-14 09:07:46 -03:00
if (op != NULL) {
1997-05-02 00:12:38 -03:00
PyObject *doc;
PyObject *consts;
Py_INCREF(code);
op->func_code = code;
1997-05-02 00:12:38 -03:00
Py_INCREF(globals);
1990-10-14 09:07:46 -03:00
op->func_globals = globals;
1997-05-02 00:12:38 -03:00
op->func_name = ((PyCodeObject *)code)->co_name;
Py_INCREF(op->func_name);
op->func_defaults = NULL; /* No default arguments */
1997-05-02 00:12:38 -03:00
consts = ((PyCodeObject *)code)->co_consts;
if (PyTuple_Size(consts) >= 1) {
doc = PyTuple_GetItem(consts, 0);
if (!PyString_Check(doc) && !PyUnicode_Check(doc))
1997-05-02 00:12:38 -03:00
doc = Py_None;
}
else
1997-05-02 00:12:38 -03:00
doc = Py_None;
Py_INCREF(doc);
op->func_doc = doc;
1990-10-14 09:07:46 -03:00
}
PyObject_GC_Init(op);
1997-05-02 00:12:38 -03:00
return (PyObject *)op;
1990-10-14 09:07:46 -03:00
}
1997-05-02 00:12:38 -03:00
PyObject *
2000-07-09 03:03:25 -03:00
PyFunction_GetCode(PyObject *op)
1990-10-14 09:07:46 -03:00
{
1997-05-02 00:12:38 -03:00
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
1990-10-14 09:07:46 -03:00
return NULL;
}
1997-05-02 00:12:38 -03:00
return ((PyFunctionObject *) op) -> func_code;
1990-10-14 09:07:46 -03:00
}
1997-05-02 00:12:38 -03:00
PyObject *
2000-07-09 03:03:25 -03:00
PyFunction_GetGlobals(PyObject *op)
1990-10-14 09:07:46 -03:00
{
1997-05-02 00:12:38 -03:00
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
1990-10-14 09:07:46 -03:00
return NULL;
}
1997-05-02 00:12:38 -03:00
return ((PyFunctionObject *) op) -> func_globals;
1990-10-14 09:07:46 -03:00
}
1997-05-02 00:12:38 -03:00
PyObject *
2000-07-09 03:03:25 -03:00
PyFunction_GetDefaults(PyObject *op)
1994-08-30 05:27:36 -03:00
{
1997-05-02 00:12:38 -03:00
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
1994-08-30 05:27:36 -03:00
return NULL;
}
1997-05-02 00:12:38 -03:00
return ((PyFunctionObject *) op) -> func_defaults;
1994-08-30 05:27:36 -03:00
}
int
2000-07-09 03:03:25 -03:00
PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
1994-08-30 05:27:36 -03:00
{
1997-05-02 00:12:38 -03:00
if (!PyFunction_Check(op)) {
PyErr_BadInternalCall();
1994-08-30 05:27:36 -03:00
return -1;
}
1997-05-02 00:12:38 -03:00
if (defaults == Py_None)
defaults = NULL;
1998-04-10 19:16:39 -03:00
else if (PyTuple_Check(defaults)) {
1997-05-02 00:12:38 -03:00
Py_XINCREF(defaults);
1998-04-10 19:16:39 -03:00
}
1994-08-30 05:27:36 -03:00
else {
1997-05-02 00:12:38 -03:00
PyErr_SetString(PyExc_SystemError, "non-tuple default args");
1994-08-30 05:27:36 -03:00
return -1;
}
1997-05-02 00:12:38 -03:00
Py_XDECREF(((PyFunctionObject *) op) -> func_defaults);
((PyFunctionObject *) op) -> func_defaults = defaults;
1994-08-30 05:27:36 -03:00
return 0;
}
1990-10-14 09:07:46 -03:00
/* Methods */
1997-05-02 00:12:38 -03:00
#define OFF(x) offsetof(PyFunctionObject, x)
1990-12-20 11:06:42 -04:00
static struct memberlist func_memberlist[] = {
{"func_code", T_OBJECT, OFF(func_code)},
{"func_globals",T_OBJECT, OFF(func_globals), READONLY},
{"func_name", T_OBJECT, OFF(func_name), READONLY},
1995-01-10 06:39:49 -04:00
{"__name__", T_OBJECT, OFF(func_name), READONLY},
{"func_defaults",T_OBJECT, OFF(func_defaults)},
{"func_doc", T_OBJECT, OFF(func_doc)},
{"__doc__", T_OBJECT, OFF(func_doc)},
1990-12-20 11:06:42 -04:00
{NULL} /* Sentinel */
};
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 03:03:25 -03:00
func_getattr(PyFunctionObject *op, char *name)
1990-12-20 11:06:42 -04:00
{
1997-05-02 00:12:38 -03:00
if (name[0] != '_' && PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
1995-01-10 06:39:49 -04:00
"function attributes not accessible in restricted mode");
return NULL;
}
1997-05-02 00:12:38 -03:00
return PyMember_Get((char *)op, func_memberlist, name);
1990-12-20 11:06:42 -04:00
}
static int
2000-07-09 03:03:25 -03:00
func_setattr(PyFunctionObject *op, char *name, PyObject *value)
{
if (PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
"function attributes not settable in restricted mode");
return -1;
}
if (strcmp(name, "func_code") == 0) {
if (value == NULL || !PyCode_Check(value)) {
PyErr_SetString(
PyExc_TypeError,
"func_code must be set to a code object");
return -1;
}
}
else if (strcmp(name, "func_defaults") == 0) {
if (value != Py_None && !PyTuple_Check(value)) {
PyErr_SetString(
PyExc_TypeError,
"func_defaults must be set to a tuple object");
return -1;
}
if (value == Py_None)
value = NULL;
}
return PyMember_Set((char *)op, func_memberlist, name, value);
}
1990-10-14 09:07:46 -03:00
static void
2000-07-09 03:03:25 -03:00
func_dealloc(PyFunctionObject *op)
1990-10-14 09:07:46 -03:00
{
PyObject_GC_Fini(op);
1997-05-02 00:12:38 -03:00
Py_DECREF(op->func_code);
Py_DECREF(op->func_globals);
Py_DECREF(op->func_name);
Py_XDECREF(op->func_defaults);
Py_XDECREF(op->func_doc);
2000-06-30 22:00:38 -03:00
op = (PyFunctionObject *) PyObject_AS_GC(op);
PyObject_DEL(op);
1990-10-14 09:07:46 -03:00
}
1997-05-02 00:12:38 -03:00
static PyObject*
2000-07-09 03:03:25 -03:00
func_repr(PyFunctionObject *op)
{
char buf[140];
1997-05-02 00:12:38 -03:00
if (op->func_name == Py_None)
sprintf(buf, "<anonymous function at %p>", op);
else
sprintf(buf, "<function %.100s at %p>",
1997-05-02 00:12:38 -03:00
PyString_AsString(op->func_name),
op);
1997-05-02 00:12:38 -03:00
return PyString_FromString(buf);
}
static int
2000-07-09 03:03:25 -03:00
func_compare(PyFunctionObject *f, PyFunctionObject *g)
{
1994-08-30 05:27:36 -03:00
int c;
if (f->func_globals != g->func_globals)
return (f->func_globals < g->func_globals) ? -1 : 1;
if (f->func_defaults != g->func_defaults) {
if (f->func_defaults == NULL)
return -1;
if (g->func_defaults == NULL)
return 1;
c = PyObject_Compare(f->func_defaults, g->func_defaults);
if (c != 0)
return c;
}
1997-05-02 00:12:38 -03:00
return PyObject_Compare(f->func_code, g->func_code);
}
static long
2000-07-09 03:03:25 -03:00
func_hash(PyFunctionObject *f)
{
long h,x;
1997-05-02 00:12:38 -03:00
h = PyObject_Hash(f->func_code);
if (h == -1) return h;
x = _Py_HashPointer(f->func_globals);
if (x == -1) return x;
h ^= x;
if (h == -1) h = -2;
return h;
}
static int
func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
{
int err;
if (f->func_code) {
err = visit(f->func_code, arg);
if (err)
return err;
}
if (f->func_globals) {
err = visit(f->func_globals, arg);
if (err)
return err;
}
if (f->func_defaults) {
err = visit(f->func_defaults, arg);
if (err)
return err;
}
if (f->func_doc) {
err = visit(f->func_doc, arg);
if (err)
return err;
}
if (f->func_name) {
err = visit(f->func_name, arg);
if (err)
return err;
}
return 0;
}
1997-05-02 00:12:38 -03:00
PyTypeObject PyFunction_Type = {
PyObject_HEAD_INIT(&PyType_Type)
1990-10-14 09:07:46 -03:00
0,
"function",
sizeof(PyFunctionObject) + PyGC_HEAD_SIZE,
1990-10-14 09:07:46 -03:00
0,
1994-08-30 05:27:36 -03:00
(destructor)func_dealloc, /*tp_dealloc*/
0, /*tp_print*/
1994-08-30 05:27:36 -03:00
(getattrfunc)func_getattr, /*tp_getattr*/
(setattrfunc)func_setattr, /*tp_setattr*/
1994-08-30 05:27:36 -03:00
(cmpfunc)func_compare, /*tp_compare*/
(reprfunc)func_repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
1994-08-30 05:27:36 -03:00
(hashfunc)func_hash, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
0, /* tp_doc */
(traverseproc)func_traverse, /* tp_traverse */
1990-10-14 09:07:46 -03:00
};