1/* Class object implementation (dead now except for methods) */ 2 3#include "Python.h" 4#include "pycore_call.h" // _PyObject_VectorcallTstate() 5#include "pycore_object.h" 6#include "pycore_pyerrors.h" 7#include "pycore_pystate.h" // _PyThreadState_GET() 8#include "structmember.h" // PyMemberDef 9 10#include "clinic/classobject.c.h" 11 12#define TP_DESCR_GET(t) ((t)->tp_descr_get) 13 14/*[clinic input] 15class method "PyMethodObject *" "&PyMethod_Type" 16[clinic start generated code]*/ 17/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b16e47edf6107c23]*/ 18 19 20PyObject * 21PyMethod_Function(PyObject *im) 22{ 23 if (!PyMethod_Check(im)) { 24 PyErr_BadInternalCall(); 25 return NULL; 26 } 27 return ((PyMethodObject *)im)->im_func; 28} 29 30PyObject * 31PyMethod_Self(PyObject *im) 32{ 33 if (!PyMethod_Check(im)) { 34 PyErr_BadInternalCall(); 35 return NULL; 36 } 37 return ((PyMethodObject *)im)->im_self; 38} 39 40 41static PyObject * 42method_vectorcall(PyObject *method, PyObject *const *args, 43 size_t nargsf, PyObject *kwnames) 44{ 45 assert(Py_IS_TYPE(method, &PyMethod_Type)); 46 47 PyThreadState *tstate = _PyThreadState_GET(); 48 PyObject *self = PyMethod_GET_SELF(method); 49 PyObject *func = PyMethod_GET_FUNCTION(method); 50 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); 51 52 PyObject *result; 53 if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) { 54 /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */ 55 PyObject **newargs = (PyObject**)args - 1; 56 nargs += 1; 57 PyObject *tmp = newargs[0]; 58 newargs[0] = self; 59 result = _PyObject_VectorcallTstate(tstate, func, newargs, 60 nargs, kwnames); 61 newargs[0] = tmp; 62 } 63 else { 64 Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); 65 Py_ssize_t totalargs = nargs + nkwargs; 66 if (totalargs == 0) { 67 return _PyObject_VectorcallTstate(tstate, func, &self, 1, NULL); 68 } 69 70 PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK]; 71 PyObject **newargs; 72 if (totalargs <= (Py_ssize_t)Py_ARRAY_LENGTH(newargs_stack) - 1) { 73 newargs = newargs_stack; 74 } 75 else { 76 newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *)); 77 if (newargs == NULL) { 78 _PyErr_NoMemory(tstate); 79 return NULL; 80 } 81 } 82 /* use borrowed references */ 83 newargs[0] = self; 84 /* bpo-37138: since totalargs > 0, it's impossible that args is NULL. 85 * We need this, since calling memcpy() with a NULL pointer is 86 * undefined behaviour. */ 87 assert(args != NULL); 88 memcpy(newargs + 1, args, totalargs * sizeof(PyObject *)); 89 result = _PyObject_VectorcallTstate(tstate, func, 90 newargs, nargs+1, kwnames); 91 if (newargs != newargs_stack) { 92 PyMem_Free(newargs); 93 } 94 } 95 return result; 96} 97 98 99/* Method objects are used for bound instance methods returned by 100 instancename.methodname. ClassName.methodname returns an ordinary 101 function. 102*/ 103 104PyObject * 105PyMethod_New(PyObject *func, PyObject *self) 106{ 107 if (self == NULL) { 108 PyErr_BadInternalCall(); 109 return NULL; 110 } 111 PyMethodObject *im = PyObject_GC_New(PyMethodObject, &PyMethod_Type); 112 if (im == NULL) { 113 return NULL; 114 } 115 im->im_weakreflist = NULL; 116 Py_INCREF(func); 117 im->im_func = func; 118 Py_INCREF(self); 119 im->im_self = self; 120 im->vectorcall = method_vectorcall; 121 _PyObject_GC_TRACK(im); 122 return (PyObject *)im; 123} 124 125/*[clinic input] 126method.__reduce__ 127[clinic start generated code]*/ 128 129static PyObject * 130method___reduce___impl(PyMethodObject *self) 131/*[clinic end generated code: output=6c04506d0fa6fdcb input=143a0bf5e96de6e8]*/ 132{ 133 PyObject *funcself = PyMethod_GET_SELF(self); 134 PyObject *func = PyMethod_GET_FUNCTION(self); 135 PyObject *funcname = PyObject_GetAttr(func, &_Py_ID(__name__)); 136 if (funcname == NULL) { 137 return NULL; 138 } 139 return Py_BuildValue( 140 "N(ON)", _PyEval_GetBuiltin(&_Py_ID(getattr)), funcself, funcname); 141} 142 143static PyMethodDef method_methods[] = { 144 METHOD___REDUCE___METHODDEF 145 {NULL, NULL} 146}; 147 148/* Descriptors for PyMethod attributes */ 149 150/* im_func and im_self are stored in the PyMethod object */ 151 152#define MO_OFF(x) offsetof(PyMethodObject, x) 153 154static PyMemberDef method_memberlist[] = { 155 {"__func__", T_OBJECT, MO_OFF(im_func), READONLY, 156 "the function (or other callable) implementing a method"}, 157 {"__self__", T_OBJECT, MO_OFF(im_self), READONLY, 158 "the instance to which a method is bound"}, 159 {NULL} /* Sentinel */ 160}; 161 162/* Christian Tismer argued convincingly that method attributes should 163 (nearly) always override function attributes. 164 The one exception is __doc__; there's a default __doc__ which 165 should only be used for the class, not for instances */ 166 167static PyObject * 168method_get_doc(PyMethodObject *im, void *context) 169{ 170 return PyObject_GetAttr(im->im_func, &_Py_ID(__doc__)); 171} 172 173static PyGetSetDef method_getset[] = { 174 {"__doc__", (getter)method_get_doc, NULL, NULL}, 175 {0} 176}; 177 178static PyObject * 179method_getattro(PyObject *obj, PyObject *name) 180{ 181 PyMethodObject *im = (PyMethodObject *)obj; 182 PyTypeObject *tp = Py_TYPE(obj); 183 PyObject *descr = NULL; 184 185 { 186 if (tp->tp_dict == NULL) { 187 if (PyType_Ready(tp) < 0) 188 return NULL; 189 } 190 descr = _PyType_Lookup(tp, name); 191 } 192 193 if (descr != NULL) { 194 descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr)); 195 if (f != NULL) 196 return f(descr, obj, (PyObject *)Py_TYPE(obj)); 197 else { 198 Py_INCREF(descr); 199 return descr; 200 } 201 } 202 203 return PyObject_GetAttr(im->im_func, name); 204} 205 206/*[clinic input] 207@classmethod 208method.__new__ as method_new 209 function: object 210 instance: object 211 / 212 213Create a bound instance method object. 214[clinic start generated code]*/ 215 216static PyObject * 217method_new_impl(PyTypeObject *type, PyObject *function, PyObject *instance) 218/*[clinic end generated code: output=d33ef4ebf702e1f7 input=4e32facc3c3108ae]*/ 219{ 220 if (!PyCallable_Check(function)) { 221 PyErr_SetString(PyExc_TypeError, 222 "first argument must be callable"); 223 return NULL; 224 } 225 if (instance == NULL || instance == Py_None) { 226 PyErr_SetString(PyExc_TypeError, 227 "instance must not be None"); 228 return NULL; 229 } 230 231 return PyMethod_New(function, instance); 232} 233 234static void 235method_dealloc(PyMethodObject *im) 236{ 237 _PyObject_GC_UNTRACK(im); 238 if (im->im_weakreflist != NULL) 239 PyObject_ClearWeakRefs((PyObject *)im); 240 Py_DECREF(im->im_func); 241 Py_XDECREF(im->im_self); 242 PyObject_GC_Del(im); 243} 244 245static PyObject * 246method_richcompare(PyObject *self, PyObject *other, int op) 247{ 248 PyMethodObject *a, *b; 249 PyObject *res; 250 int eq; 251 252 if ((op != Py_EQ && op != Py_NE) || 253 !PyMethod_Check(self) || 254 !PyMethod_Check(other)) 255 { 256 Py_RETURN_NOTIMPLEMENTED; 257 } 258 a = (PyMethodObject *)self; 259 b = (PyMethodObject *)other; 260 eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ); 261 if (eq == 1) { 262 eq = (a->im_self == b->im_self); 263 } 264 else if (eq < 0) 265 return NULL; 266 if (op == Py_EQ) 267 res = eq ? Py_True : Py_False; 268 else 269 res = eq ? Py_False : Py_True; 270 Py_INCREF(res); 271 return res; 272} 273 274static PyObject * 275method_repr(PyMethodObject *a) 276{ 277 PyObject *self = a->im_self; 278 PyObject *func = a->im_func; 279 PyObject *funcname, *result; 280 const char *defname = "?"; 281 282 if (_PyObject_LookupAttr(func, &_Py_ID(__qualname__), &funcname) < 0 || 283 (funcname == NULL && 284 _PyObject_LookupAttr(func, &_Py_ID(__name__), &funcname) < 0)) 285 { 286 return NULL; 287 } 288 289 if (funcname != NULL && !PyUnicode_Check(funcname)) { 290 Py_DECREF(funcname); 291 funcname = NULL; 292 } 293 294 /* XXX Shouldn't use repr()/%R here! */ 295 result = PyUnicode_FromFormat("<bound method %V of %R>", 296 funcname, defname, self); 297 298 Py_XDECREF(funcname); 299 return result; 300} 301 302static Py_hash_t 303method_hash(PyMethodObject *a) 304{ 305 Py_hash_t x, y; 306 x = _Py_HashPointer(a->im_self); 307 y = PyObject_Hash(a->im_func); 308 if (y == -1) 309 return -1; 310 x = x ^ y; 311 if (x == -1) 312 x = -2; 313 return x; 314} 315 316static int 317method_traverse(PyMethodObject *im, visitproc visit, void *arg) 318{ 319 Py_VISIT(im->im_func); 320 Py_VISIT(im->im_self); 321 return 0; 322} 323 324PyTypeObject PyMethod_Type = { 325 PyVarObject_HEAD_INIT(&PyType_Type, 0) 326 .tp_name = "method", 327 .tp_basicsize = sizeof(PyMethodObject), 328 .tp_dealloc = (destructor)method_dealloc, 329 .tp_vectorcall_offset = offsetof(PyMethodObject, vectorcall), 330 .tp_repr = (reprfunc)method_repr, 331 .tp_hash = (hashfunc)method_hash, 332 .tp_call = PyVectorcall_Call, 333 .tp_getattro = method_getattro, 334 .tp_setattro = PyObject_GenericSetAttr, 335 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 336 Py_TPFLAGS_HAVE_VECTORCALL, 337 .tp_doc = method_new__doc__, 338 .tp_traverse = (traverseproc)method_traverse, 339 .tp_richcompare = method_richcompare, 340 .tp_weaklistoffset = offsetof(PyMethodObject, im_weakreflist), 341 .tp_methods = method_methods, 342 .tp_members = method_memberlist, 343 .tp_getset = method_getset, 344 .tp_new = method_new, 345}; 346 347/* ------------------------------------------------------------------------ 348 * instance method 349 */ 350 351/*[clinic input] 352class instancemethod "PyInstanceMethodObject *" "&PyInstanceMethod_Type" 353[clinic start generated code]*/ 354/*[clinic end generated code: output=da39a3ee5e6b4b0d input=28c9762a9016f4d2]*/ 355 356PyObject * 357PyInstanceMethod_New(PyObject *func) { 358 PyInstanceMethodObject *method; 359 method = PyObject_GC_New(PyInstanceMethodObject, 360 &PyInstanceMethod_Type); 361 if (method == NULL) return NULL; 362 Py_INCREF(func); 363 method->func = func; 364 _PyObject_GC_TRACK(method); 365 return (PyObject *)method; 366} 367 368PyObject * 369PyInstanceMethod_Function(PyObject *im) 370{ 371 if (!PyInstanceMethod_Check(im)) { 372 PyErr_BadInternalCall(); 373 return NULL; 374 } 375 return PyInstanceMethod_GET_FUNCTION(im); 376} 377 378#define IMO_OFF(x) offsetof(PyInstanceMethodObject, x) 379 380static PyMemberDef instancemethod_memberlist[] = { 381 {"__func__", T_OBJECT, IMO_OFF(func), READONLY, 382 "the function (or other callable) implementing a method"}, 383 {NULL} /* Sentinel */ 384}; 385 386static PyObject * 387instancemethod_get_doc(PyObject *self, void *context) 388{ 389 return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), 390 &_Py_ID(__doc__)); 391} 392 393static PyGetSetDef instancemethod_getset[] = { 394 {"__doc__", (getter)instancemethod_get_doc, NULL, NULL}, 395 {0} 396}; 397 398static PyObject * 399instancemethod_getattro(PyObject *self, PyObject *name) 400{ 401 PyTypeObject *tp = Py_TYPE(self); 402 PyObject *descr = NULL; 403 404 if (tp->tp_dict == NULL) { 405 if (PyType_Ready(tp) < 0) 406 return NULL; 407 } 408 descr = _PyType_Lookup(tp, name); 409 410 if (descr != NULL) { 411 descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr)); 412 if (f != NULL) 413 return f(descr, self, (PyObject *)Py_TYPE(self)); 414 else { 415 Py_INCREF(descr); 416 return descr; 417 } 418 } 419 420 return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name); 421} 422 423static void 424instancemethod_dealloc(PyObject *self) { 425 _PyObject_GC_UNTRACK(self); 426 Py_DECREF(PyInstanceMethod_GET_FUNCTION(self)); 427 PyObject_GC_Del(self); 428} 429 430static int 431instancemethod_traverse(PyObject *self, visitproc visit, void *arg) { 432 Py_VISIT(PyInstanceMethod_GET_FUNCTION(self)); 433 return 0; 434} 435 436static PyObject * 437instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw) 438{ 439 return PyObject_Call(PyInstanceMethod_GET_FUNCTION(self), arg, kw); 440} 441 442static PyObject * 443instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) { 444 PyObject *func = PyInstanceMethod_GET_FUNCTION(descr); 445 if (obj == NULL) { 446 Py_INCREF(func); 447 return func; 448 } 449 else 450 return PyMethod_New(func, obj); 451} 452 453static PyObject * 454instancemethod_richcompare(PyObject *self, PyObject *other, int op) 455{ 456 PyInstanceMethodObject *a, *b; 457 PyObject *res; 458 int eq; 459 460 if ((op != Py_EQ && op != Py_NE) || 461 !PyInstanceMethod_Check(self) || 462 !PyInstanceMethod_Check(other)) 463 { 464 Py_RETURN_NOTIMPLEMENTED; 465 } 466 a = (PyInstanceMethodObject *)self; 467 b = (PyInstanceMethodObject *)other; 468 eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ); 469 if (eq < 0) 470 return NULL; 471 if (op == Py_EQ) 472 res = eq ? Py_True : Py_False; 473 else 474 res = eq ? Py_False : Py_True; 475 Py_INCREF(res); 476 return res; 477} 478 479static PyObject * 480instancemethod_repr(PyObject *self) 481{ 482 PyObject *func = PyInstanceMethod_Function(self); 483 PyObject *funcname, *result; 484 const char *defname = "?"; 485 486 if (func == NULL) { 487 PyErr_BadInternalCall(); 488 return NULL; 489 } 490 491 if (_PyObject_LookupAttr(func, &_Py_ID(__name__), &funcname) < 0) { 492 return NULL; 493 } 494 if (funcname != NULL && !PyUnicode_Check(funcname)) { 495 Py_DECREF(funcname); 496 funcname = NULL; 497 } 498 499 result = PyUnicode_FromFormat("<instancemethod %V at %p>", 500 funcname, defname, self); 501 502 Py_XDECREF(funcname); 503 return result; 504} 505 506/*[clinic input] 507@classmethod 508instancemethod.__new__ as instancemethod_new 509 function: object 510 / 511 512Bind a function to a class. 513[clinic start generated code]*/ 514 515static PyObject * 516instancemethod_new_impl(PyTypeObject *type, PyObject *function) 517/*[clinic end generated code: output=5e0397b2bdb750be input=cfc54e8b973664a8]*/ 518{ 519 if (!PyCallable_Check(function)) { 520 PyErr_SetString(PyExc_TypeError, 521 "first argument must be callable"); 522 return NULL; 523 } 524 525 return PyInstanceMethod_New(function); 526} 527 528PyTypeObject PyInstanceMethod_Type = { 529 PyVarObject_HEAD_INIT(&PyType_Type, 0) 530 .tp_name = "instancemethod", 531 .tp_basicsize = sizeof(PyInstanceMethodObject), 532 .tp_dealloc = instancemethod_dealloc, 533 .tp_repr = (reprfunc)instancemethod_repr, 534 .tp_call = instancemethod_call, 535 .tp_getattro = instancemethod_getattro, 536 .tp_setattro = PyObject_GenericSetAttr, 537 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, 538 .tp_doc = instancemethod_new__doc__, 539 .tp_traverse = instancemethod_traverse, 540 .tp_richcompare = instancemethod_richcompare, 541 .tp_members = instancemethod_memberlist, 542 .tp_getset = instancemethod_getset, 543 .tp_descr_get = instancemethod_descr_get, 544 .tp_new = instancemethod_new, 545}; 546