blob: 4a1fa93f4aa4d75d40077ba146421416fda0c24c [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 *
Fred Drakeee238b92000-07-09 06:03:25 +000020PyCFunction_New(PyMethodDef *ml, PyObject *self)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000021{
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000022 PyCFunctionObject *op;
23 op = free_list;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000024 if (op != NULL) {
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000025 free_list = (PyCFunctionObject *)(op->m_self);
Guido van Rossumb18618d2000-05-03 23:44:39 +000026 PyObject_INIT(op, &PyCFunction_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000027 }
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000028 else {
29 op = PyObject_NEW(PyCFunctionObject, &PyCFunction_Type);
30 if (op == NULL)
31 return NULL;
32 }
33 op->m_ml = ml;
34 Py_XINCREF(self);
35 op->m_self = self;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000036 return (PyObject *)op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000037}
38
Guido van Rossumc0b618a1997-05-02 03:12:38 +000039PyCFunction
Fred Drakeee238b92000-07-09 06:03:25 +000040PyCFunction_GetFunction(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_ml -> ml_meth;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047}
48
Guido van Rossumc0b618a1997-05-02 03:12:38 +000049PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +000050PyCFunction_GetSelf(PyObject *op)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000051{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000052 if (!PyCFunction_Check(op)) {
53 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054 return NULL;
55 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000056 return ((PyCFunctionObject *)op) -> m_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057}
58
Guido van Rossumc0602291991-12-16 13:07:24 +000059int
Fred Drakeee238b92000-07-09 06:03:25 +000060PyCFunction_GetFlags(PyObject *op)
Guido van Rossumc0602291991-12-16 13:07:24 +000061{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000062 if (!PyCFunction_Check(op)) {
63 PyErr_BadInternalCall();
Guido van Rossumc0602291991-12-16 13:07:24 +000064 return -1;
65 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000066 return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
Guido van Rossumc0602291991-12-16 13:07:24 +000067}
68
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069/* Methods (the standard built-in methods, that is) */
70
71static void
Fred Drakeee238b92000-07-09 06:03:25 +000072meth_dealloc(PyCFunctionObject *m)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000074 Py_XDECREF(m->m_self);
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000075 m->m_self = (PyObject *)free_list;
76 free_list = m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077}
78
Guido van Rossumc0b618a1997-05-02 03:12:38 +000079static PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +000080meth_getattr(PyCFunctionObject *m, char *name)
Guido van Rossumcab650d1995-01-07 12:34:58 +000081{
82 if (strcmp(name, "__name__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000083 return PyString_FromString(m->m_ml->ml_name);
Guido van Rossumcab650d1995-01-07 12:34:58 +000084 }
85 if (strcmp(name, "__doc__") == 0) {
86 char *doc = m->m_ml->ml_doc;
87 if (doc != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +000088 return PyString_FromString(doc);
89 Py_INCREF(Py_None);
90 return Py_None;
Guido van Rossumcab650d1995-01-07 12:34:58 +000091 }
92 if (strcmp(name, "__self__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000093 PyObject *self;
94 if (PyEval_GetRestricted()) {
95 PyErr_SetString(PyExc_RuntimeError,
Guido van Rossum10393b11995-01-10 10:39:49 +000096 "method.__self__ not accessible in restricted mode");
97 return NULL;
98 }
99 self = m->m_self;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000100 if (self == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000101 self = Py_None;
102 Py_INCREF(self);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000103 return self;
104 }
105 if (strcmp(name, "__members__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000106 return Py_BuildValue("[sss]",
107 "__doc__", "__name__", "__self__");
Guido van Rossumcab650d1995-01-07 12:34:58 +0000108 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000110 return NULL;
111}
112
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000113static PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000114meth_repr(PyCFunctionObject *m)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115{
116 char buf[200];
117 if (m->m_self == NULL)
Guido van Rossumcab650d1995-01-07 12:34:58 +0000118 sprintf(buf, "<built-in function %.80s>", m->m_ml->ml_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119 else
Guido van Rossum3f5da241990-12-20 15:06:42 +0000120 sprintf(buf,
Fred Drakea44d3532000-06-30 15:01:00 +0000121 "<built-in method %.80s of %.80s object at %p>",
Guido van Rossumcab650d1995-01-07 12:34:58 +0000122 m->m_ml->ml_name, m->m_self->ob_type->tp_name,
Fred Drakea44d3532000-06-30 15:01:00 +0000123 m->m_self);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000124 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125}
126
Guido van Rossum9bfef441993-03-29 10:43:31 +0000127static int
Fred Drakeee238b92000-07-09 06:03:25 +0000128meth_compare(PyCFunctionObject *a, PyCFunctionObject *b)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000129{
130 if (a->m_self != b->m_self)
Guido van Rossum13fdf5e1998-12-04 18:52:55 +0000131 return (a->m_self < b->m_self) ? -1 : 1;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000132 if (a->m_ml->ml_meth == b->m_ml->ml_meth)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000133 return 0;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000134 if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000135 return -1;
136 else
137 return 1;
138}
139
140static long
Fred Drakeee238b92000-07-09 06:03:25 +0000141meth_hash(PyCFunctionObject *a)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000142{
Fred Drake13634cf2000-06-29 19:17:04 +0000143 long x,y;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000144 if (a->m_self == NULL)
145 x = 0;
146 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000147 x = PyObject_Hash(a->m_self);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000148 if (x == -1)
149 return -1;
150 }
Guido van Rossum9a15c212000-06-30 22:46:04 +0000151 y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
Fred Drake13634cf2000-06-29 19:17:04 +0000152 if (y == -1)
153 return -1;
154 x ^= y;
155 if (x == -1)
156 x = -2;
157 return x;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000158}
159
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000160PyTypeObject PyCFunction_Type = {
161 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162 0,
Guido van Rossum7066dd71992-09-17 17:54:56 +0000163 "builtin_function_or_method",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000164 sizeof(PyCFunctionObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000166 (destructor)meth_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000167 0, /*tp_print*/
Guido van Rossumcab650d1995-01-07 12:34:58 +0000168 (getattrfunc)meth_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000169 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000170 (cmpfunc)meth_compare, /*tp_compare*/
171 (reprfunc)meth_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 0, /*tp_as_number*/
173 0, /*tp_as_sequence*/
174 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000175 (hashfunc)meth_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176};
Guido van Rossum3f5da241990-12-20 15:06:42 +0000177
Guido van Rossum69785031995-01-26 22:58:48 +0000178/* List all methods in a chain -- helper for findmethodinchain */
Guido van Rossume9c430f1991-10-20 20:21:15 +0000179
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000180static PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000181listmethodchain(PyMethodChain *chain)
Guido van Rossume9c430f1991-10-20 20:21:15 +0000182{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000183 PyMethodChain *c;
184 PyMethodDef *ml;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000185 int i, n;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000186 PyObject *v;
Guido van Rossum69785031995-01-26 22:58:48 +0000187
188 n = 0;
189 for (c = chain; c != NULL; c = c->link) {
190 for (ml = c->methods; ml->ml_name != NULL; ml++)
191 n++;
192 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000193 v = PyList_New(n);
Guido van Rossum69785031995-01-26 22:58:48 +0000194 if (v == NULL)
195 return NULL;
196 i = 0;
197 for (c = chain; c != NULL; c = c->link) {
198 for (ml = c->methods; ml->ml_name != NULL; ml++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000199 PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
Guido van Rossum69785031995-01-26 22:58:48 +0000200 i++;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000201 }
202 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000203 if (PyErr_Occurred()) {
204 Py_DECREF(v);
Guido van Rossum69785031995-01-26 22:58:48 +0000205 return NULL;
206 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000207 PyList_Sort(v);
Guido van Rossume9c430f1991-10-20 20:21:15 +0000208 return v;
209}
210
Guido van Rossum69785031995-01-26 22:58:48 +0000211/* Find a method in a method chain */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000212
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000213PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000214Py_FindMethodInChain(PyMethodChain *chain, PyObject *self, char *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000215{
Guido van Rossum8a92c621998-06-27 18:28:59 +0000216 if (name[0] == '_' && name[1] == '_') {
217 if (strcmp(name, "__methods__") == 0)
218 return listmethodchain(chain);
219 if (strcmp(name, "__doc__") == 0) {
220 char *doc = self->ob_type->tp_doc;
221 if (doc != NULL)
222 return PyString_FromString(doc);
223 }
224 }
Guido van Rossum69785031995-01-26 22:58:48 +0000225 while (chain != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000226 PyMethodDef *ml = chain->methods;
Guido van Rossum69785031995-01-26 22:58:48 +0000227 for (; ml->ml_name != NULL; ml++) {
228 if (name[0] == ml->ml_name[0] &&
229 strcmp(name+1, ml->ml_name+1) == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000230 return PyCFunction_New(ml, self);
Guido van Rossum69785031995-01-26 22:58:48 +0000231 }
232 chain = chain->link;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000233 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000234 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000235 return NULL;
236}
Guido van Rossum69785031995-01-26 22:58:48 +0000237
238/* Find a method in a single method list */
239
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240PyObject *
Fred Drakeee238b92000-07-09 06:03:25 +0000241Py_FindMethod(PyMethodDef *methods, PyObject *self, char *name)
Guido van Rossum69785031995-01-26 22:58:48 +0000242{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000243 PyMethodChain chain;
Guido van Rossum69785031995-01-26 22:58:48 +0000244 chain.methods = methods;
245 chain.link = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000246 return Py_FindMethodInChain(&chain, self, name);
Guido van Rossum69785031995-01-26 22:58:48 +0000247}
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000248
249/* Clear out the free list */
250
251void
Fred Drakeee238b92000-07-09 06:03:25 +0000252PyCFunction_Fini(void)
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000253{
254 while (free_list) {
255 PyCFunctionObject *v = free_list;
256 free_list = (PyCFunctionObject *)(v->m_self);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000257 PyObject_DEL(v);
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000258 }
259}