blob: 4874c285043cda6e75a9e9c25e65de25607f33e1 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009******************************************************************/
10
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011/* Method object implementation */
12
Guido van Rossumc0b618a1997-05-02 03:12:38 +000013#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000015#include "token.h"
16
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000017static PyCFunctionObject *free_list = NULL;
18
Guido van Rossumc0b618a1997-05-02 03:12:38 +000019PyObject *
20PyCFunction_New(ml, self)
21 PyMethodDef *ml;
22 PyObject *self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000023{
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000024 PyCFunctionObject *op;
25 op = free_list;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000026 if (op != NULL) {
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000027 free_list = (PyCFunctionObject *)(op->m_self);
Guido van Rossumb18618d2000-05-03 23:44:39 +000028 PyObject_INIT(op, &PyCFunction_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000029 }
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000030 else {
31 op = PyObject_NEW(PyCFunctionObject, &PyCFunction_Type);
32 if (op == NULL)
33 return NULL;
34 }
35 op->m_ml = ml;
36 Py_XINCREF(self);
37 op->m_self = self;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000038 return (PyObject *)op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039}
40
Guido van Rossumc0b618a1997-05-02 03:12:38 +000041PyCFunction
42PyCFunction_GetFunction(op)
43 PyObject *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000045 if (!PyCFunction_Check(op)) {
46 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047 return NULL;
48 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000049 return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050}
51
Guido van Rossumc0b618a1997-05-02 03:12:38 +000052PyObject *
53PyCFunction_GetSelf(op)
54 PyObject *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000055{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000056 if (!PyCFunction_Check(op)) {
57 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000058 return NULL;
59 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000060 return ((PyCFunctionObject *)op) -> m_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061}
62
Guido van Rossumc0602291991-12-16 13:07:24 +000063int
Guido van Rossumc0b618a1997-05-02 03:12:38 +000064PyCFunction_GetFlags(op)
65 PyObject *op;
Guido van Rossumc0602291991-12-16 13:07:24 +000066{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000067 if (!PyCFunction_Check(op)) {
68 PyErr_BadInternalCall();
Guido van Rossumc0602291991-12-16 13:07:24 +000069 return -1;
70 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000071 return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
Guido van Rossumc0602291991-12-16 13:07:24 +000072}
73
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074/* Methods (the standard built-in methods, that is) */
75
76static void
77meth_dealloc(m)
Guido van Rossumc0b618a1997-05-02 03:12:38 +000078 PyCFunctionObject *m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000080 Py_XDECREF(m->m_self);
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000081 m->m_self = (PyObject *)free_list;
82 free_list = m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083}
84
Guido van Rossumc0b618a1997-05-02 03:12:38 +000085static PyObject *
Guido van Rossumcab650d1995-01-07 12:34:58 +000086meth_getattr(m, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +000087 PyCFunctionObject *m;
Guido van Rossumcab650d1995-01-07 12:34:58 +000088 char *name;
89{
90 if (strcmp(name, "__name__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091 return PyString_FromString(m->m_ml->ml_name);
Guido van Rossumcab650d1995-01-07 12:34:58 +000092 }
93 if (strcmp(name, "__doc__") == 0) {
94 char *doc = m->m_ml->ml_doc;
95 if (doc != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +000096 return PyString_FromString(doc);
97 Py_INCREF(Py_None);
98 return Py_None;
Guido van Rossumcab650d1995-01-07 12:34:58 +000099 }
100 if (strcmp(name, "__self__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000101 PyObject *self;
102 if (PyEval_GetRestricted()) {
103 PyErr_SetString(PyExc_RuntimeError,
Guido van Rossum10393b11995-01-10 10:39:49 +0000104 "method.__self__ not accessible in restricted mode");
105 return NULL;
106 }
107 self = m->m_self;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000108 if (self == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109 self = Py_None;
110 Py_INCREF(self);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000111 return self;
112 }
113 if (strcmp(name, "__members__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000114 return Py_BuildValue("[sss]",
115 "__doc__", "__name__", "__self__");
Guido van Rossumcab650d1995-01-07 12:34:58 +0000116 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000117 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000118 return NULL;
119}
120
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000121static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000122meth_repr(m)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000123 PyCFunctionObject *m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124{
125 char buf[200];
126 if (m->m_self == NULL)
Guido van Rossumcab650d1995-01-07 12:34:58 +0000127 sprintf(buf, "<built-in function %.80s>", m->m_ml->ml_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000128 else
Guido van Rossum3f5da241990-12-20 15:06:42 +0000129 sprintf(buf,
Fred Drakea44d3532000-06-30 15:01:00 +0000130 "<built-in method %.80s of %.80s object at %p>",
Guido van Rossumcab650d1995-01-07 12:34:58 +0000131 m->m_ml->ml_name, m->m_self->ob_type->tp_name,
Fred Drakea44d3532000-06-30 15:01:00 +0000132 m->m_self);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000133 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134}
135
Guido van Rossum9bfef441993-03-29 10:43:31 +0000136static int
137meth_compare(a, b)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000138 PyCFunctionObject *a, *b;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000139{
140 if (a->m_self != b->m_self)
Guido van Rossum13fdf5e1998-12-04 18:52:55 +0000141 return (a->m_self < b->m_self) ? -1 : 1;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000142 if (a->m_ml->ml_meth == b->m_ml->ml_meth)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000143 return 0;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000144 if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000145 return -1;
146 else
147 return 1;
148}
149
150static long
151meth_hash(a)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000152 PyCFunctionObject *a;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000153{
Fred Drake13634cf2000-06-29 19:17:04 +0000154 long x,y;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000155 if (a->m_self == NULL)
156 x = 0;
157 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000158 x = PyObject_Hash(a->m_self);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000159 if (x == -1)
160 return -1;
161 }
Guido van Rossum9a15c212000-06-30 22:46:04 +0000162 y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
Fred Drake13634cf2000-06-29 19:17:04 +0000163 if (y == -1)
164 return -1;
165 x ^= y;
166 if (x == -1)
167 x = -2;
168 return x;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000169}
170
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000171PyTypeObject PyCFunction_Type = {
172 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173 0,
Guido van Rossum7066dd71992-09-17 17:54:56 +0000174 "builtin_function_or_method",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000175 sizeof(PyCFunctionObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000177 (destructor)meth_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000178 0, /*tp_print*/
Guido van Rossumcab650d1995-01-07 12:34:58 +0000179 (getattrfunc)meth_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000181 (cmpfunc)meth_compare, /*tp_compare*/
182 (reprfunc)meth_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183 0, /*tp_as_number*/
184 0, /*tp_as_sequence*/
185 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000186 (hashfunc)meth_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187};
Guido van Rossum3f5da241990-12-20 15:06:42 +0000188
Guido van Rossum69785031995-01-26 22:58:48 +0000189/* List all methods in a chain -- helper for findmethodinchain */
Guido van Rossume9c430f1991-10-20 20:21:15 +0000190
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000191static PyObject *
Guido van Rossum69785031995-01-26 22:58:48 +0000192listmethodchain(chain)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000193 PyMethodChain *chain;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000194{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000195 PyMethodChain *c;
196 PyMethodDef *ml;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000197 int i, n;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000198 PyObject *v;
Guido van Rossum69785031995-01-26 22:58:48 +0000199
200 n = 0;
201 for (c = chain; c != NULL; c = c->link) {
202 for (ml = c->methods; ml->ml_name != NULL; ml++)
203 n++;
204 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000205 v = PyList_New(n);
Guido van Rossum69785031995-01-26 22:58:48 +0000206 if (v == NULL)
207 return NULL;
208 i = 0;
209 for (c = chain; c != NULL; c = c->link) {
210 for (ml = c->methods; ml->ml_name != NULL; ml++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000211 PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
Guido van Rossum69785031995-01-26 22:58:48 +0000212 i++;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000213 }
214 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000215 if (PyErr_Occurred()) {
216 Py_DECREF(v);
Guido van Rossum69785031995-01-26 22:58:48 +0000217 return NULL;
218 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000219 PyList_Sort(v);
Guido van Rossume9c430f1991-10-20 20:21:15 +0000220 return v;
221}
222
Guido van Rossum69785031995-01-26 22:58:48 +0000223/* Find a method in a method chain */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000224
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000225PyObject *
226Py_FindMethodInChain(chain, self, name)
227 PyMethodChain *chain;
228 PyObject *self;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000229 char *name;
230{
Guido van Rossum8a92c621998-06-27 18:28:59 +0000231 if (name[0] == '_' && name[1] == '_') {
232 if (strcmp(name, "__methods__") == 0)
233 return listmethodchain(chain);
234 if (strcmp(name, "__doc__") == 0) {
235 char *doc = self->ob_type->tp_doc;
236 if (doc != NULL)
237 return PyString_FromString(doc);
238 }
239 }
Guido van Rossum69785031995-01-26 22:58:48 +0000240 while (chain != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000241 PyMethodDef *ml = chain->methods;
Guido van Rossum69785031995-01-26 22:58:48 +0000242 for (; ml->ml_name != NULL; ml++) {
243 if (name[0] == ml->ml_name[0] &&
244 strcmp(name+1, ml->ml_name+1) == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000245 return PyCFunction_New(ml, self);
Guido van Rossum69785031995-01-26 22:58:48 +0000246 }
247 chain = chain->link;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000248 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000249 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000250 return NULL;
251}
Guido van Rossum69785031995-01-26 22:58:48 +0000252
253/* Find a method in a single method list */
254
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000255PyObject *
256Py_FindMethod(methods, self, name)
257 PyMethodDef *methods;
258 PyObject *self;
Guido van Rossum69785031995-01-26 22:58:48 +0000259 char *name;
260{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000261 PyMethodChain chain;
Guido van Rossum69785031995-01-26 22:58:48 +0000262 chain.methods = methods;
263 chain.link = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000264 return Py_FindMethodInChain(&chain, self, name);
Guido van Rossum69785031995-01-26 22:58:48 +0000265}
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000266
267/* Clear out the free list */
268
269void
270PyCFunction_Fini()
271{
272 while (free_list) {
273 PyCFunctionObject *v = free_list;
274 free_list = (PyCFunctionObject *)(v->m_self);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000275 PyObject_DEL(v);
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000276 }
277}