(root)/
Python-3.12.0/
Objects/
methodobject.c
       1  
       2  /* Method object implementation */
       3  
       4  #include "Python.h"
       5  #include "pycore_ceval.h"         // _Py_EnterRecursiveCallTstate()
       6  #include "pycore_object.h"
       7  #include "pycore_pyerrors.h"
       8  #include "pycore_pystate.h"       // _PyThreadState_GET()
       9  #include "structmember.h"         // PyMemberDef
      10  
      11  /* undefine macro trampoline to PyCFunction_NewEx */
      12  #undef PyCFunction_New
      13  /* undefine macro trampoline to PyCMethod_New */
      14  #undef PyCFunction_NewEx
      15  
      16  /* Forward declarations */
      17  static PyObject * cfunction_vectorcall_FASTCALL(
      18      PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
      19  static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS(
      20      PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
      21  static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD(
      22      PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
      23  static PyObject * cfunction_vectorcall_NOARGS(
      24      PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
      25  static PyObject * cfunction_vectorcall_O(
      26      PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
      27  static PyObject * cfunction_call(
      28      PyObject *func, PyObject *args, PyObject *kwargs);
      29  
      30  
      31  PyObject *
      32  PyCFunction_New(PyMethodDef *ml, PyObject *self)
      33  {
      34      return PyCFunction_NewEx(ml, self, NULL);
      35  }
      36  
      37  PyObject *
      38  PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
      39  {
      40      return PyCMethod_New(ml, self, module, NULL);
      41  }
      42  
      43  PyObject *
      44  PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *cls)
      45  {
      46      /* Figure out correct vectorcall function to use */
      47      vectorcallfunc vectorcall;
      48      switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS |
      49                              METH_O | METH_KEYWORDS | METH_METHOD))
      50      {
      51          case METH_VARARGS:
      52          case METH_VARARGS | METH_KEYWORDS:
      53              /* For METH_VARARGS functions, it's more efficient to use tp_call
      54               * instead of vectorcall. */
      55              vectorcall = NULL;
      56              break;
      57          case METH_FASTCALL:
      58              vectorcall = cfunction_vectorcall_FASTCALL;
      59              break;
      60          case METH_FASTCALL | METH_KEYWORDS:
      61              vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS;
      62              break;
      63          case METH_NOARGS:
      64              vectorcall = cfunction_vectorcall_NOARGS;
      65              break;
      66          case METH_O:
      67              vectorcall = cfunction_vectorcall_O;
      68              break;
      69          case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
      70              vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD;
      71              break;
      72          default:
      73              PyErr_Format(PyExc_SystemError,
      74                           "%s() method: bad call flags", ml->ml_name);
      75              return NULL;
      76      }
      77  
      78      PyCFunctionObject *op = NULL;
      79  
      80      if (ml->ml_flags & METH_METHOD) {
      81          if (!cls) {
      82              PyErr_SetString(PyExc_SystemError,
      83                              "attempting to create PyCMethod with a METH_METHOD "
      84                              "flag but no class");
      85              return NULL;
      86          }
      87          PyCMethodObject *om = PyObject_GC_New(PyCMethodObject, &PyCMethod_Type);
      88          if (om == NULL) {
      89              return NULL;
      90          }
      91          om->mm_class = (PyTypeObject*)Py_NewRef(cls);
      92          op = (PyCFunctionObject *)om;
      93      } else {
      94          if (cls) {
      95              PyErr_SetString(PyExc_SystemError,
      96                              "attempting to create PyCFunction with class "
      97                              "but no METH_METHOD flag");
      98              return NULL;
      99          }
     100          op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
     101          if (op == NULL) {
     102              return NULL;
     103          }
     104      }
     105  
     106      op->m_weakreflist = NULL;
     107      op->m_ml = ml;
     108      op->m_self = Py_XNewRef(self);
     109      op->m_module = Py_XNewRef(module);
     110      op->vectorcall = vectorcall;
     111      _PyObject_GC_TRACK(op);
     112      return (PyObject *)op;
     113  }
     114  
     115  PyCFunction
     116  PyCFunction_GetFunction(PyObject *op)
     117  {
     118      if (!PyCFunction_Check(op)) {
     119          PyErr_BadInternalCall();
     120          return NULL;
     121      }
     122      return PyCFunction_GET_FUNCTION(op);
     123  }
     124  
     125  PyObject *
     126  PyCFunction_GetSelf(PyObject *op)
     127  {
     128      if (!PyCFunction_Check(op)) {
     129          PyErr_BadInternalCall();
     130          return NULL;
     131      }
     132      return PyCFunction_GET_SELF(op);
     133  }
     134  
     135  int
     136  PyCFunction_GetFlags(PyObject *op)
     137  {
     138      if (!PyCFunction_Check(op)) {
     139          PyErr_BadInternalCall();
     140          return -1;
     141      }
     142      return PyCFunction_GET_FLAGS(op);
     143  }
     144  
     145  PyTypeObject *
     146  PyCMethod_GetClass(PyObject *op)
     147  {
     148      if (!PyCFunction_Check(op)) {
     149          PyErr_BadInternalCall();
     150          return NULL;
     151      }
     152      return PyCFunction_GET_CLASS(op);
     153  }
     154  
     155  /* Methods (the standard built-in methods, that is) */
     156  
     157  static void
     158  meth_dealloc(PyCFunctionObject *m)
     159  {
     160      // The Py_TRASHCAN mechanism requires that we be able to
     161      // call PyObject_GC_UnTrack twice on an object.
     162      PyObject_GC_UnTrack(m);
     163      Py_TRASHCAN_BEGIN(m, meth_dealloc);
     164      if (m->m_weakreflist != NULL) {
     165          PyObject_ClearWeakRefs((PyObject*) m);
     166      }
     167      // Dereference class before m_self: PyCFunction_GET_CLASS accesses
     168      // PyMethodDef m_ml, which could be kept alive by m_self
     169      Py_XDECREF(PyCFunction_GET_CLASS(m));
     170      Py_XDECREF(m->m_self);
     171      Py_XDECREF(m->m_module);
     172      PyObject_GC_Del(m);
     173      Py_TRASHCAN_END;
     174  }
     175  
     176  static PyObject *
     177  meth_reduce(PyCFunctionObject *m, PyObject *Py_UNUSED(ignored))
     178  {
     179      if (m->m_self == NULL || PyModule_Check(m->m_self))
     180          return PyUnicode_FromString(m->m_ml->ml_name);
     181  
     182      return Py_BuildValue("N(Os)", _PyEval_GetBuiltin(&_Py_ID(getattr)),
     183                           m->m_self, m->m_ml->ml_name);
     184  }
     185  
     186  static PyMethodDef meth_methods[] = {
     187      {"__reduce__", (PyCFunction)meth_reduce, METH_NOARGS, NULL},
     188      {NULL, NULL}
     189  };
     190  
     191  static PyObject *
     192  meth_get__text_signature__(PyCFunctionObject *m, void *closure)
     193  {
     194      return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc);
     195  }
     196  
     197  static PyObject *
     198  meth_get__doc__(PyCFunctionObject *m, void *closure)
     199  {
     200      return _PyType_GetDocFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc);
     201  }
     202  
     203  static PyObject *
     204  meth_get__name__(PyCFunctionObject *m, void *closure)
     205  {
     206      return PyUnicode_FromString(m->m_ml->ml_name);
     207  }
     208  
     209  static PyObject *
     210  meth_get__qualname__(PyCFunctionObject *m, void *closure)
     211  {
     212      /* If __self__ is a module or NULL, return m.__name__
     213         (e.g. len.__qualname__ == 'len')
     214  
     215         If __self__ is a type, return m.__self__.__qualname__ + '.' + m.__name__
     216         (e.g. dict.fromkeys.__qualname__ == 'dict.fromkeys')
     217  
     218         Otherwise return type(m.__self__).__qualname__ + '.' + m.__name__
     219         (e.g. [].append.__qualname__ == 'list.append') */
     220      PyObject *type, *type_qualname, *res;
     221  
     222      if (m->m_self == NULL || PyModule_Check(m->m_self))
     223          return PyUnicode_FromString(m->m_ml->ml_name);
     224  
     225      type = PyType_Check(m->m_self) ? m->m_self : (PyObject*)Py_TYPE(m->m_self);
     226  
     227      type_qualname = PyObject_GetAttr(type, &_Py_ID(__qualname__));
     228      if (type_qualname == NULL)
     229          return NULL;
     230  
     231      if (!PyUnicode_Check(type_qualname)) {
     232          PyErr_SetString(PyExc_TypeError, "<method>.__class__."
     233                          "__qualname__ is not a unicode object");
     234          Py_XDECREF(type_qualname);
     235          return NULL;
     236      }
     237  
     238      res = PyUnicode_FromFormat("%S.%s", type_qualname, m->m_ml->ml_name);
     239      Py_DECREF(type_qualname);
     240      return res;
     241  }
     242  
     243  static int
     244  meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
     245  {
     246      Py_VISIT(PyCFunction_GET_CLASS(m));
     247      Py_VISIT(m->m_self);
     248      Py_VISIT(m->m_module);
     249      return 0;
     250  }
     251  
     252  static PyObject *
     253  meth_get__self__(PyCFunctionObject *m, void *closure)
     254  {
     255      PyObject *self;
     256  
     257      self = PyCFunction_GET_SELF(m);
     258      if (self == NULL)
     259          self = Py_None;
     260      return Py_NewRef(self);
     261  }
     262  
     263  static PyGetSetDef meth_getsets [] = {
     264      {"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
     265      {"__name__", (getter)meth_get__name__, NULL, NULL},
     266      {"__qualname__", (getter)meth_get__qualname__, NULL, NULL},
     267      {"__self__", (getter)meth_get__self__, NULL, NULL},
     268      {"__text_signature__", (getter)meth_get__text_signature__, NULL, NULL},
     269      {0}
     270  };
     271  
     272  #define OFF(x) offsetof(PyCFunctionObject, x)
     273  
     274  static PyMemberDef meth_members[] = {
     275      {"__module__",    T_OBJECT,     OFF(m_module), 0},
     276      {NULL}
     277  };
     278  
     279  static PyObject *
     280  meth_repr(PyCFunctionObject *m)
     281  {
     282      if (m->m_self == NULL || PyModule_Check(m->m_self))
     283          return PyUnicode_FromFormat("<built-in function %s>",
     284                                     m->m_ml->ml_name);
     285      return PyUnicode_FromFormat("<built-in method %s of %s object at %p>",
     286                                 m->m_ml->ml_name,
     287                                 Py_TYPE(m->m_self)->tp_name,
     288                                 m->m_self);
     289  }
     290  
     291  static PyObject *
     292  meth_richcompare(PyObject *self, PyObject *other, int op)
     293  {
     294      PyCFunctionObject *a, *b;
     295      PyObject *res;
     296      int eq;
     297  
     298      if ((op != Py_EQ && op != Py_NE) ||
     299          !PyCFunction_Check(self) ||
     300          !PyCFunction_Check(other))
     301      {
     302          Py_RETURN_NOTIMPLEMENTED;
     303      }
     304      a = (PyCFunctionObject *)self;
     305      b = (PyCFunctionObject *)other;
     306      eq = a->m_self == b->m_self;
     307      if (eq)
     308          eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
     309      if (op == Py_EQ)
     310          res = eq ? Py_True : Py_False;
     311      else
     312          res = eq ? Py_False : Py_True;
     313      return Py_NewRef(res);
     314  }
     315  
     316  static Py_hash_t
     317  meth_hash(PyCFunctionObject *a)
     318  {
     319      Py_hash_t x, y;
     320      x = _Py_HashPointer(a->m_self);
     321      y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
     322      x ^= y;
     323      if (x == -1)
     324          x = -2;
     325      return x;
     326  }
     327  
     328  
     329  PyTypeObject PyCFunction_Type = {
     330      PyVarObject_HEAD_INIT(&PyType_Type, 0)
     331      "builtin_function_or_method",
     332      sizeof(PyCFunctionObject),
     333      0,
     334      (destructor)meth_dealloc,                   /* tp_dealloc */
     335      offsetof(PyCFunctionObject, vectorcall),    /* tp_vectorcall_offset */
     336      0,                                          /* tp_getattr */
     337      0,                                          /* tp_setattr */
     338      0,                                          /* tp_as_async */
     339      (reprfunc)meth_repr,                        /* tp_repr */
     340      0,                                          /* tp_as_number */
     341      0,                                          /* tp_as_sequence */
     342      0,                                          /* tp_as_mapping */
     343      (hashfunc)meth_hash,                        /* tp_hash */
     344      cfunction_call,                             /* tp_call */
     345      0,                                          /* tp_str */
     346      PyObject_GenericGetAttr,                    /* tp_getattro */
     347      0,                                          /* tp_setattro */
     348      0,                                          /* tp_as_buffer */
     349      Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
     350      Py_TPFLAGS_HAVE_VECTORCALL,                 /* tp_flags */
     351      0,                                          /* tp_doc */
     352      (traverseproc)meth_traverse,                /* tp_traverse */
     353      0,                                          /* tp_clear */
     354      meth_richcompare,                           /* tp_richcompare */
     355      offsetof(PyCFunctionObject, m_weakreflist), /* tp_weaklistoffset */
     356      0,                                          /* tp_iter */
     357      0,                                          /* tp_iternext */
     358      meth_methods,                               /* tp_methods */
     359      meth_members,                               /* tp_members */
     360      meth_getsets,                               /* tp_getset */
     361      0,                                          /* tp_base */
     362      0,                                          /* tp_dict */
     363  };
     364  
     365  PyTypeObject PyCMethod_Type = {
     366      PyVarObject_HEAD_INIT(&PyType_Type, 0)
     367      .tp_name = "builtin_method",
     368      .tp_basicsize = sizeof(PyCMethodObject),
     369      .tp_base = &PyCFunction_Type,
     370  };
     371  
     372  /* Vectorcall functions for each of the PyCFunction calling conventions,
     373   * except for METH_VARARGS (possibly combined with METH_KEYWORDS) which
     374   * doesn't use vectorcall.
     375   *
     376   * First, common helpers
     377   */
     378  
     379  static inline int
     380  cfunction_check_kwargs(PyThreadState *tstate, PyObject *func, PyObject *kwnames)
     381  {
     382      assert(!_PyErr_Occurred(tstate));
     383      assert(PyCFunction_Check(func));
     384      if (kwnames && PyTuple_GET_SIZE(kwnames)) {
     385          PyObject *funcstr = _PyObject_FunctionStr(func);
     386          if (funcstr != NULL) {
     387              _PyErr_Format(tstate, PyExc_TypeError,
     388                           "%U takes no keyword arguments", funcstr);
     389              Py_DECREF(funcstr);
     390          }
     391          return -1;
     392      }
     393      return 0;
     394  }
     395  
     396  typedef void (*funcptr)(void);
     397  
     398  static inline funcptr
     399  cfunction_enter_call(PyThreadState *tstate, PyObject *func)
     400  {
     401      if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
     402          return NULL;
     403      }
     404      return (funcptr)PyCFunction_GET_FUNCTION(func);
     405  }
     406  
     407  /* Now the actual vectorcall functions */
     408  static PyObject *
     409  cfunction_vectorcall_FASTCALL(
     410      PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     411  {
     412      PyThreadState *tstate = _PyThreadState_GET();
     413      if (cfunction_check_kwargs(tstate, func, kwnames)) {
     414          return NULL;
     415      }
     416      Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     417      _PyCFunctionFast meth = (_PyCFunctionFast)
     418                              cfunction_enter_call(tstate, func);
     419      if (meth == NULL) {
     420          return NULL;
     421      }
     422      PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs);
     423      _Py_LeaveRecursiveCallTstate(tstate);
     424      return result;
     425  }
     426  
     427  static PyObject *
     428  cfunction_vectorcall_FASTCALL_KEYWORDS(
     429      PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     430  {
     431      PyThreadState *tstate = _PyThreadState_GET();
     432      Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     433      _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
     434                                          cfunction_enter_call(tstate, func);
     435      if (meth == NULL) {
     436          return NULL;
     437      }
     438      PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames);
     439      _Py_LeaveRecursiveCallTstate(tstate);
     440      return result;
     441  }
     442  
     443  static PyObject *
     444  cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD(
     445      PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     446  {
     447      PyThreadState *tstate = _PyThreadState_GET();
     448      PyTypeObject *cls = PyCFunction_GET_CLASS(func);
     449      Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     450      PyCMethod meth = (PyCMethod)cfunction_enter_call(tstate, func);
     451      if (meth == NULL) {
     452          return NULL;
     453      }
     454      PyObject *result = meth(PyCFunction_GET_SELF(func), cls, args, nargs, kwnames);
     455      _Py_LeaveRecursiveCallTstate(tstate);
     456      return result;
     457  }
     458  
     459  static PyObject *
     460  cfunction_vectorcall_NOARGS(
     461      PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     462  {
     463      PyThreadState *tstate = _PyThreadState_GET();
     464      if (cfunction_check_kwargs(tstate, func, kwnames)) {
     465          return NULL;
     466      }
     467      Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     468      if (nargs != 0) {
     469          PyObject *funcstr = _PyObject_FunctionStr(func);
     470          if (funcstr != NULL) {
     471              _PyErr_Format(tstate, PyExc_TypeError,
     472                  "%U takes no arguments (%zd given)", funcstr, nargs);
     473              Py_DECREF(funcstr);
     474          }
     475          return NULL;
     476      }
     477      PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func);
     478      if (meth == NULL) {
     479          return NULL;
     480      }
     481      PyObject *result = _PyCFunction_TrampolineCall(
     482          meth, PyCFunction_GET_SELF(func), NULL);
     483      _Py_LeaveRecursiveCallTstate(tstate);
     484      return result;
     485  }
     486  
     487  static PyObject *
     488  cfunction_vectorcall_O(
     489      PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     490  {
     491      PyThreadState *tstate = _PyThreadState_GET();
     492      if (cfunction_check_kwargs(tstate, func, kwnames)) {
     493          return NULL;
     494      }
     495      Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     496      if (nargs != 1) {
     497          PyObject *funcstr = _PyObject_FunctionStr(func);
     498          if (funcstr != NULL) {
     499              _PyErr_Format(tstate, PyExc_TypeError,
     500                  "%U takes exactly one argument (%zd given)", funcstr, nargs);
     501              Py_DECREF(funcstr);
     502          }
     503          return NULL;
     504      }
     505      PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func);
     506      if (meth == NULL) {
     507          return NULL;
     508      }
     509      PyObject *result = _PyCFunction_TrampolineCall(
     510          meth, PyCFunction_GET_SELF(func), args[0]);
     511      _Py_LeaveRecursiveCallTstate(tstate);
     512      return result;
     513  }
     514  
     515  
     516  static PyObject *
     517  cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs)
     518  {
     519      assert(kwargs == NULL || PyDict_Check(kwargs));
     520  
     521      PyThreadState *tstate = _PyThreadState_GET();
     522      assert(!_PyErr_Occurred(tstate));
     523  
     524      int flags = PyCFunction_GET_FLAGS(func);
     525      if (!(flags & METH_VARARGS)) {
     526          /* If this is not a METH_VARARGS function, delegate to vectorcall */
     527          return PyVectorcall_Call(func, args, kwargs);
     528      }
     529  
     530      /* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer
     531       * is NULL. This is intentional, since vectorcall would be slower. */
     532      PyCFunction meth = PyCFunction_GET_FUNCTION(func);
     533      PyObject *self = PyCFunction_GET_SELF(func);
     534  
     535      PyObject *result;
     536      if (flags & METH_KEYWORDS) {
     537          result = _PyCFunctionWithKeywords_TrampolineCall(
     538              (*(PyCFunctionWithKeywords)(void(*)(void))meth),
     539              self, args, kwargs);
     540      }
     541      else {
     542          if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
     543              _PyErr_Format(tstate, PyExc_TypeError,
     544                            "%.200s() takes no keyword arguments",
     545                            ((PyCFunctionObject*)func)->m_ml->ml_name);
     546              return NULL;
     547          }
     548          result = _PyCFunction_TrampolineCall(meth, self, args);
     549      }
     550      return _Py_CheckFunctionResult(tstate, func, result, NULL);
     551  }
     552  
     553  #if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
     554  #include <emscripten.h>
     555  
     556  EM_JS(PyObject*, _PyCFunctionWithKeywords_TrampolineCall, (PyCFunctionWithKeywords func, PyObject *self, PyObject *args, PyObject *kw), {
     557      return wasmTable.get(func)(self, args, kw);
     558  });
     559  #endif