PageRenderTime 42ms CodeModel.GetById 19ms app.highlight 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Objects/methodobject.c

https://gitlab.com/unofficial-mirrors/cpython
C | 657 lines | 526 code | 99 blank | 32 comment | 112 complexity | 3b24a230ff414b18a37276646d41b5af MD5 | raw file
  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 */
 10static PyCFunctionObject *free_list = NULL;
 11static int numfree = 0;
 12#ifndef PyCFunction_MAXFREELIST
 13#define PyCFunction_MAXFREELIST 256
 14#endif
 15
 16/* undefine macro trampoline to PyCFunction_NewEx */
 17#undef PyCFunction_New
 18
 19PyAPI_FUNC(PyObject *)
 20PyCFunction_New(PyMethodDef *ml, PyObject *self)
 21{
 22    return PyCFunction_NewEx(ml, self, NULL);
 23}
 24
 25PyObject *
 26PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
 27{
 28    PyCFunctionObject *op;
 29    op = free_list;
 30    if (op != NULL) {
 31        free_list = (PyCFunctionObject *)(op->m_self);
 32        (void)PyObject_INIT(op, &PyCFunction_Type);
 33        numfree--;
 34    }
 35    else {
 36        op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
 37        if (op == NULL)
 38            return NULL;
 39    }
 40    op->m_weakreflist = NULL;
 41    op->m_ml = ml;
 42    Py_XINCREF(self);
 43    op->m_self = self;
 44    Py_XINCREF(module);
 45    op->m_module = module;
 46    _PyObject_GC_TRACK(op);
 47    return (PyObject *)op;
 48}
 49
 50PyCFunction
 51PyCFunction_GetFunction(PyObject *op)
 52{
 53    if (!PyCFunction_Check(op)) {
 54        PyErr_BadInternalCall();
 55        return NULL;
 56    }
 57    return PyCFunction_GET_FUNCTION(op);
 58}
 59
 60PyObject *
 61PyCFunction_GetSelf(PyObject *op)
 62{
 63    if (!PyCFunction_Check(op)) {
 64        PyErr_BadInternalCall();
 65        return NULL;
 66    }
 67    return PyCFunction_GET_SELF(op);
 68}
 69
 70int
 71PyCFunction_GetFlags(PyObject *op)
 72{
 73    if (!PyCFunction_Check(op)) {
 74        PyErr_BadInternalCall();
 75        return -1;
 76    }
 77    return PyCFunction_GET_FLAGS(op);
 78}
 79
 80static PyObject *
 81cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs)
 82{
 83    assert(!PyErr_Occurred());
 84
 85    PyCFunction meth = PyCFunction_GET_FUNCTION(func);
 86    PyObject *self = PyCFunction_GET_SELF(func);
 87    PyObject *result;
 88
 89    if (PyCFunction_GET_FLAGS(func) & METH_KEYWORDS) {
 90        if (Py_EnterRecursiveCall(" while calling a Python object")) {
 91            return NULL;
 92        }
 93
 94        result = (*(PyCFunctionWithKeywords)meth)(self, args, kwargs);
 95
 96        Py_LeaveRecursiveCall();
 97    }
 98    else {
 99        if (kwargs != NULL && PyDict_Size(kwargs) != 0) {
100            PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
101                         ((PyCFunctionObject*)func)->m_ml->ml_name);
102            return NULL;
103        }
104
105        if (Py_EnterRecursiveCall(" while calling a Python object")) {
106            return NULL;
107        }
108
109        result = (*meth)(self, args);
110
111        Py_LeaveRecursiveCall();
112    }
113
114    return _Py_CheckFunctionResult(func, result, NULL);
115}
116
117
118PyObject *
119PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwargs)
120{
121    /* first try METH_VARARGS to pass directly args tuple unchanged.
122       _PyMethodDef_RawFastCallDict() creates a new temporary tuple
123       for METH_VARARGS. */
124    if (PyCFunction_GET_FLAGS(func) & METH_VARARGS) {
125        return cfunction_call_varargs(func, args, kwargs);
126    }
127    else {
128        return _PyCFunction_FastCallDict(func,
129                                         &PyTuple_GET_ITEM(args, 0),
130                                         PyTuple_GET_SIZE(args),
131                                         kwargs);
132    }
133}
134
135PyObject *
136_PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, PyObject **args,
137                             Py_ssize_t nargs, PyObject *kwargs)
138{
139    /* _PyMethodDef_RawFastCallDict() must not be called with an exception set,
140       because it can clear it (directly or indirectly) and so the
141       caller loses its exception */
142    assert(!PyErr_Occurred());
143
144    assert(method != NULL);
145    assert(nargs >= 0);
146    assert(nargs == 0 || args != NULL);
147    assert(kwargs == NULL || PyDict_Check(kwargs));
148
149    PyCFunction meth = method->ml_meth;
150    int flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
151    PyObject *result = NULL;
152
153    if (Py_EnterRecursiveCall(" while calling a Python object")) {
154        return NULL;
155    }
156
157    switch (flags)
158    {
159    case METH_NOARGS:
160        if (nargs != 0) {
161            PyErr_Format(PyExc_TypeError,
162                "%.200s() takes no arguments (%zd given)",
163                method->ml_name, nargs);
164            goto exit;
165        }
166
167        if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
168            goto no_keyword_error;
169        }
170
171        result = (*meth) (self, NULL);
172        break;
173
174    case METH_O:
175        if (nargs != 1) {
176            PyErr_Format(PyExc_TypeError,
177                "%.200s() takes exactly one argument (%zd given)",
178                method->ml_name, nargs);
179            goto exit;
180        }
181
182        if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
183            goto no_keyword_error;
184        }
185
186        result = (*meth) (self, args[0]);
187        break;
188
189    case METH_VARARGS:
190        if (!(flags & METH_KEYWORDS)
191                && kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
192            goto no_keyword_error;
193        }
194        /* fall through next case */
195
196    case METH_VARARGS | METH_KEYWORDS:
197    {
198        /* Slow-path: create a temporary tuple for positional arguments */
199        PyObject *argstuple = _PyStack_AsTuple(args, nargs);
200        if (argstuple == NULL) {
201            goto exit;
202        }
203
204        if (flags & METH_KEYWORDS) {
205            result = (*(PyCFunctionWithKeywords)meth) (self, argstuple, kwargs);
206        }
207        else {
208            result = (*meth) (self, argstuple);
209        }
210        Py_DECREF(argstuple);
211        break;
212    }
213
214    case METH_FASTCALL:
215    {
216        PyObject **stack;
217        PyObject *kwnames;
218        _PyCFunctionFast fastmeth = (_PyCFunctionFast)meth;
219
220        if (_PyStack_UnpackDict(args, nargs, kwargs, &stack, &kwnames) < 0) {
221            goto exit;
222        }
223
224        result = (*fastmeth) (self, stack, nargs, kwnames);
225        if (stack != args) {
226            PyMem_Free(stack);
227        }
228        Py_XDECREF(kwnames);
229        break;
230    }
231
232    default:
233        PyErr_SetString(PyExc_SystemError,
234                        "Bad call flags in _PyMethodDef_RawFastCallDict. "
235                        "METH_OLDARGS is no longer supported!");
236        goto exit;
237    }
238
239    goto exit;
240
241no_keyword_error:
242    PyErr_Format(PyExc_TypeError,
243                 "%.200s() takes no keyword arguments",
244                 method->ml_name, nargs);
245
246exit:
247    Py_LeaveRecursiveCall();
248    return result;
249}
250
251PyObject *
252_PyCFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
253                          PyObject *kwargs)
254{
255    PyObject *result;
256
257    assert(func != NULL);
258    assert(PyCFunction_Check(func));
259
260    result = _PyMethodDef_RawFastCallDict(((PyCFunctionObject*)func)->m_ml,
261                                          PyCFunction_GET_SELF(func),
262                                          args, nargs, kwargs);
263    result = _Py_CheckFunctionResult(func, result, NULL);
264    return result;
265}
266
267PyObject *
268_PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self, PyObject **args,
269                                 Py_ssize_t nargs, PyObject *kwnames)
270{
271    /* _PyMethodDef_RawFastCallKeywords() must not be called with an exception set,
272       because it can clear it (directly or indirectly) and so the
273       caller loses its exception */
274    assert(!PyErr_Occurred());
275
276    assert(method != NULL);
277    assert(nargs >= 0);
278    assert(kwnames == NULL || PyTuple_CheckExact(kwnames));
279    /* kwnames must only contains str strings, no subclass, and all keys must
280       be unique */
281
282    PyCFunction meth = method->ml_meth;
283    int flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
284    Py_ssize_t nkwargs = kwnames == NULL ? 0 : PyTuple_Size(kwnames);
285    PyObject *result = NULL;
286
287    if (Py_EnterRecursiveCall(" while calling a Python object")) {
288        return NULL;
289    }
290
291    switch (flags)
292    {
293    case METH_NOARGS:
294        if (nargs != 0) {
295            PyErr_Format(PyExc_TypeError,
296                "%.200s() takes no arguments (%zd given)",
297                method->ml_name, nargs);
298            goto exit;
299        }
300
301        if (nkwargs) {
302            goto no_keyword_error;
303        }
304
305        result = (*meth) (self, NULL);
306        break;
307
308    case METH_O:
309        if (nargs != 1) {
310            PyErr_Format(PyExc_TypeError,
311                "%.200s() takes exactly one argument (%zd given)",
312                method->ml_name, nargs);
313            goto exit;
314        }
315
316        if (nkwargs) {
317            goto no_keyword_error;
318        }
319
320        result = (*meth) (self, args[0]);
321        break;
322
323    case METH_FASTCALL:
324        /* Fast-path: avoid temporary dict to pass keyword arguments */
325        result = ((_PyCFunctionFast)meth) (self, args, nargs, kwnames);
326        break;
327
328    case METH_VARARGS:
329    case METH_VARARGS | METH_KEYWORDS:
330    {
331        /* Slow-path: create a temporary tuple for positional arguments
332           and a temporary dict for keyword arguments */
333        PyObject *argtuple;
334
335        if (!(flags & METH_KEYWORDS) && nkwargs) {
336            goto no_keyword_error;
337        }
338
339        argtuple = _PyStack_AsTuple(args, nargs);
340        if (argtuple == NULL) {
341            goto exit;
342        }
343
344        if (flags & METH_KEYWORDS) {
345            PyObject *kwdict;
346
347            if (nkwargs > 0) {
348                kwdict = _PyStack_AsDict(args + nargs, kwnames);
349                if (kwdict == NULL) {
350                    Py_DECREF(argtuple);
351                    goto exit;
352                }
353            }
354            else {
355                kwdict = NULL;
356            }
357
358            result = (*(PyCFunctionWithKeywords)meth) (self, argtuple, kwdict);
359            Py_XDECREF(kwdict);
360        }
361        else {
362            result = (*meth) (self, argtuple);
363        }
364        Py_DECREF(argtuple);
365        break;
366    }
367
368    default:
369        PyErr_SetString(PyExc_SystemError,
370                        "Bad call flags in _PyCFunction_FastCallKeywords. "
371                        "METH_OLDARGS is no longer supported!");
372        goto exit;
373    }
374
375    goto exit;
376
377no_keyword_error:
378    PyErr_Format(PyExc_TypeError,
379                 "%.200s() takes no keyword arguments",
380                 method->ml_name);
381
382exit:
383    Py_LeaveRecursiveCall();
384    return result;
385}
386
387PyObject *
388_PyCFunction_FastCallKeywords(PyObject *func, PyObject **args,
389                              Py_ssize_t nargs, PyObject *kwnames)
390{
391    PyObject *result;
392
393    assert(func != NULL);
394    assert(PyCFunction_Check(func));
395
396    result = _PyMethodDef_RawFastCallKeywords(((PyCFunctionObject*)func)->m_ml,
397                                              PyCFunction_GET_SELF(func),
398                                              args, nargs, kwnames);
399    result = _Py_CheckFunctionResult(func, result, NULL);
400    return result;
401}
402
403/* Methods (the standard built-in methods, that is) */
404
405static void
406meth_dealloc(PyCFunctionObject *m)
407{
408    _PyObject_GC_UNTRACK(m);
409    if (m->m_weakreflist != NULL) {
410        PyObject_ClearWeakRefs((PyObject*) m);
411    }
412    Py_XDECREF(m->m_self);
413    Py_XDECREF(m->m_module);
414    if (numfree < PyCFunction_MAXFREELIST) {
415        m->m_self = (PyObject *)free_list;
416        free_list = m;
417        numfree++;
418    }
419    else {
420        PyObject_GC_Del(m);
421    }
422}
423
424static PyObject *
425meth_reduce(PyCFunctionObject *m)
426{
427    PyObject *builtins;
428    PyObject *getattr;
429    _Py_IDENTIFIER(getattr);
430
431    if (m->m_self == NULL || PyModule_Check(m->m_self))
432        return PyUnicode_FromString(m->m_ml->ml_name);
433
434    builtins = PyEval_GetBuiltins();
435    getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
436    return Py_BuildValue("O(Os)", getattr, m->m_self, m->m_ml->ml_name);
437}
438
439static PyMethodDef meth_methods[] = {
440    {"__reduce__", (PyCFunction)meth_reduce, METH_NOARGS, NULL},
441    {NULL, NULL}
442};
443
444static PyObject *
445meth_get__text_signature__(PyCFunctionObject *m, void *closure)
446{
447    return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc);
448}
449
450static PyObject *
451meth_get__doc__(PyCFunctionObject *m, void *closure)
452{
453    return _PyType_GetDocFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc);
454}
455
456static PyObject *
457meth_get__name__(PyCFunctionObject *m, void *closure)
458{
459    return PyUnicode_FromString(m->m_ml->ml_name);
460}
461
462static PyObject *
463meth_get__qualname__(PyCFunctionObject *m, void *closure)
464{
465    /* If __self__ is a module or NULL, return m.__name__
466       (e.g. len.__qualname__ == 'len')
467
468       If __self__ is a type, return m.__self__.__qualname__ + '.' + m.__name__
469       (e.g. dict.fromkeys.__qualname__ == 'dict.fromkeys')
470
471       Otherwise return type(m.__self__).__qualname__ + '.' + m.__name__
472       (e.g. [].append.__qualname__ == 'list.append') */
473    PyObject *type, *type_qualname, *res;
474    _Py_IDENTIFIER(__qualname__);
475
476    if (m->m_self == NULL || PyModule_Check(m->m_self))
477        return PyUnicode_FromString(m->m_ml->ml_name);
478
479    type = PyType_Check(m->m_self) ? m->m_self : (PyObject*)Py_TYPE(m->m_self);
480
481    type_qualname = _PyObject_GetAttrId(type, &PyId___qualname__);
482    if (type_qualname == NULL)
483        return NULL;
484
485    if (!PyUnicode_Check(type_qualname)) {
486        PyErr_SetString(PyExc_TypeError, "<method>.__class__."
487                        "__qualname__ is not a unicode object");
488        Py_XDECREF(type_qualname);
489        return NULL;
490    }
491
492    res = PyUnicode_FromFormat("%S.%s", type_qualname, m->m_ml->ml_name);
493    Py_DECREF(type_qualname);
494    return res;
495}
496
497static int
498meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
499{
500    Py_VISIT(m->m_self);
501    Py_VISIT(m->m_module);
502    return 0;
503}
504
505static PyObject *
506meth_get__self__(PyCFunctionObject *m, void *closure)
507{
508    PyObject *self;
509
510    self = PyCFunction_GET_SELF(m);
511    if (self == NULL)
512        self = Py_None;
513    Py_INCREF(self);
514    return self;
515}
516
517static PyGetSetDef meth_getsets [] = {
518    {"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
519    {"__name__", (getter)meth_get__name__, NULL, NULL},
520    {"__qualname__", (getter)meth_get__qualname__, NULL, NULL},
521    {"__self__", (getter)meth_get__self__, NULL, NULL},
522    {"__text_signature__", (getter)meth_get__text_signature__, NULL, NULL},
523    {0}
524};
525
526#define OFF(x) offsetof(PyCFunctionObject, x)
527
528static PyMemberDef meth_members[] = {
529    {"__module__",    T_OBJECT,     OFF(m_module), PY_WRITE_RESTRICTED},
530    {NULL}
531};
532
533static PyObject *
534meth_repr(PyCFunctionObject *m)
535{
536    if (m->m_self == NULL || PyModule_Check(m->m_self))
537        return PyUnicode_FromFormat("<built-in function %s>",
538                                   m->m_ml->ml_name);
539    return PyUnicode_FromFormat("<built-in method %s of %s object at %p>",
540                               m->m_ml->ml_name,
541                               m->m_self->ob_type->tp_name,
542                               m->m_self);
543}
544
545static PyObject *
546meth_richcompare(PyObject *self, PyObject *other, int op)
547{
548    PyCFunctionObject *a, *b;
549    PyObject *res;
550    int eq;
551
552    if ((op != Py_EQ && op != Py_NE) ||
553        !PyCFunction_Check(self) ||
554        !PyCFunction_Check(other))
555    {
556        Py_RETURN_NOTIMPLEMENTED;
557    }
558    a = (PyCFunctionObject *)self;
559    b = (PyCFunctionObject *)other;
560    eq = a->m_self == b->m_self;
561    if (eq)
562        eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
563    if (op == Py_EQ)
564        res = eq ? Py_True : Py_False;
565    else
566        res = eq ? Py_False : Py_True;
567    Py_INCREF(res);
568    return res;
569}
570
571static Py_hash_t
572meth_hash(PyCFunctionObject *a)
573{
574    Py_hash_t x, y;
575    if (a->m_self == NULL)
576        x = 0;
577    else {
578        x = PyObject_Hash(a->m_self);
579        if (x == -1)
580            return -1;
581    }
582    y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
583    if (y == -1)
584        return -1;
585    x ^= y;
586    if (x == -1)
587        x = -2;
588    return x;
589}
590
591
592PyTypeObject PyCFunction_Type = {
593    PyVarObject_HEAD_INIT(&PyType_Type, 0)
594    "builtin_function_or_method",
595    sizeof(PyCFunctionObject),
596    0,
597    (destructor)meth_dealloc,                   /* tp_dealloc */
598    0,                                          /* tp_print */
599    0,                                          /* tp_getattr */
600    0,                                          /* tp_setattr */
601    0,                                          /* tp_reserved */
602    (reprfunc)meth_repr,                        /* tp_repr */
603    0,                                          /* tp_as_number */
604    0,                                          /* tp_as_sequence */
605    0,                                          /* tp_as_mapping */
606    (hashfunc)meth_hash,                        /* tp_hash */
607    PyCFunction_Call,                           /* tp_call */
608    0,                                          /* tp_str */
609    PyObject_GenericGetAttr,                    /* tp_getattro */
610    0,                                          /* tp_setattro */
611    0,                                          /* tp_as_buffer */
612    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
613    0,                                          /* tp_doc */
614    (traverseproc)meth_traverse,                /* tp_traverse */
615    0,                                          /* tp_clear */
616    meth_richcompare,                           /* tp_richcompare */
617    offsetof(PyCFunctionObject, m_weakreflist), /* tp_weaklistoffset */
618    0,                                          /* tp_iter */
619    0,                                          /* tp_iternext */
620    meth_methods,                               /* tp_methods */
621    meth_members,                               /* tp_members */
622    meth_getsets,                               /* tp_getset */
623    0,                                          /* tp_base */
624    0,                                          /* tp_dict */
625};
626
627/* Clear out the free list */
628
629int
630PyCFunction_ClearFreeList(void)
631{
632    int freelist_size = numfree;
633
634    while (free_list) {
635        PyCFunctionObject *v = free_list;
636        free_list = (PyCFunctionObject *)(v->m_self);
637        PyObject_GC_Del(v);
638        numfree--;
639    }
640    assert(numfree == 0);
641    return freelist_size;
642}
643
644void
645PyCFunction_Fini(void)
646{
647    (void)PyCFunction_ClearFreeList();
648}
649
650/* Print summary info about the state of the optimized allocator */
651void
652_PyCFunction_DebugMallocStats(FILE *out)
653{
654    _PyDebugAllocatorStats(out,
655                           "free PyCFunctionObject",
656                           numfree, sizeof(PyCFunctionObject));
657}