blob: f0bbeeacc990f1c47e8c73e7fb9530a2c4b62f8e [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 Rossum85a5fbb1990-10-14 12:07:46 +00006#include "token.h"
7
Guido van Rossum1f39c5c1997-08-05 02:11:41 +00008static PyCFunctionObject *free_list = NULL;
9
Guido van Rossumc0b618a1997-05-02 03:12:38 +000010PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +000011PyCFunction_New(PyMethodDef *ml, PyObject *self)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012{
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000013 PyCFunctionObject *op;
14 op = free_list;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000015 if (op != NULL) {
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000016 free_list = (PyCFunctionObject *)(op->m_self);
Guido van Rossumb18618d2000-05-03 23:44:39 +000017 PyObject_INIT(op, &PyCFunction_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000018 }
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000019 else {
20 op = PyObject_NEW(PyCFunctionObject, &PyCFunction_Type);
21 if (op == NULL)
22 return NULL;
23 }
24 op->m_ml = ml;
25 Py_XINCREF(self);
26 op->m_self = self;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000027 return (PyObject *)op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028}
29
Guido van Rossumc0b618a1997-05-02 03:12:38 +000030PyCFunction
Fred Drakeee238b92000-07-09 06:03:25 +000031PyCFunction_GetFunction(PyObject *op)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000033 if (!PyCFunction_Check(op)) {
34 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000035 return NULL;
36 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000037 return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000038}
39
Guido van Rossumc0b618a1997-05-02 03:12:38 +000040PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +000041PyCFunction_GetSelf(PyObject *op)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000042{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000043 if (!PyCFunction_Check(op)) {
44 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000045 return NULL;
46 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000047 return ((PyCFunctionObject *)op) -> m_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000048}
49
Guido van Rossumc0602291991-12-16 13:07:24 +000050int
Fred Drakeee238b92000-07-09 06:03:25 +000051PyCFunction_GetFlags(PyObject *op)
Guido van Rossumc0602291991-12-16 13:07:24 +000052{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000053 if (!PyCFunction_Check(op)) {
54 PyErr_BadInternalCall();
Guido van Rossumc0602291991-12-16 13:07:24 +000055 return -1;
56 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000057 return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
Guido van Rossumc0602291991-12-16 13:07:24 +000058}
59
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060/* Methods (the standard built-in methods, that is) */
61
62static void
Fred Drakeee238b92000-07-09 06:03:25 +000063meth_dealloc(PyCFunctionObject *m)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000064{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000065 Py_XDECREF(m->m_self);
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000066 m->m_self = (PyObject *)free_list;
67 free_list = m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000068}
69
Guido van Rossumc0b618a1997-05-02 03:12:38 +000070static PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +000071meth_getattr(PyCFunctionObject *m, char *name)
Guido van Rossumcab650d1995-01-07 12:34:58 +000072{
73 if (strcmp(name, "__name__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000074 return PyString_FromString(m->m_ml->ml_name);
Guido van Rossumcab650d1995-01-07 12:34:58 +000075 }
76 if (strcmp(name, "__doc__") == 0) {
77 char *doc = m->m_ml->ml_doc;
78 if (doc != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +000079 return PyString_FromString(doc);
80 Py_INCREF(Py_None);
81 return Py_None;
Guido van Rossumcab650d1995-01-07 12:34:58 +000082 }
83 if (strcmp(name, "__self__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000084 PyObject *self;
85 if (PyEval_GetRestricted()) {
86 PyErr_SetString(PyExc_RuntimeError,
Guido van Rossum10393b11995-01-10 10:39:49 +000087 "method.__self__ not accessible in restricted mode");
88 return NULL;
89 }
90 self = m->m_self;
Guido van Rossumcab650d1995-01-07 12:34:58 +000091 if (self == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +000092 self = Py_None;
93 Py_INCREF(self);
Guido van Rossumcab650d1995-01-07 12:34:58 +000094 return self;
95 }
96 if (strcmp(name, "__members__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000097 return Py_BuildValue("[sss]",
98 "__doc__", "__name__", "__self__");
Guido van Rossumcab650d1995-01-07 12:34:58 +000099 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000100 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000101 return NULL;
102}
103
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000104static PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000105meth_repr(PyCFunctionObject *m)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106{
107 char buf[200];
108 if (m->m_self == NULL)
Guido van Rossumcab650d1995-01-07 12:34:58 +0000109 sprintf(buf, "<built-in function %.80s>", m->m_ml->ml_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 else
Guido van Rossum3f5da241990-12-20 15:06:42 +0000111 sprintf(buf,
Fred Drakea44d3532000-06-30 15:01:00 +0000112 "<built-in method %.80s of %.80s object at %p>",
Guido van Rossumcab650d1995-01-07 12:34:58 +0000113 m->m_ml->ml_name, m->m_self->ob_type->tp_name,
Fred Drakea44d3532000-06-30 15:01:00 +0000114 m->m_self);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000115 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116}
117
Guido van Rossum9bfef441993-03-29 10:43:31 +0000118static int
Fred Drakeee238b92000-07-09 06:03:25 +0000119meth_compare(PyCFunctionObject *a, PyCFunctionObject *b)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000120{
121 if (a->m_self != b->m_self)
Guido van Rossum13fdf5e1998-12-04 18:52:55 +0000122 return (a->m_self < b->m_self) ? -1 : 1;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000123 if (a->m_ml->ml_meth == b->m_ml->ml_meth)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000124 return 0;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000125 if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000126 return -1;
127 else
128 return 1;
129}
130
131static long
Fred Drakeee238b92000-07-09 06:03:25 +0000132meth_hash(PyCFunctionObject *a)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000133{
Fred Drake13634cf2000-06-29 19:17:04 +0000134 long x,y;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000135 if (a->m_self == NULL)
136 x = 0;
137 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000138 x = PyObject_Hash(a->m_self);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000139 if (x == -1)
140 return -1;
141 }
Guido van Rossum9a15c212000-06-30 22:46:04 +0000142 y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
Fred Drake13634cf2000-06-29 19:17:04 +0000143 if (y == -1)
144 return -1;
145 x ^= y;
146 if (x == -1)
147 x = -2;
148 return x;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000149}
150
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000151PyTypeObject PyCFunction_Type = {
152 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153 0,
Guido van Rossum7066dd71992-09-17 17:54:56 +0000154 "builtin_function_or_method",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000155 sizeof(PyCFunctionObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000157 (destructor)meth_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000158 0, /*tp_print*/
Guido van Rossumcab650d1995-01-07 12:34:58 +0000159 (getattrfunc)meth_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000161 (cmpfunc)meth_compare, /*tp_compare*/
162 (reprfunc)meth_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163 0, /*tp_as_number*/
164 0, /*tp_as_sequence*/
165 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000166 (hashfunc)meth_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000167};
Guido van Rossum3f5da241990-12-20 15:06:42 +0000168
Guido van Rossum69785031995-01-26 22:58:48 +0000169/* List all methods in a chain -- helper for findmethodinchain */
Guido van Rossume9c430f1991-10-20 20:21:15 +0000170
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000171static PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000172listmethodchain(PyMethodChain *chain)
Guido van Rossume9c430f1991-10-20 20:21:15 +0000173{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000174 PyMethodChain *c;
175 PyMethodDef *ml;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000176 int i, n;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000177 PyObject *v;
Guido van Rossum69785031995-01-26 22:58:48 +0000178
179 n = 0;
180 for (c = chain; c != NULL; c = c->link) {
181 for (ml = c->methods; ml->ml_name != NULL; ml++)
182 n++;
183 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000184 v = PyList_New(n);
Guido van Rossum69785031995-01-26 22:58:48 +0000185 if (v == NULL)
186 return NULL;
187 i = 0;
188 for (c = chain; c != NULL; c = c->link) {
189 for (ml = c->methods; ml->ml_name != NULL; ml++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000190 PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
Guido van Rossum69785031995-01-26 22:58:48 +0000191 i++;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000192 }
193 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000194 if (PyErr_Occurred()) {
195 Py_DECREF(v);
Guido van Rossum69785031995-01-26 22:58:48 +0000196 return NULL;
197 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000198 PyList_Sort(v);
Guido van Rossume9c430f1991-10-20 20:21:15 +0000199 return v;
200}
201
Guido van Rossum69785031995-01-26 22:58:48 +0000202/* Find a method in a method chain */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000203
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000205Py_FindMethodInChain(PyMethodChain *chain, PyObject *self, char *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000206{
Guido van Rossum8a92c621998-06-27 18:28:59 +0000207 if (name[0] == '_' && name[1] == '_') {
208 if (strcmp(name, "__methods__") == 0)
209 return listmethodchain(chain);
210 if (strcmp(name, "__doc__") == 0) {
211 char *doc = self->ob_type->tp_doc;
212 if (doc != NULL)
213 return PyString_FromString(doc);
214 }
215 }
Guido van Rossum69785031995-01-26 22:58:48 +0000216 while (chain != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000217 PyMethodDef *ml = chain->methods;
Guido van Rossum69785031995-01-26 22:58:48 +0000218 for (; ml->ml_name != NULL; ml++) {
219 if (name[0] == ml->ml_name[0] &&
220 strcmp(name+1, ml->ml_name+1) == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221 return PyCFunction_New(ml, self);
Guido van Rossum69785031995-01-26 22:58:48 +0000222 }
223 chain = chain->link;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000224 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000225 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000226 return NULL;
227}
Guido van Rossum69785031995-01-26 22:58:48 +0000228
229/* Find a method in a single method list */
230
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000232Py_FindMethod(PyMethodDef *methods, PyObject *self, char *name)
Guido van Rossum69785031995-01-26 22:58:48 +0000233{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000234 PyMethodChain chain;
Guido van Rossum69785031995-01-26 22:58:48 +0000235 chain.methods = methods;
236 chain.link = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 return Py_FindMethodInChain(&chain, self, name);
Guido van Rossum69785031995-01-26 22:58:48 +0000238}
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000239
240/* Clear out the free list */
241
242void
Fred Drakeee238b92000-07-09 06:03:25 +0000243PyCFunction_Fini(void)
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000244{
245 while (free_list) {
246 PyCFunctionObject *v = free_list;
247 free_list = (PyCFunctionObject *)(v->m_self);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000248 PyObject_DEL(v);
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000249 }
250}