blob: 5c69744b7bf21096008be7f70c2b08f0b82183ed [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Method object implementation */
33
Guido van Rossumc0b618a1997-05-02 03:12:38 +000034#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000035
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036#include "token.h"
37
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000038static PyCFunctionObject *free_list = NULL;
39
Guido van Rossumc0b618a1997-05-02 03:12:38 +000040PyObject *
41PyCFunction_New(ml, self)
42 PyMethodDef *ml;
43 PyObject *self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044{
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000045 PyCFunctionObject *op;
46 op = free_list;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047 if (op != NULL) {
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000048 free_list = (PyCFunctionObject *)(op->m_self);
49 op->ob_type = &PyCFunction_Type;
Guido van Rossumbffd6832000-01-20 22:32:56 +000050 _Py_NewReference((PyObject *)op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000051 }
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000052 else {
53 op = PyObject_NEW(PyCFunctionObject, &PyCFunction_Type);
54 if (op == NULL)
55 return NULL;
56 }
57 op->m_ml = ml;
58 Py_XINCREF(self);
59 op->m_self = self;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000060 return (PyObject *)op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061}
62
Guido van Rossumc0b618a1997-05-02 03:12:38 +000063PyCFunction
64PyCFunction_GetFunction(op)
65 PyObject *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000067 if (!PyCFunction_Check(op)) {
68 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069 return NULL;
70 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000071 return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000072}
73
Guido van Rossumc0b618a1997-05-02 03:12:38 +000074PyObject *
75PyCFunction_GetSelf(op)
76 PyObject *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000078 if (!PyCFunction_Check(op)) {
79 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080 return NULL;
81 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000082 return ((PyCFunctionObject *)op) -> m_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083}
84
Guido van Rossumc0602291991-12-16 13:07:24 +000085int
Guido van Rossumc0b618a1997-05-02 03:12:38 +000086PyCFunction_GetFlags(op)
87 PyObject *op;
Guido van Rossumc0602291991-12-16 13:07:24 +000088{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000089 if (!PyCFunction_Check(op)) {
90 PyErr_BadInternalCall();
Guido van Rossumc0602291991-12-16 13:07:24 +000091 return -1;
92 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000093 return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
Guido van Rossumc0602291991-12-16 13:07:24 +000094}
95
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096/* Methods (the standard built-in methods, that is) */
97
98static void
99meth_dealloc(m)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000100 PyCFunctionObject *m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000102 Py_XDECREF(m->m_self);
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000103 m->m_self = (PyObject *)free_list;
104 free_list = m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105}
106
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000107static PyObject *
Guido van Rossumcab650d1995-01-07 12:34:58 +0000108meth_getattr(m, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109 PyCFunctionObject *m;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000110 char *name;
111{
112 if (strcmp(name, "__name__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000113 return PyString_FromString(m->m_ml->ml_name);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000114 }
115 if (strcmp(name, "__doc__") == 0) {
116 char *doc = m->m_ml->ml_doc;
117 if (doc != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000118 return PyString_FromString(doc);
119 Py_INCREF(Py_None);
120 return Py_None;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000121 }
122 if (strcmp(name, "__self__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000123 PyObject *self;
124 if (PyEval_GetRestricted()) {
125 PyErr_SetString(PyExc_RuntimeError,
Guido van Rossum10393b11995-01-10 10:39:49 +0000126 "method.__self__ not accessible in restricted mode");
127 return NULL;
128 }
129 self = m->m_self;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000130 if (self == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000131 self = Py_None;
132 Py_INCREF(self);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000133 return self;
134 }
135 if (strcmp(name, "__members__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000136 return Py_BuildValue("[sss]",
137 "__doc__", "__name__", "__self__");
Guido van Rossumcab650d1995-01-07 12:34:58 +0000138 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000139 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000140 return NULL;
141}
142
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000143static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000144meth_repr(m)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000145 PyCFunctionObject *m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000146{
147 char buf[200];
148 if (m->m_self == NULL)
Guido van Rossumcab650d1995-01-07 12:34:58 +0000149 sprintf(buf, "<built-in function %.80s>", m->m_ml->ml_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150 else
Guido van Rossum3f5da241990-12-20 15:06:42 +0000151 sprintf(buf,
Guido van Rossumb3f72581993-05-21 19:56:10 +0000152 "<built-in method %.80s of %.80s object at %lx>",
Guido van Rossumcab650d1995-01-07 12:34:58 +0000153 m->m_ml->ml_name, m->m_self->ob_type->tp_name,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000154 (long)m->m_self);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000155 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156}
157
Guido van Rossum9bfef441993-03-29 10:43:31 +0000158static int
159meth_compare(a, b)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000160 PyCFunctionObject *a, *b;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000161{
162 if (a->m_self != b->m_self)
Guido van Rossum13fdf5e1998-12-04 18:52:55 +0000163 return (a->m_self < b->m_self) ? -1 : 1;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000164 if (a->m_ml->ml_meth == b->m_ml->ml_meth)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000165 return 0;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000166 if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000167 return -1;
168 else
169 return 1;
170}
171
172static long
173meth_hash(a)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000174 PyCFunctionObject *a;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000175{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000176 long x;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000177 if (a->m_self == NULL)
178 x = 0;
179 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000180 x = PyObject_Hash(a->m_self);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000181 if (x == -1)
182 return -1;
183 }
Guido van Rossumcab650d1995-01-07 12:34:58 +0000184 return x ^ (long) a->m_ml->ml_meth;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000185}
186
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000187PyTypeObject PyCFunction_Type = {
188 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189 0,
Guido van Rossum7066dd71992-09-17 17:54:56 +0000190 "builtin_function_or_method",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000191 sizeof(PyCFunctionObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000193 (destructor)meth_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000194 0, /*tp_print*/
Guido van Rossumcab650d1995-01-07 12:34:58 +0000195 (getattrfunc)meth_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000197 (cmpfunc)meth_compare, /*tp_compare*/
198 (reprfunc)meth_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000199 0, /*tp_as_number*/
200 0, /*tp_as_sequence*/
201 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000202 (hashfunc)meth_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000203};
Guido van Rossum3f5da241990-12-20 15:06:42 +0000204
Guido van Rossum69785031995-01-26 22:58:48 +0000205/* List all methods in a chain -- helper for findmethodinchain */
Guido van Rossume9c430f1991-10-20 20:21:15 +0000206
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000207static PyObject *
Guido van Rossum69785031995-01-26 22:58:48 +0000208listmethodchain(chain)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000209 PyMethodChain *chain;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000210{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000211 PyMethodChain *c;
212 PyMethodDef *ml;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000213 int i, n;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000214 PyObject *v;
Guido van Rossum69785031995-01-26 22:58:48 +0000215
216 n = 0;
217 for (c = chain; c != NULL; c = c->link) {
218 for (ml = c->methods; ml->ml_name != NULL; ml++)
219 n++;
220 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221 v = PyList_New(n);
Guido van Rossum69785031995-01-26 22:58:48 +0000222 if (v == NULL)
223 return NULL;
224 i = 0;
225 for (c = chain; c != NULL; c = c->link) {
226 for (ml = c->methods; ml->ml_name != NULL; ml++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000227 PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
Guido van Rossum69785031995-01-26 22:58:48 +0000228 i++;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000229 }
230 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231 if (PyErr_Occurred()) {
232 Py_DECREF(v);
Guido van Rossum69785031995-01-26 22:58:48 +0000233 return NULL;
234 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235 PyList_Sort(v);
Guido van Rossume9c430f1991-10-20 20:21:15 +0000236 return v;
237}
238
Guido van Rossum69785031995-01-26 22:58:48 +0000239/* Find a method in a method chain */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000240
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000241PyObject *
242Py_FindMethodInChain(chain, self, name)
243 PyMethodChain *chain;
244 PyObject *self;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000245 char *name;
246{
Guido van Rossum8a92c621998-06-27 18:28:59 +0000247 if (name[0] == '_' && name[1] == '_') {
248 if (strcmp(name, "__methods__") == 0)
249 return listmethodchain(chain);
250 if (strcmp(name, "__doc__") == 0) {
251 char *doc = self->ob_type->tp_doc;
252 if (doc != NULL)
253 return PyString_FromString(doc);
254 }
255 }
Guido van Rossum69785031995-01-26 22:58:48 +0000256 while (chain != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000257 PyMethodDef *ml = chain->methods;
Guido van Rossum69785031995-01-26 22:58:48 +0000258 for (; ml->ml_name != NULL; ml++) {
259 if (name[0] == ml->ml_name[0] &&
260 strcmp(name+1, ml->ml_name+1) == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000261 return PyCFunction_New(ml, self);
Guido van Rossum69785031995-01-26 22:58:48 +0000262 }
263 chain = chain->link;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000264 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000265 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000266 return NULL;
267}
Guido van Rossum69785031995-01-26 22:58:48 +0000268
269/* Find a method in a single method list */
270
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000271PyObject *
272Py_FindMethod(methods, self, name)
273 PyMethodDef *methods;
274 PyObject *self;
Guido van Rossum69785031995-01-26 22:58:48 +0000275 char *name;
276{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000277 PyMethodChain chain;
Guido van Rossum69785031995-01-26 22:58:48 +0000278 chain.methods = methods;
279 chain.link = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000280 return Py_FindMethodInChain(&chain, self, name);
Guido van Rossum69785031995-01-26 22:58:48 +0000281}
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000282
283/* Clear out the free list */
284
285void
286PyCFunction_Fini()
287{
288 while (free_list) {
289 PyCFunctionObject *v = free_list;
290 free_list = (PyCFunctionObject *)(v->m_self);
291 PyMem_DEL(v);
292 }
293}