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