Line data Source code
1 :
2 : /* Method object implementation */
3 :
4 : #include "Python.h"
5 : #include "structmember.h"
6 :
7 : /* Free list for method objects to safe malloc/free overhead
8 : * The m_self element is used to chain the objects.
9 : */
10 : static PyCFunctionObject *free_list = NULL;
11 : static int numfree = 0;
12 : #ifndef PyCFunction_MAXFREELIST
13 : #define PyCFunction_MAXFREELIST 256
14 : #endif
15 :
16 : PyObject *
17 29978 : PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
18 : {
19 : PyCFunctionObject *op;
20 29978 : op = free_list;
21 29978 : if (op != NULL) {
22 29357 : free_list = (PyCFunctionObject *)(op->m_self);
23 29357 : PyObject_INIT(op, &PyCFunction_Type);
24 29357 : numfree--;
25 : }
26 : else {
27 621 : op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
28 621 : if (op == NULL)
29 0 : return NULL;
30 : }
31 29978 : op->m_ml = ml;
32 29978 : Py_XINCREF(self);
33 29978 : op->m_self = self;
34 29978 : Py_XINCREF(module);
35 29978 : op->m_module = module;
36 29978 : _PyObject_GC_TRACK(op);
37 29978 : return (PyObject *)op;
38 : }
39 :
40 : PyCFunction
41 0 : PyCFunction_GetFunction(PyObject *op)
42 : {
43 0 : if (!PyCFunction_Check(op)) {
44 0 : PyErr_BadInternalCall();
45 0 : return NULL;
46 : }
47 0 : return PyCFunction_GET_FUNCTION(op);
48 : }
49 :
50 : PyObject *
51 0 : PyCFunction_GetSelf(PyObject *op)
52 : {
53 0 : if (!PyCFunction_Check(op)) {
54 0 : PyErr_BadInternalCall();
55 0 : return NULL;
56 : }
57 0 : return PyCFunction_GET_SELF(op);
58 : }
59 :
60 : int
61 0 : PyCFunction_GetFlags(PyObject *op)
62 : {
63 0 : if (!PyCFunction_Check(op)) {
64 0 : PyErr_BadInternalCall();
65 0 : return -1;
66 : }
67 0 : return PyCFunction_GET_FLAGS(op);
68 : }
69 :
70 : PyObject *
71 30044 : PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
72 : {
73 30044 : PyCFunctionObject* f = (PyCFunctionObject*)func;
74 30044 : PyCFunction meth = PyCFunction_GET_FUNCTION(func);
75 30044 : PyObject *self = PyCFunction_GET_SELF(func);
76 : Py_ssize_t size;
77 :
78 30044 : switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
79 : case METH_VARARGS:
80 19137 : if (kw == NULL || PyDict_Size(kw) == 0)
81 19137 : return (*meth)(self, arg);
82 0 : break;
83 : case METH_VARARGS | METH_KEYWORDS:
84 5363 : return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
85 : case METH_NOARGS:
86 2159 : if (kw == NULL || PyDict_Size(kw) == 0) {
87 2159 : size = PyTuple_GET_SIZE(arg);
88 2159 : if (size == 0)
89 2159 : return (*meth)(self, NULL);
90 0 : PyErr_Format(PyExc_TypeError,
91 : "%.200s() takes no arguments (%zd given)",
92 0 : f->m_ml->ml_name, size);
93 0 : return NULL;
94 : }
95 0 : break;
96 : case METH_O:
97 3385 : if (kw == NULL || PyDict_Size(kw) == 0) {
98 3385 : size = PyTuple_GET_SIZE(arg);
99 3385 : if (size == 1)
100 3385 : return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
101 0 : PyErr_Format(PyExc_TypeError,
102 : "%.200s() takes exactly one argument (%zd given)",
103 0 : f->m_ml->ml_name, size);
104 0 : return NULL;
105 : }
106 0 : break;
107 : default:
108 0 : PyErr_SetString(PyExc_SystemError, "Bad call flags in "
109 : "PyCFunction_Call. METH_OLDARGS is no "
110 : "longer supported!");
111 :
112 0 : return NULL;
113 : }
114 0 : PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
115 0 : f->m_ml->ml_name);
116 0 : return NULL;
117 : }
118 :
119 : /* Methods (the standard built-in methods, that is) */
120 :
121 : static void
122 29366 : meth_dealloc(PyCFunctionObject *m)
123 : {
124 29366 : _PyObject_GC_UNTRACK(m);
125 29366 : Py_XDECREF(m->m_self);
126 29366 : Py_XDECREF(m->m_module);
127 29366 : if (numfree < PyCFunction_MAXFREELIST) {
128 29366 : m->m_self = (PyObject *)free_list;
129 29366 : free_list = m;
130 29366 : numfree++;
131 : }
132 : else {
133 0 : PyObject_GC_Del(m);
134 : }
135 29366 : }
136 :
137 : static PyObject *
138 1 : meth_get__doc__(PyCFunctionObject *m, void *closure)
139 : {
140 1 : const char *doc = m->m_ml->ml_doc;
141 :
142 1 : if (doc != NULL)
143 1 : return PyUnicode_FromString(doc);
144 0 : Py_INCREF(Py_None);
145 0 : return Py_None;
146 : }
147 :
148 : static PyObject *
149 1 : meth_get__name__(PyCFunctionObject *m, void *closure)
150 : {
151 1 : return PyUnicode_FromString(m->m_ml->ml_name);
152 : }
153 :
154 : static PyObject *
155 1 : meth_get__qualname__(PyCFunctionObject *m, void *closure)
156 : {
157 : /* If __self__ is a module or NULL, return m.__name__
158 : (e.g. len.__qualname__ == 'len')
159 :
160 : If __self__ is a type, return m.__self__.__qualname__ + '.' + m.__name__
161 : (e.g. dict.fromkeys.__qualname__ == 'dict.fromkeys')
162 :
163 : Otherwise return type(m.__self__).__qualname__ + '.' + m.__name__
164 : (e.g. [].append.__qualname__ == 'list.append') */
165 : PyObject *type, *type_qualname, *res;
166 : _Py_IDENTIFIER(__qualname__);
167 :
168 1 : if (m->m_self == NULL || PyModule_Check(m->m_self))
169 1 : return PyUnicode_FromString(m->m_ml->ml_name);
170 :
171 0 : type = PyType_Check(m->m_self) ? m->m_self : (PyObject*)Py_TYPE(m->m_self);
172 :
173 0 : type_qualname = _PyObject_GetAttrId(type, &PyId___qualname__);
174 0 : if (type_qualname == NULL)
175 0 : return NULL;
176 :
177 0 : if (!PyUnicode_Check(type_qualname)) {
178 0 : PyErr_SetString(PyExc_TypeError, "<method>.__class__."
179 : "__qualname__ is not a unicode object");
180 0 : Py_XDECREF(type_qualname);
181 0 : return NULL;
182 : }
183 :
184 0 : res = PyUnicode_FromFormat("%S.%s", type_qualname, m->m_ml->ml_name);
185 0 : Py_DECREF(type_qualname);
186 0 : return res;
187 : }
188 :
189 : static int
190 2334 : meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
191 : {
192 2334 : Py_VISIT(m->m_self);
193 2334 : Py_VISIT(m->m_module);
194 2334 : return 0;
195 : }
196 :
197 : static PyObject *
198 0 : meth_get__self__(PyCFunctionObject *m, void *closure)
199 : {
200 : PyObject *self;
201 :
202 0 : self = PyCFunction_GET_SELF(m);
203 0 : if (self == NULL)
204 0 : self = Py_None;
205 0 : Py_INCREF(self);
206 0 : return self;
207 : }
208 :
209 : static PyGetSetDef meth_getsets [] = {
210 : {"__doc__", (getter)meth_get__doc__, NULL, NULL},
211 : {"__name__", (getter)meth_get__name__, NULL, NULL},
212 : {"__qualname__", (getter)meth_get__qualname__, NULL, NULL},
213 : {"__self__", (getter)meth_get__self__, NULL, NULL},
214 : {0}
215 : };
216 :
217 : #define OFF(x) offsetof(PyCFunctionObject, x)
218 :
219 : static PyMemberDef meth_members[] = {
220 : {"__module__", T_OBJECT, OFF(m_module), PY_WRITE_RESTRICTED},
221 : {NULL}
222 : };
223 :
224 : static PyObject *
225 0 : meth_repr(PyCFunctionObject *m)
226 : {
227 0 : if (m->m_self == NULL || PyModule_Check(m->m_self))
228 0 : return PyUnicode_FromFormat("<built-in function %s>",
229 0 : m->m_ml->ml_name);
230 0 : return PyUnicode_FromFormat("<built-in method %s of %s object at %p>",
231 0 : m->m_ml->ml_name,
232 0 : m->m_self->ob_type->tp_name,
233 : m->m_self);
234 : }
235 :
236 : static PyObject *
237 0 : meth_richcompare(PyObject *self, PyObject *other, int op)
238 : {
239 : PyCFunctionObject *a, *b;
240 : PyObject *res;
241 : int eq;
242 :
243 0 : if ((op != Py_EQ && op != Py_NE) ||
244 0 : !PyCFunction_Check(self) ||
245 0 : !PyCFunction_Check(other))
246 : {
247 0 : Py_RETURN_NOTIMPLEMENTED;
248 : }
249 0 : a = (PyCFunctionObject *)self;
250 0 : b = (PyCFunctionObject *)other;
251 0 : eq = a->m_self == b->m_self;
252 0 : if (eq)
253 0 : eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
254 0 : if (op == Py_EQ)
255 0 : res = eq ? Py_True : Py_False;
256 : else
257 0 : res = eq ? Py_False : Py_True;
258 0 : Py_INCREF(res);
259 0 : return res;
260 : }
261 :
262 : static Py_hash_t
263 39 : meth_hash(PyCFunctionObject *a)
264 : {
265 : Py_hash_t x, y;
266 39 : if (a->m_self == NULL)
267 0 : x = 0;
268 : else {
269 39 : x = PyObject_Hash(a->m_self);
270 39 : if (x == -1)
271 0 : return -1;
272 : }
273 39 : y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
274 39 : if (y == -1)
275 0 : return -1;
276 39 : x ^= y;
277 39 : if (x == -1)
278 0 : x = -2;
279 39 : return x;
280 : }
281 :
282 :
283 : PyTypeObject PyCFunction_Type = {
284 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
285 : "builtin_function_or_method",
286 : sizeof(PyCFunctionObject),
287 : 0,
288 : (destructor)meth_dealloc, /* tp_dealloc */
289 : 0, /* tp_print */
290 : 0, /* tp_getattr */
291 : 0, /* tp_setattr */
292 : 0, /* tp_reserved */
293 : (reprfunc)meth_repr, /* tp_repr */
294 : 0, /* tp_as_number */
295 : 0, /* tp_as_sequence */
296 : 0, /* tp_as_mapping */
297 : (hashfunc)meth_hash, /* tp_hash */
298 : PyCFunction_Call, /* tp_call */
299 : 0, /* tp_str */
300 : PyObject_GenericGetAttr, /* tp_getattro */
301 : 0, /* tp_setattro */
302 : 0, /* tp_as_buffer */
303 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
304 : 0, /* tp_doc */
305 : (traverseproc)meth_traverse, /* tp_traverse */
306 : 0, /* tp_clear */
307 : meth_richcompare, /* tp_richcompare */
308 : 0, /* tp_weaklistoffset */
309 : 0, /* tp_iter */
310 : 0, /* tp_iternext */
311 : 0, /* tp_methods */
312 : meth_members, /* tp_members */
313 : meth_getsets, /* tp_getset */
314 : 0, /* tp_base */
315 : 0, /* tp_dict */
316 : };
317 :
318 : /* Clear out the free list */
319 :
320 : int
321 0 : PyCFunction_ClearFreeList(void)
322 : {
323 0 : int freelist_size = numfree;
324 :
325 0 : while (free_list) {
326 0 : PyCFunctionObject *v = free_list;
327 0 : free_list = (PyCFunctionObject *)(v->m_self);
328 0 : PyObject_GC_Del(v);
329 0 : numfree--;
330 : }
331 : assert(numfree == 0);
332 0 : return freelist_size;
333 : }
334 :
335 : void
336 0 : PyCFunction_Fini(void)
337 : {
338 0 : (void)PyCFunction_ClearFreeList();
339 0 : }
340 :
341 : /* Print summary info about the state of the optimized allocator */
342 : void
343 0 : _PyCFunction_DebugMallocStats(FILE *out)
344 : {
345 0 : _PyDebugAllocatorStats(out,
346 : "free PyCFunction",
347 : numfree, sizeof(PyCFunction));
348 0 : }
349 :
350 : /* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
351 : but it's part of the API so we need to keep a function around that
352 : existing C extensions can call.
353 : */
354 :
355 : #undef PyCFunction_New
356 : PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);
357 :
358 : PyObject *
359 0 : PyCFunction_New(PyMethodDef *ml, PyObject *self)
360 : {
361 0 : return PyCFunction_NewEx(ml, self, NULL);
362 : }
|