blob: c0befa95c66404d4e5fffeb153e932401b14e466 [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
38typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000039 PyObject_HEAD
40 PyMethodDef *m_ml;
41 PyObject *m_self;
42} PyCFunctionObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043
Guido van Rossumc0b618a1997-05-02 03:12:38 +000044PyObject *
45PyCFunction_New(ml, self)
46 PyMethodDef *ml;
47 PyObject *self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000048{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000049 PyCFunctionObject *op = PyObject_NEW(PyCFunctionObject,
50 &PyCFunction_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000051 if (op != NULL) {
Guido van Rossumcab650d1995-01-07 12:34:58 +000052 op->m_ml = ml;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000053 Py_XINCREF(self);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054 op->m_self = self;
55 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000056 return (PyObject *)op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057}
58
Guido van Rossumc0b618a1997-05-02 03:12:38 +000059PyCFunction
60PyCFunction_GetFunction(op)
61 PyObject *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000062{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000063 if (!PyCFunction_Check(op)) {
64 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000065 return NULL;
66 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000067 return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000068}
69
Guido van Rossumc0b618a1997-05-02 03:12:38 +000070PyObject *
71PyCFunction_GetSelf(op)
72 PyObject *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000074 if (!PyCFunction_Check(op)) {
75 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076 return NULL;
77 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000078 return ((PyCFunctionObject *)op) -> m_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079}
80
Guido van Rossumc0602291991-12-16 13:07:24 +000081int
Guido van Rossumc0b618a1997-05-02 03:12:38 +000082PyCFunction_GetFlags(op)
83 PyObject *op;
Guido van Rossumc0602291991-12-16 13:07:24 +000084{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000085 if (!PyCFunction_Check(op)) {
86 PyErr_BadInternalCall();
Guido van Rossumc0602291991-12-16 13:07:24 +000087 return -1;
88 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000089 return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
Guido van Rossumc0602291991-12-16 13:07:24 +000090}
91
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092/* Methods (the standard built-in methods, that is) */
93
94static void
95meth_dealloc(m)
Guido van Rossumc0b618a1997-05-02 03:12:38 +000096 PyCFunctionObject *m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000098 Py_XDECREF(m->m_self);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099 free((char *)m);
100}
101
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000102static PyObject *
Guido van Rossumcab650d1995-01-07 12:34:58 +0000103meth_getattr(m, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000104 PyCFunctionObject *m;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000105 char *name;
106{
107 if (strcmp(name, "__name__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000108 return PyString_FromString(m->m_ml->ml_name);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000109 }
110 if (strcmp(name, "__doc__") == 0) {
111 char *doc = m->m_ml->ml_doc;
112 if (doc != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000113 return PyString_FromString(doc);
114 Py_INCREF(Py_None);
115 return Py_None;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000116 }
117 if (strcmp(name, "__self__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000118 PyObject *self;
119 if (PyEval_GetRestricted()) {
120 PyErr_SetString(PyExc_RuntimeError,
Guido van Rossum10393b11995-01-10 10:39:49 +0000121 "method.__self__ not accessible in restricted mode");
122 return NULL;
123 }
124 self = m->m_self;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000125 if (self == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000126 self = Py_None;
127 Py_INCREF(self);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000128 return self;
129 }
130 if (strcmp(name, "__members__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000131 return Py_BuildValue("[sss]",
132 "__doc__", "__name__", "__self__");
Guido van Rossumcab650d1995-01-07 12:34:58 +0000133 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000134 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000135 return NULL;
136}
137
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000138static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139meth_repr(m)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000140 PyCFunctionObject *m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000141{
142 char buf[200];
143 if (m->m_self == NULL)
Guido van Rossumcab650d1995-01-07 12:34:58 +0000144 sprintf(buf, "<built-in function %.80s>", m->m_ml->ml_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145 else
Guido van Rossum3f5da241990-12-20 15:06:42 +0000146 sprintf(buf,
Guido van Rossumb3f72581993-05-21 19:56:10 +0000147 "<built-in method %.80s of %.80s object at %lx>",
Guido van Rossumcab650d1995-01-07 12:34:58 +0000148 m->m_ml->ml_name, m->m_self->ob_type->tp_name,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000149 (long)m->m_self);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000150 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151}
152
Guido van Rossum9bfef441993-03-29 10:43:31 +0000153static int
154meth_compare(a, b)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000155 PyCFunctionObject *a, *b;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000156{
157 if (a->m_self != b->m_self)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000158 return PyObject_Compare(a->m_self, b->m_self);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000159 if (a->m_ml->ml_meth == b->m_ml->ml_meth)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000160 return 0;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000161 if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000162 return -1;
163 else
164 return 1;
165}
166
167static long
168meth_hash(a)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000169 PyCFunctionObject *a;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000170{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000171 long x;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000172 if (a->m_self == NULL)
173 x = 0;
174 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000175 x = PyObject_Hash(a->m_self);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000176 if (x == -1)
177 return -1;
178 }
Guido van Rossumcab650d1995-01-07 12:34:58 +0000179 return x ^ (long) a->m_ml->ml_meth;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000180}
181
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000182PyTypeObject PyCFunction_Type = {
183 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184 0,
Guido van Rossum7066dd71992-09-17 17:54:56 +0000185 "builtin_function_or_method",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000186 sizeof(PyCFunctionObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000188 (destructor)meth_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000189 0, /*tp_print*/
Guido van Rossumcab650d1995-01-07 12:34:58 +0000190 (getattrfunc)meth_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000192 (cmpfunc)meth_compare, /*tp_compare*/
193 (reprfunc)meth_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 0, /*tp_as_number*/
195 0, /*tp_as_sequence*/
196 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000197 (hashfunc)meth_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198};
Guido van Rossum3f5da241990-12-20 15:06:42 +0000199
Guido van Rossum69785031995-01-26 22:58:48 +0000200/* List all methods in a chain -- helper for findmethodinchain */
Guido van Rossume9c430f1991-10-20 20:21:15 +0000201
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000202static PyObject *
Guido van Rossum69785031995-01-26 22:58:48 +0000203listmethodchain(chain)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204 PyMethodChain *chain;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000205{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000206 PyMethodChain *c;
207 PyMethodDef *ml;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000208 int i, n;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000209 PyObject *v;
Guido van Rossum69785031995-01-26 22:58:48 +0000210
211 n = 0;
212 for (c = chain; c != NULL; c = c->link) {
213 for (ml = c->methods; ml->ml_name != NULL; ml++)
214 n++;
215 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000216 v = PyList_New(n);
Guido van Rossum69785031995-01-26 22:58:48 +0000217 if (v == NULL)
218 return NULL;
219 i = 0;
220 for (c = chain; c != NULL; c = c->link) {
221 for (ml = c->methods; ml->ml_name != NULL; ml++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000222 PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
Guido van Rossum69785031995-01-26 22:58:48 +0000223 i++;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000224 }
225 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000226 if (PyErr_Occurred()) {
227 Py_DECREF(v);
Guido van Rossum69785031995-01-26 22:58:48 +0000228 return NULL;
229 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000230 PyList_Sort(v);
Guido van Rossume9c430f1991-10-20 20:21:15 +0000231 return v;
232}
233
Guido van Rossum69785031995-01-26 22:58:48 +0000234/* Find a method in a method chain */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000235
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000236PyObject *
237Py_FindMethodInChain(chain, self, name)
238 PyMethodChain *chain;
239 PyObject *self;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000240 char *name;
241{
Guido van Rossume9c430f1991-10-20 20:21:15 +0000242 if (strcmp(name, "__methods__") == 0)
Guido van Rossum69785031995-01-26 22:58:48 +0000243 return listmethodchain(chain);
244 while (chain != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000245 PyMethodDef *ml = chain->methods;
Guido van Rossum69785031995-01-26 22:58:48 +0000246 for (; ml->ml_name != NULL; ml++) {
247 if (name[0] == ml->ml_name[0] &&
248 strcmp(name+1, ml->ml_name+1) == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000249 return PyCFunction_New(ml, self);
Guido van Rossum69785031995-01-26 22:58:48 +0000250 }
251 chain = chain->link;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000252 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000253 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000254 return NULL;
255}
Guido van Rossum69785031995-01-26 22:58:48 +0000256
257/* Find a method in a single method list */
258
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000259PyObject *
260Py_FindMethod(methods, self, name)
261 PyMethodDef *methods;
262 PyObject *self;
Guido van Rossum69785031995-01-26 22:58:48 +0000263 char *name;
264{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000265 PyMethodChain chain;
Guido van Rossum69785031995-01-26 22:58:48 +0000266 chain.methods = methods;
267 chain.link = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000268 return Py_FindMethodInChain(&chain, self, name);
Guido van Rossum69785031995-01-26 22:58:48 +0000269}