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]
15 class method "PyMethodObject *" "&PyMethod_Type"
16 [clinic start generated code]*/
17 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b16e47edf6107c23]*/
18
19
20 PyObject *
PyMethod_Function(PyObject * im)21 PyMethod_Function(PyObject *im)
22 {
23 if (!PyMethod_Check(im)) {
24 PyErr_BadInternalCall();
25 return NULL;
26 }
27 return ((PyMethodObject *)im)->im_func;
28 }
29
30 PyObject *
PyMethod_Self(PyObject * im)31 PyMethod_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
41 static PyObject *
method_vectorcall(PyObject * method,PyObject * const * args,size_t nargsf,PyObject * kwnames)42 method_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
104 PyObject *
PyMethod_New(PyObject * func,PyObject * self)105 PyMethod_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]
126 method.__reduce__
127 [clinic start generated code]*/
128
129 static PyObject *
method___reduce___impl(PyMethodObject * self)130 method___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
143 static 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
154 static 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
167 static PyObject *
method_get_doc(PyMethodObject * im,void * context)168 method_get_doc(PyMethodObject *im, void *context)
169 {
170 return PyObject_GetAttr(im->im_func, &_Py_ID(__doc__));
171 }
172
173 static PyGetSetDef method_getset[] = {
174 {"__doc__", (getter)method_get_doc, NULL, NULL},
175 {0}
176 };
177
178 static PyObject *
method_getattro(PyObject * obj,PyObject * name)179 method_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
208 method.__new__ as method_new
209 function: object
210 instance: object
211 /
212
213 Create a bound instance method object.
214 [clinic start generated code]*/
215
216 static PyObject *
method_new_impl(PyTypeObject * type,PyObject * function,PyObject * instance)217 method_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
234 static void
method_dealloc(PyMethodObject * im)235 method_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
245 static PyObject *
method_richcompare(PyObject * self,PyObject * other,int op)246 method_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
274 static PyObject *
method_repr(PyMethodObject * a)275 method_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
302 static Py_hash_t
method_hash(PyMethodObject * a)303 method_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
316 static int
method_traverse(PyMethodObject * im,visitproc visit,void * arg)317 method_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
324 PyTypeObject 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]
352 class instancemethod "PyInstanceMethodObject *" "&PyInstanceMethod_Type"
353 [clinic start generated code]*/
354 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=28c9762a9016f4d2]*/
355
356 PyObject *
PyInstanceMethod_New(PyObject * func)357 PyInstanceMethod_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
368 PyObject *
PyInstanceMethod_Function(PyObject * im)369 PyInstanceMethod_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
380 static 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
386 static PyObject *
instancemethod_get_doc(PyObject * self,void * context)387 instancemethod_get_doc(PyObject *self, void *context)
388 {
389 return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self),
390 &_Py_ID(__doc__));
391 }
392
393 static PyGetSetDef instancemethod_getset[] = {
394 {"__doc__", (getter)instancemethod_get_doc, NULL, NULL},
395 {0}
396 };
397
398 static PyObject *
instancemethod_getattro(PyObject * self,PyObject * name)399 instancemethod_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
423 static void
instancemethod_dealloc(PyObject * self)424 instancemethod_dealloc(PyObject *self) {
425 _PyObject_GC_UNTRACK(self);
426 Py_DECREF(PyInstanceMethod_GET_FUNCTION(self));
427 PyObject_GC_Del(self);
428 }
429
430 static int
instancemethod_traverse(PyObject * self,visitproc visit,void * arg)431 instancemethod_traverse(PyObject *self, visitproc visit, void *arg) {
432 Py_VISIT(PyInstanceMethod_GET_FUNCTION(self));
433 return 0;
434 }
435
436 static PyObject *
instancemethod_call(PyObject * self,PyObject * arg,PyObject * kw)437 instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw)
438 {
439 return PyObject_Call(PyInstanceMethod_GET_FUNCTION(self), arg, kw);
440 }
441
442 static PyObject *
instancemethod_descr_get(PyObject * descr,PyObject * obj,PyObject * type)443 instancemethod_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
453 static PyObject *
instancemethod_richcompare(PyObject * self,PyObject * other,int op)454 instancemethod_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
479 static PyObject *
instancemethod_repr(PyObject * self)480 instancemethod_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
508 instancemethod.__new__ as instancemethod_new
509 function: object
510 /
511
512 Bind a function to a class.
513 [clinic start generated code]*/
514
515 static PyObject *
instancemethod_new_impl(PyTypeObject * type,PyObject * function)516 instancemethod_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
528 PyTypeObject 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