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