blob: 8b045f4695ea2f6c2903d4144d632971ac6c7a6f [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* Function object implementation */
3
Guido van Rossumc0b618a1997-05-02 03:12:38 +00004#include "Python.h"
Guido van Rossum9bfef441993-03-29 10:43:31 +00005#include "compile.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +00006#include "structmember.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007
Guido van Rossumc0b618a1997-05-02 03:12:38 +00008PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +00009PyFunction_New(PyObject *code, PyObject *globals)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000011 PyFunctionObject *op = PyObject_NEW(PyFunctionObject,
12 &PyFunction_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013 if (op != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000014 PyObject *doc;
15 PyObject *consts;
16 Py_INCREF(code);
Guido van Rossum846e4311990-11-18 17:44:06 +000017 op->func_code = code;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000018 Py_INCREF(globals);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000019 op->func_globals = globals;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000020 op->func_name = ((PyCodeObject *)code)->co_name;
21 Py_INCREF(op->func_name);
Guido van Rossum2271bf71995-07-18 14:30:34 +000022 op->func_defaults = NULL; /* No default arguments */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000023 consts = ((PyCodeObject *)code)->co_consts;
24 if (PyTuple_Size(consts) >= 1) {
25 doc = PyTuple_GetItem(consts, 0);
Guido van Rossumec5b7762000-04-27 20:14:13 +000026 if (!PyString_Check(doc) && !PyUnicode_Check(doc))
Guido van Rossumc0b618a1997-05-02 03:12:38 +000027 doc = Py_None;
Guido van Rossum5bd38051995-01-07 12:01:30 +000028 }
29 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000030 doc = Py_None;
31 Py_INCREF(doc);
Guido van Rossum5bd38051995-01-07 12:01:30 +000032 op->func_doc = doc;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000033 }
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000034 PyObject_GC_Init(op);
Guido van Rossumc0b618a1997-05-02 03:12:38 +000035 return (PyObject *)op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036}
37
Guido van Rossumc0b618a1997-05-02 03:12:38 +000038PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +000039PyFunction_GetCode(PyObject *op)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000040{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000041 if (!PyFunction_Check(op)) {
42 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043 return NULL;
44 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000045 return ((PyFunctionObject *) op) -> func_code;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046}
47
Guido van Rossumc0b618a1997-05-02 03:12:38 +000048PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +000049PyFunction_GetGlobals(PyObject *op)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000051 if (!PyFunction_Check(op)) {
52 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053 return NULL;
54 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000055 return ((PyFunctionObject *) op) -> func_globals;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000056}
57
Guido van Rossumc0b618a1997-05-02 03:12:38 +000058PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +000059PyFunction_GetDefaults(PyObject *op)
Guido van Rossum1d5735e1994-08-30 08:27:36 +000060{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000061 if (!PyFunction_Check(op)) {
62 PyErr_BadInternalCall();
Guido van Rossum1d5735e1994-08-30 08:27:36 +000063 return NULL;
64 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000065 return ((PyFunctionObject *) op) -> func_defaults;
Guido van Rossum1d5735e1994-08-30 08:27:36 +000066}
67
68int
Fred Drakeee238b92000-07-09 06:03:25 +000069PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
Guido van Rossum1d5735e1994-08-30 08:27:36 +000070{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000071 if (!PyFunction_Check(op)) {
72 PyErr_BadInternalCall();
Guido van Rossum1d5735e1994-08-30 08:27:36 +000073 return -1;
74 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000075 if (defaults == Py_None)
Guido van Rossum2271bf71995-07-18 14:30:34 +000076 defaults = NULL;
Guido van Rossum1109fbc1998-04-10 22:16:39 +000077 else if (PyTuple_Check(defaults)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000078 Py_XINCREF(defaults);
Guido van Rossum1109fbc1998-04-10 22:16:39 +000079 }
Guido van Rossum1d5735e1994-08-30 08:27:36 +000080 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000081 PyErr_SetString(PyExc_SystemError, "non-tuple default args");
Guido van Rossum1d5735e1994-08-30 08:27:36 +000082 return -1;
83 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000084 Py_XDECREF(((PyFunctionObject *) op) -> func_defaults);
85 ((PyFunctionObject *) op) -> func_defaults = defaults;
Guido van Rossum1d5735e1994-08-30 08:27:36 +000086 return 0;
87}
88
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089/* Methods */
90
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091#define OFF(x) offsetof(PyFunctionObject, x)
Guido van Rossum3f5da241990-12-20 15:06:42 +000092
93static struct memberlist func_memberlist[] = {
Guido van Rossum0dabace1998-05-22 00:55:34 +000094 {"func_code", T_OBJECT, OFF(func_code)},
Guido van Rossuma38c0ff1992-01-14 18:32:20 +000095 {"func_globals",T_OBJECT, OFF(func_globals), READONLY},
Guido van Rossum25831651993-05-19 14:50:45 +000096 {"func_name", T_OBJECT, OFF(func_name), READONLY},
Guido van Rossum10393b11995-01-10 10:39:49 +000097 {"__name__", T_OBJECT, OFF(func_name), READONLY},
Guido van Rossum0dabace1998-05-22 00:55:34 +000098 {"func_defaults",T_OBJECT, OFF(func_defaults)},
Guido van Rossum5bd38051995-01-07 12:01:30 +000099 {"func_doc", T_OBJECT, OFF(func_doc)},
100 {"__doc__", T_OBJECT, OFF(func_doc)},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000101 {NULL} /* Sentinel */
102};
103
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000104static PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000105func_getattr(PyFunctionObject *op, char *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000106{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000107 if (name[0] != '_' && PyEval_GetRestricted()) {
108 PyErr_SetString(PyExc_RuntimeError,
Guido van Rossum10393b11995-01-10 10:39:49 +0000109 "function attributes not accessible in restricted mode");
110 return NULL;
111 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000112 return PyMember_Get((char *)op, func_memberlist, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000113}
114
Guido van Rossum0dabace1998-05-22 00:55:34 +0000115static int
Fred Drakeee238b92000-07-09 06:03:25 +0000116func_setattr(PyFunctionObject *op, char *name, PyObject *value)
Guido van Rossum0dabace1998-05-22 00:55:34 +0000117{
118 if (PyEval_GetRestricted()) {
119 PyErr_SetString(PyExc_RuntimeError,
120 "function attributes not settable in restricted mode");
121 return -1;
122 }
123 if (strcmp(name, "func_code") == 0) {
124 if (value == NULL || !PyCode_Check(value)) {
125 PyErr_SetString(
126 PyExc_TypeError,
127 "func_code must be set to a code object");
128 return -1;
129 }
130 }
131 else if (strcmp(name, "func_defaults") == 0) {
132 if (value != Py_None && !PyTuple_Check(value)) {
133 PyErr_SetString(
134 PyExc_TypeError,
135 "func_defaults must be set to a tuple object");
136 return -1;
137 }
138 if (value == Py_None)
139 value = NULL;
140 }
141 return PyMember_Set((char *)op, func_memberlist, name, value);
142}
143
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000144static void
Fred Drakeee238b92000-07-09 06:03:25 +0000145func_dealloc(PyFunctionObject *op)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000146{
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000147 PyObject_GC_Fini(op);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000148 Py_DECREF(op->func_code);
149 Py_DECREF(op->func_globals);
150 Py_DECREF(op->func_name);
151 Py_XDECREF(op->func_defaults);
152 Py_XDECREF(op->func_doc);
Guido van Rossum4cc6ac72000-07-01 01:00:38 +0000153 op = (PyFunctionObject *) PyObject_AS_GC(op);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000154 PyObject_DEL(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155}
156
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000157static PyObject*
Fred Drakeee238b92000-07-09 06:03:25 +0000158func_repr(PyFunctionObject *op)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000159{
160 char buf[140];
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000161 if (op->func_name == Py_None)
Fred Drakea44d3532000-06-30 15:01:00 +0000162 sprintf(buf, "<anonymous function at %p>", op);
Guido van Rossum590baa41993-11-30 13:40:46 +0000163 else
Fred Drakea44d3532000-06-30 15:01:00 +0000164 sprintf(buf, "<function %.100s at %p>",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000165 PyString_AsString(op->func_name),
Fred Drakea44d3532000-06-30 15:01:00 +0000166 op);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000167 return PyString_FromString(buf);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000168}
169
Guido van Rossum2e8f8a31993-11-05 10:20:10 +0000170static int
Fred Drakeee238b92000-07-09 06:03:25 +0000171func_compare(PyFunctionObject *f, PyFunctionObject *g)
Guido van Rossum2e8f8a31993-11-05 10:20:10 +0000172{
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000173 int c;
Guido van Rossum2e8f8a31993-11-05 10:20:10 +0000174 if (f->func_globals != g->func_globals)
175 return (f->func_globals < g->func_globals) ? -1 : 1;
Guido van Rossum83f9ad81997-08-05 16:51:05 +0000176 if (f->func_defaults != g->func_defaults) {
177 if (f->func_defaults == NULL)
178 return -1;
179 if (g->func_defaults == NULL)
180 return 1;
181 c = PyObject_Compare(f->func_defaults, g->func_defaults);
182 if (c != 0)
183 return c;
184 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000185 return PyObject_Compare(f->func_code, g->func_code);
Guido van Rossum2e8f8a31993-11-05 10:20:10 +0000186}
187
188static long
Fred Drakeee238b92000-07-09 06:03:25 +0000189func_hash(PyFunctionObject *f)
Guido van Rossum2e8f8a31993-11-05 10:20:10 +0000190{
Fred Drake13634cf2000-06-29 19:17:04 +0000191 long h,x;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000192 h = PyObject_Hash(f->func_code);
Guido van Rossum2e8f8a31993-11-05 10:20:10 +0000193 if (h == -1) return h;
Fred Drake13634cf2000-06-29 19:17:04 +0000194 x = _Py_HashPointer(f->func_globals);
195 if (x == -1) return x;
196 h ^= x;
Guido van Rossum2e8f8a31993-11-05 10:20:10 +0000197 if (h == -1) h = -2;
198 return h;
199}
200
Jeremy Hylton8caad492000-06-23 14:18:11 +0000201static int
202func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
203{
204 int err;
205 if (f->func_code) {
206 err = visit(f->func_code, arg);
207 if (err)
208 return err;
209 }
210 if (f->func_globals) {
211 err = visit(f->func_globals, arg);
212 if (err)
213 return err;
214 }
215 if (f->func_defaults) {
216 err = visit(f->func_defaults, arg);
217 if (err)
218 return err;
219 }
220 if (f->func_doc) {
221 err = visit(f->func_doc, arg);
222 if (err)
223 return err;
224 }
225 if (f->func_name) {
226 err = visit(f->func_name, arg);
227 if (err)
228 return err;
229 }
230 return 0;
231}
232
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233PyTypeObject PyFunction_Type = {
234 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235 0,
236 "function",
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000237 sizeof(PyFunctionObject) + PyGC_HEAD_SIZE,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000239 (destructor)func_dealloc, /*tp_dealloc*/
Guido van Rossum846e4311990-11-18 17:44:06 +0000240 0, /*tp_print*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000241 (getattrfunc)func_getattr, /*tp_getattr*/
Guido van Rossum0dabace1998-05-22 00:55:34 +0000242 (setattrfunc)func_setattr, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000243 (cmpfunc)func_compare, /*tp_compare*/
244 (reprfunc)func_repr, /*tp_repr*/
Guido van Rossum2e8f8a31993-11-05 10:20:10 +0000245 0, /*tp_as_number*/
246 0, /*tp_as_sequence*/
247 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000248 (hashfunc)func_hash, /*tp_hash*/
Jeremy Hylton8caad492000-06-23 14:18:11 +0000249 0, /*tp_call*/
250 0, /*tp_str*/
251 0, /*tp_getattro*/
252 0, /*tp_setattro*/
253 0, /* tp_as_buffer */
Jeremy Hyltond08b4c42000-06-23 19:37:02 +0000254 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
Jeremy Hylton8caad492000-06-23 14:18:11 +0000255 0, /* tp_doc */
256 (traverseproc)func_traverse, /* tp_traverse */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000257};