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