blob: e766ba5e89fd882e2e324a29dfdca390fbe8a8d3 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* Method object implementation */
3
Guido van Rossumc0b618a1997-05-02 03:12:38 +00004#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005
Guido van Rossum1f39c5c1997-08-05 02:11:41 +00006static PyCFunctionObject *free_list = NULL;
7
Guido van Rossumc0b618a1997-05-02 03:12:38 +00008PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +00009PyCFunction_New(PyMethodDef *ml, PyObject *self)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010{
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000011 PyCFunctionObject *op;
12 op = free_list;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013 if (op != NULL) {
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000014 free_list = (PyCFunctionObject *)(op->m_self);
Guido van Rossumb18618d2000-05-03 23:44:39 +000015 PyObject_INIT(op, &PyCFunction_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000016 }
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000017 else {
18 op = PyObject_NEW(PyCFunctionObject, &PyCFunction_Type);
19 if (op == NULL)
20 return NULL;
21 }
22 op->m_ml = ml;
23 Py_XINCREF(self);
24 op->m_self = self;
Neil Schemenauer10c66922001-07-12 13:27:35 +000025 PyObject_GC_Init(op);
Guido van Rossumc0b618a1997-05-02 03:12:38 +000026 return (PyObject *)op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000027}
28
Guido van Rossumc0b618a1997-05-02 03:12:38 +000029PyCFunction
Fred Drakeee238b92000-07-09 06:03:25 +000030PyCFunction_GetFunction(PyObject *op)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000031{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000032 if (!PyCFunction_Check(op)) {
33 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000034 return NULL;
35 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000036 return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000037}
38
Guido van Rossumc0b618a1997-05-02 03:12:38 +000039PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +000040PyCFunction_GetSelf(PyObject *op)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000042 if (!PyCFunction_Check(op)) {
43 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044 return NULL;
45 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000046 return ((PyCFunctionObject *)op) -> m_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047}
48
Guido van Rossumc0602291991-12-16 13:07:24 +000049int
Fred Drakeee238b92000-07-09 06:03:25 +000050PyCFunction_GetFlags(PyObject *op)
Guido van Rossumc0602291991-12-16 13:07:24 +000051{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000052 if (!PyCFunction_Check(op)) {
53 PyErr_BadInternalCall();
Guido van Rossumc0602291991-12-16 13:07:24 +000054 return -1;
55 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000056 return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
Guido van Rossumc0602291991-12-16 13:07:24 +000057}
58
Jeremy Hylton910d7d42001-08-12 21:52:24 +000059PyObject *
60PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
61{
62 PyCFunctionObject* f = (PyCFunctionObject*)func;
63 PyCFunction meth = PyCFunction_GET_FUNCTION(func);
64 PyObject *self = PyCFunction_GET_SELF(func);
65 int flags = PyCFunction_GET_FLAGS(func);
Martin v. Löwise3eb1f22001-08-16 13:15:00 +000066 int size = PyTuple_GET_SIZE(arg);
Jeremy Hylton910d7d42001-08-12 21:52:24 +000067
68 if (flags & METH_KEYWORDS) {
69 return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
70 }
71 if (kw != NULL && PyDict_Size(kw) != 0) {
72 PyErr_Format(PyExc_TypeError,
73 "%.200s() takes no keyword arguments",
74 f->m_ml->ml_name);
75 return NULL;
76 }
Martin v. Löwise3eb1f22001-08-16 13:15:00 +000077
78 switch (flags) {
79 case METH_VARARGS:
Jeremy Hylton910d7d42001-08-12 21:52:24 +000080 return (*meth)(self, arg);
Martin v. Löwise3eb1f22001-08-16 13:15:00 +000081 break;
82 case METH_NOARGS:
83 if (size == 0)
84 return (*meth)(self, NULL);
85 PyErr_Format(PyExc_TypeError,
86 "%.200s() takes no arguments (%d given)",
87 f->m_ml->ml_name, size);
88 return NULL;
89 break;
90 case METH_O:
91 if (size == 1)
92 return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
93 PyErr_Format(PyExc_TypeError,
94 "%.200s() takes exactly one argument (%d given)",
95 f->m_ml->ml_name, size);
96 return NULL;
97 break;
98 case METH_OLDARGS:
Jeremy Hylton910d7d42001-08-12 21:52:24 +000099 /* the really old style */
Jeremy Hylton910d7d42001-08-12 21:52:24 +0000100 if (size == 1)
101 arg = PyTuple_GET_ITEM(arg, 0);
102 else if (size == 0)
103 arg = NULL;
104 return (*meth)(self, arg);
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000105 default:
106 /* should never get here ??? */
107 PyErr_BadInternalCall();
108 return NULL;
Jeremy Hylton910d7d42001-08-12 21:52:24 +0000109 }
Jeremy Hylton910d7d42001-08-12 21:52:24 +0000110}
111
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112/* Methods (the standard built-in methods, that is) */
113
114static void
Fred Drakeee238b92000-07-09 06:03:25 +0000115meth_dealloc(PyCFunctionObject *m)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116{
Neil Schemenauer10c66922001-07-12 13:27:35 +0000117 PyObject_GC_Fini(m);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000118 Py_XDECREF(m->m_self);
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000119 m->m_self = (PyObject *)free_list;
120 free_list = m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121}
122
Tim Peters6d6c1a32001-08-02 04:15:00 +0000123static PyObject *
124meth_get__doc__(PyCFunctionObject *m, void *closure)
125{
126 char *doc = m->m_ml->ml_doc;
127
128 if (doc != NULL)
129 return PyString_FromString(doc);
130 Py_INCREF(Py_None);
131 return Py_None;
132}
133
134static PyObject *
135meth_get__name__(PyCFunctionObject *m, void *closure)
136{
137 return PyString_FromString(m->m_ml->ml_name);
138}
139
Neil Schemenauer10c66922001-07-12 13:27:35 +0000140static int
141meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
142{
143 if (m->m_self != NULL)
144 return visit(m->m_self, arg);
145 else
146 return 0;
147}
148
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000149static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000150meth_get__self__(PyCFunctionObject *m, void *closure)
Guido van Rossumcab650d1995-01-07 12:34:58 +0000151{
Tim Peters6d6c1a32001-08-02 04:15:00 +0000152 PyObject *self;
153 if (PyEval_GetRestricted()) {
154 PyErr_SetString(PyExc_RuntimeError,
155 "method.__self__ not accessible in restricted mode");
156 return NULL;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000157 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000158 self = m->m_self;
159 if (self == NULL)
160 self = Py_None;
161 Py_INCREF(self);
162 return self;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000163}
164
Tim Peters6d6c1a32001-08-02 04:15:00 +0000165static struct getsetlist meth_getsets [] = {
166 {"__doc__", (getter)meth_get__doc__, NULL, NULL},
167 {"__name__", (getter)meth_get__name__, NULL, NULL},
168 {"__self__", (getter)meth_get__self__, NULL, NULL},
169 {0}
170};
171
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000172static PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000173meth_repr(PyCFunctionObject *m)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000175 if (m->m_self == NULL)
Barry Warsaw7ce36942001-08-24 18:34:26 +0000176 return PyString_FromFormat("<built-in function %s>",
177 m->m_ml->ml_name);
178 return PyString_FromFormat("<built-in method %s of %s object at %p>",
179 m->m_ml->ml_name,
180 m->m_self->ob_type->tp_name,
181 m->m_self);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182}
183
Guido van Rossum9bfef441993-03-29 10:43:31 +0000184static int
Fred Drakeee238b92000-07-09 06:03:25 +0000185meth_compare(PyCFunctionObject *a, PyCFunctionObject *b)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000186{
187 if (a->m_self != b->m_self)
Guido van Rossum13fdf5e1998-12-04 18:52:55 +0000188 return (a->m_self < b->m_self) ? -1 : 1;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000189 if (a->m_ml->ml_meth == b->m_ml->ml_meth)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000190 return 0;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000191 if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000192 return -1;
193 else
194 return 1;
195}
196
197static long
Fred Drakeee238b92000-07-09 06:03:25 +0000198meth_hash(PyCFunctionObject *a)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000199{
Fred Drake13634cf2000-06-29 19:17:04 +0000200 long x,y;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000201 if (a->m_self == NULL)
202 x = 0;
203 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204 x = PyObject_Hash(a->m_self);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000205 if (x == -1)
206 return -1;
207 }
Guido van Rossum9a15c212000-06-30 22:46:04 +0000208 y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
Fred Drake13634cf2000-06-29 19:17:04 +0000209 if (y == -1)
210 return -1;
211 x ^= y;
212 if (x == -1)
213 x = -2;
214 return x;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000215}
216
Tim Peters6d6c1a32001-08-02 04:15:00 +0000217
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000218PyTypeObject PyCFunction_Type = {
219 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220 0,
Guido van Rossum7066dd71992-09-17 17:54:56 +0000221 "builtin_function_or_method",
Neil Schemenauer10c66922001-07-12 13:27:35 +0000222 sizeof(PyCFunctionObject) + PyGC_HEAD_SIZE,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000223 0,
Neil Schemenauer10c66922001-07-12 13:27:35 +0000224 (destructor)meth_dealloc, /* tp_dealloc */
225 0, /* tp_print */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000226 0, /* tp_getattr */
Neil Schemenauer10c66922001-07-12 13:27:35 +0000227 0, /* tp_setattr */
228 (cmpfunc)meth_compare, /* tp_compare */
229 (reprfunc)meth_repr, /* tp_repr */
230 0, /* tp_as_number */
231 0, /* tp_as_sequence */
232 0, /* tp_as_mapping */
233 (hashfunc)meth_hash, /* tp_hash */
Jeremy Hylton910d7d42001-08-12 21:52:24 +0000234 PyCFunction_Call, /* tp_call */
Neil Schemenauer10c66922001-07-12 13:27:35 +0000235 0, /* tp_str */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000236 PyObject_GenericGetAttr, /* tp_getattro */
Neil Schemenauer10c66922001-07-12 13:27:35 +0000237 0, /* tp_setattro */
238 0, /* tp_as_buffer */
239 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */
240 0, /* tp_doc */
241 (traverseproc)meth_traverse, /* tp_traverse */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000242 0, /* tp_clear */
243 0, /* tp_richcompare */
244 0, /* tp_weaklistoffset */
245 0, /* tp_iter */
246 0, /* tp_iternext */
247 0, /* tp_methods */
248 0, /* tp_members */
249 meth_getsets, /* tp_getset */
250 0, /* tp_base */
251 0, /* tp_dict */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000252};
Guido van Rossum3f5da241990-12-20 15:06:42 +0000253
Guido van Rossum69785031995-01-26 22:58:48 +0000254/* List all methods in a chain -- helper for findmethodinchain */
Guido van Rossume9c430f1991-10-20 20:21:15 +0000255
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000256static PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000257listmethodchain(PyMethodChain *chain)
Guido van Rossume9c430f1991-10-20 20:21:15 +0000258{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000259 PyMethodChain *c;
260 PyMethodDef *ml;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000261 int i, n;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000262 PyObject *v;
Guido van Rossum69785031995-01-26 22:58:48 +0000263
264 n = 0;
265 for (c = chain; c != NULL; c = c->link) {
266 for (ml = c->methods; ml->ml_name != NULL; ml++)
267 n++;
268 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000269 v = PyList_New(n);
Guido van Rossum69785031995-01-26 22:58:48 +0000270 if (v == NULL)
271 return NULL;
272 i = 0;
273 for (c = chain; c != NULL; c = c->link) {
274 for (ml = c->methods; ml->ml_name != NULL; ml++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000275 PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
Guido van Rossum69785031995-01-26 22:58:48 +0000276 i++;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000277 }
278 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000279 if (PyErr_Occurred()) {
280 Py_DECREF(v);
Guido van Rossum69785031995-01-26 22:58:48 +0000281 return NULL;
282 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000283 PyList_Sort(v);
Guido van Rossume9c430f1991-10-20 20:21:15 +0000284 return v;
285}
286
Guido van Rossum69785031995-01-26 22:58:48 +0000287/* Find a method in a method chain */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000288
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000289PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000290Py_FindMethodInChain(PyMethodChain *chain, PyObject *self, char *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000291{
Guido van Rossum8a92c621998-06-27 18:28:59 +0000292 if (name[0] == '_' && name[1] == '_') {
293 if (strcmp(name, "__methods__") == 0)
294 return listmethodchain(chain);
295 if (strcmp(name, "__doc__") == 0) {
296 char *doc = self->ob_type->tp_doc;
297 if (doc != NULL)
298 return PyString_FromString(doc);
299 }
300 }
Guido van Rossum69785031995-01-26 22:58:48 +0000301 while (chain != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000302 PyMethodDef *ml = chain->methods;
Guido van Rossum69785031995-01-26 22:58:48 +0000303 for (; ml->ml_name != NULL; ml++) {
304 if (name[0] == ml->ml_name[0] &&
305 strcmp(name+1, ml->ml_name+1) == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306 return PyCFunction_New(ml, self);
Guido van Rossum69785031995-01-26 22:58:48 +0000307 }
308 chain = chain->link;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000309 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000311 return NULL;
312}
Guido van Rossum69785031995-01-26 22:58:48 +0000313
314/* Find a method in a single method list */
315
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000316PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000317Py_FindMethod(PyMethodDef *methods, PyObject *self, char *name)
Guido van Rossum69785031995-01-26 22:58:48 +0000318{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000319 PyMethodChain chain;
Guido van Rossum69785031995-01-26 22:58:48 +0000320 chain.methods = methods;
321 chain.link = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000322 return Py_FindMethodInChain(&chain, self, name);
Guido van Rossum69785031995-01-26 22:58:48 +0000323}
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000324
325/* Clear out the free list */
326
327void
Fred Drakeee238b92000-07-09 06:03:25 +0000328PyCFunction_Fini(void)
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000329{
330 while (free_list) {
331 PyCFunctionObject *v = free_list;
332 free_list = (PyCFunctionObject *)(v->m_self);
Neil Schemenauer10c66922001-07-12 13:27:35 +0000333 v = (PyCFunctionObject *) PyObject_AS_GC(v);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000334 PyObject_DEL(v);
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000335 }
336}