Branch data Line data Source code
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 *
21 : 0 : PyMethod_Function(PyObject *im)
22 : : {
23 [ # # ]: 0 : if (!PyMethod_Check(im)) {
24 : 0 : PyErr_BadInternalCall();
25 : 0 : return NULL;
26 : : }
27 : 0 : return ((PyMethodObject *)im)->im_func;
28 : : }
29 : :
30 : : PyObject *
31 : 0 : PyMethod_Self(PyObject *im)
32 : : {
33 [ # # ]: 0 : if (!PyMethod_Check(im)) {
34 : 0 : PyErr_BadInternalCall();
35 : 0 : return NULL;
36 : : }
37 : 0 : return ((PyMethodObject *)im)->im_self;
38 : : }
39 : :
40 : :
41 : : static PyObject *
42 : 9971829 : method_vectorcall(PyObject *method, PyObject *const *args,
43 : : size_t nargsf, PyObject *kwnames)
44 : : {
45 : : assert(Py_IS_TYPE(method, &PyMethod_Type));
46 : :
47 : 9971829 : PyThreadState *tstate = _PyThreadState_GET();
48 : 9971829 : PyObject *self = PyMethod_GET_SELF(method);
49 : 9971829 : PyObject *func = PyMethod_GET_FUNCTION(method);
50 : 9971829 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
51 : :
52 : : PyObject *result;
53 [ + + ]: 9971829 : if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) {
54 : : /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */
55 : 3792957 : PyObject **newargs = (PyObject**)args - 1;
56 : 3792957 : nargs += 1;
57 : 3792957 : PyObject *tmp = newargs[0];
58 : 3792957 : newargs[0] = self;
59 : 3792957 : result = _PyObject_VectorcallTstate(tstate, func, newargs,
60 : : nargs, kwnames);
61 : 3792957 : newargs[0] = tmp;
62 : : }
63 : : else {
64 [ + + ]: 6178872 : Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames);
65 : 6178872 : Py_ssize_t totalargs = nargs + nkwargs;
66 [ + + ]: 6178872 : if (totalargs == 0) {
67 : 2980068 : return _PyObject_VectorcallTstate(tstate, func, &self, 1, NULL);
68 : : }
69 : :
70 : : PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK];
71 : : PyObject **newargs;
72 [ + + ]: 3198804 : if (totalargs <= (Py_ssize_t)Py_ARRAY_LENGTH(newargs_stack) - 1) {
73 : 3084977 : newargs = newargs_stack;
74 : : }
75 : : else {
76 : 113827 : newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *));
77 [ - + ]: 113827 : if (newargs == NULL) {
78 : : _PyErr_NoMemory(tstate);
79 : 0 : return NULL;
80 : : }
81 : : }
82 : : /* use borrowed references */
83 : 3198804 : 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 : 3198804 : memcpy(newargs + 1, args, totalargs * sizeof(PyObject *));
89 : 3198804 : result = _PyObject_VectorcallTstate(tstate, func,
90 : 3198804 : newargs, nargs+1, kwnames);
91 [ + + ]: 3198761 : if (newargs != newargs_stack) {
92 : 113827 : PyMem_Free(newargs);
93 : : }
94 : : }
95 : 6991718 : 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 *
105 : 27469083 : PyMethod_New(PyObject *func, PyObject *self)
106 : : {
107 [ - + ]: 27469083 : if (self == NULL) {
108 : 0 : PyErr_BadInternalCall();
109 : 0 : return NULL;
110 : : }
111 : 27469083 : PyMethodObject *im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
112 [ - + ]: 27469083 : if (im == NULL) {
113 : 0 : return NULL;
114 : : }
115 : 27469083 : im->im_weakreflist = NULL;
116 : 27469083 : Py_INCREF(func);
117 : 27469083 : im->im_func = func;
118 : 27469083 : Py_INCREF(self);
119 : 27469083 : im->im_self = self;
120 : 27469083 : im->vectorcall = method_vectorcall;
121 : 27469083 : _PyObject_GC_TRACK(im);
122 : 27469083 : return (PyObject *)im;
123 : : }
124 : :
125 : : /*[clinic input]
126 : : method.__reduce__
127 : : [clinic start generated code]*/
128 : :
129 : : static PyObject *
130 : 574 : method___reduce___impl(PyMethodObject *self)
131 : : /*[clinic end generated code: output=6c04506d0fa6fdcb input=143a0bf5e96de6e8]*/
132 : : {
133 : 574 : PyObject *funcself = PyMethod_GET_SELF(self);
134 : 574 : PyObject *func = PyMethod_GET_FUNCTION(self);
135 : 574 : PyObject *funcname = PyObject_GetAttr(func, &_Py_ID(__name__));
136 [ - + ]: 574 : if (funcname == NULL) {
137 : 0 : return NULL;
138 : : }
139 : 574 : 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 *
168 : 214889 : method_get_doc(PyMethodObject *im, void *context)
169 : : {
170 : 214889 : 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 *
179 : 341530 : method_getattro(PyObject *obj, PyObject *name)
180 : : {
181 : 341530 : PyMethodObject *im = (PyMethodObject *)obj;
182 : 341530 : PyTypeObject *tp = Py_TYPE(obj);
183 : 341530 : PyObject *descr = NULL;
184 : :
185 : : {
186 [ - + ]: 341530 : if (tp->tp_dict == NULL) {
187 [ # # ]: 0 : if (PyType_Ready(tp) < 0)
188 : 0 : return NULL;
189 : : }
190 : 341530 : descr = _PyType_Lookup(tp, name);
191 : : }
192 : :
193 [ + + ]: 341530 : if (descr != NULL) {
194 : 229572 : descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr));
195 [ + + ]: 229572 : if (f != NULL)
196 : 229512 : return f(descr, obj, (PyObject *)Py_TYPE(obj));
197 : : else {
198 : 60 : Py_INCREF(descr);
199 : 60 : return descr;
200 : : }
201 : : }
202 : :
203 : 111958 : 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 *
217 : 1004 : method_new_impl(PyTypeObject *type, PyObject *function, PyObject *instance)
218 : : /*[clinic end generated code: output=d33ef4ebf702e1f7 input=4e32facc3c3108ae]*/
219 : : {
220 [ - + ]: 1004 : if (!PyCallable_Check(function)) {
221 : 0 : PyErr_SetString(PyExc_TypeError,
222 : : "first argument must be callable");
223 : 0 : return NULL;
224 : : }
225 [ + - - + ]: 1004 : if (instance == NULL || instance == Py_None) {
226 : 0 : PyErr_SetString(PyExc_TypeError,
227 : : "instance must not be None");
228 : 0 : return NULL;
229 : : }
230 : :
231 : 1004 : return PyMethod_New(function, instance);
232 : : }
233 : :
234 : : static void
235 : 27468716 : method_dealloc(PyMethodObject *im)
236 : : {
237 : 27468716 : _PyObject_GC_UNTRACK(im);
238 [ + + ]: 27468716 : if (im->im_weakreflist != NULL)
239 : 1 : PyObject_ClearWeakRefs((PyObject *)im);
240 : 27468716 : Py_DECREF(im->im_func);
241 : 27468716 : Py_XDECREF(im->im_self);
242 : 27468716 : PyObject_GC_Del(im);
243 : 27468716 : }
244 : :
245 : : static PyObject *
246 : 77 : method_richcompare(PyObject *self, PyObject *other, int op)
247 : : {
248 : : PyMethodObject *a, *b;
249 : : PyObject *res;
250 : : int eq;
251 : :
252 [ + + + + : 146 : if ((op != Py_EQ && op != Py_NE) ||
+ - ]
253 [ + + ]: 138 : !PyMethod_Check(self) ||
254 : 69 : !PyMethod_Check(other))
255 : : {
256 : 12 : Py_RETURN_NOTIMPLEMENTED;
257 : : }
258 : 65 : a = (PyMethodObject *)self;
259 : 65 : b = (PyMethodObject *)other;
260 : 65 : eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ);
261 [ + + ]: 65 : if (eq == 1) {
262 : 63 : eq = (a->im_self == b->im_self);
263 : : }
264 [ - + ]: 2 : else if (eq < 0)
265 : 0 : return NULL;
266 [ + + ]: 65 : if (op == Py_EQ)
267 [ + + ]: 32 : res = eq ? Py_True : Py_False;
268 : : else
269 [ + + ]: 33 : res = eq ? Py_False : Py_True;
270 : 65 : Py_INCREF(res);
271 : 65 : return res;
272 : : }
273 : :
274 : : static PyObject *
275 : 1809 : method_repr(PyMethodObject *a)
276 : : {
277 : 1809 : PyObject *self = a->im_self;
278 : 1809 : PyObject *func = a->im_func;
279 : : PyObject *funcname, *result;
280 : 1809 : const char *defname = "?";
281 : :
282 [ + - ]: 1809 : if (_PyObject_LookupAttr(func, &_Py_ID(__qualname__), &funcname) < 0 ||
283 [ + + - + ]: 1812 : (funcname == NULL &&
284 : 3 : _PyObject_LookupAttr(func, &_Py_ID(__name__), &funcname) < 0))
285 : : {
286 : 0 : return NULL;
287 : : }
288 : :
289 [ + + - + ]: 1809 : if (funcname != NULL && !PyUnicode_Check(funcname)) {
290 : 0 : Py_DECREF(funcname);
291 : 0 : funcname = NULL;
292 : : }
293 : :
294 : : /* XXX Shouldn't use repr()/%R here! */
295 : 1809 : result = PyUnicode_FromFormat("<bound method %V of %R>",
296 : : funcname, defname, self);
297 : :
298 : 1809 : Py_XDECREF(funcname);
299 : 1809 : return result;
300 : : }
301 : :
302 : : static Py_hash_t
303 : 101 : method_hash(PyMethodObject *a)
304 : : {
305 : : Py_hash_t x, y;
306 : 101 : x = _Py_HashPointer(a->im_self);
307 : 101 : y = PyObject_Hash(a->im_func);
308 [ - + ]: 101 : if (y == -1)
309 : 0 : return -1;
310 : 101 : x = x ^ y;
311 [ - + ]: 101 : if (x == -1)
312 : 0 : x = -2;
313 : 101 : return x;
314 : : }
315 : :
316 : : static int
317 : 7578809 : method_traverse(PyMethodObject *im, visitproc visit, void *arg)
318 : : {
319 [ + - + + ]: 7578809 : Py_VISIT(im->im_func);
320 [ + - - + ]: 7578801 : Py_VISIT(im->im_self);
321 : 7578801 : 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 *
357 : 2 : PyInstanceMethod_New(PyObject *func) {
358 : : PyInstanceMethodObject *method;
359 : 2 : method = PyObject_GC_New(PyInstanceMethodObject,
360 : : &PyInstanceMethod_Type);
361 [ - + ]: 2 : if (method == NULL) return NULL;
362 : 2 : Py_INCREF(func);
363 : 2 : method->func = func;
364 : 2 : _PyObject_GC_TRACK(method);
365 : 2 : return (PyObject *)method;
366 : : }
367 : :
368 : : PyObject *
369 : 0 : PyInstanceMethod_Function(PyObject *im)
370 : : {
371 [ # # ]: 0 : if (!PyInstanceMethod_Check(im)) {
372 : 0 : PyErr_BadInternalCall();
373 : 0 : return NULL;
374 : : }
375 : 0 : 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 *
387 : 0 : instancemethod_get_doc(PyObject *self, void *context)
388 : : {
389 : 0 : 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 *
399 : 0 : instancemethod_getattro(PyObject *self, PyObject *name)
400 : : {
401 : 0 : PyTypeObject *tp = Py_TYPE(self);
402 : 0 : PyObject *descr = NULL;
403 : :
404 [ # # ]: 0 : if (tp->tp_dict == NULL) {
405 [ # # ]: 0 : if (PyType_Ready(tp) < 0)
406 : 0 : return NULL;
407 : : }
408 : 0 : descr = _PyType_Lookup(tp, name);
409 : :
410 [ # # ]: 0 : if (descr != NULL) {
411 : 0 : descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr));
412 [ # # ]: 0 : if (f != NULL)
413 : 0 : return f(descr, self, (PyObject *)Py_TYPE(self));
414 : : else {
415 : 0 : Py_INCREF(descr);
416 : 0 : return descr;
417 : : }
418 : : }
419 : :
420 : 0 : return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name);
421 : : }
422 : :
423 : : static void
424 : 2 : instancemethod_dealloc(PyObject *self) {
425 : 2 : _PyObject_GC_UNTRACK(self);
426 : 2 : Py_DECREF(PyInstanceMethod_GET_FUNCTION(self));
427 : 2 : PyObject_GC_Del(self);
428 : 2 : }
429 : :
430 : : static int
431 : 200 : instancemethod_traverse(PyObject *self, visitproc visit, void *arg) {
432 [ + - - + ]: 200 : Py_VISIT(PyInstanceMethod_GET_FUNCTION(self));
433 : 200 : return 0;
434 : : }
435 : :
436 : : static PyObject *
437 : 0 : instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw)
438 : : {
439 : 0 : return PyObject_Call(PyInstanceMethod_GET_FUNCTION(self), arg, kw);
440 : : }
441 : :
442 : : static PyObject *
443 : 6 : instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) {
444 : 6 : PyObject *func = PyInstanceMethod_GET_FUNCTION(descr);
445 [ + + ]: 6 : if (obj == NULL) {
446 : 2 : Py_INCREF(func);
447 : 2 : return func;
448 : : }
449 : : else
450 : 4 : return PyMethod_New(func, obj);
451 : : }
452 : :
453 : : static PyObject *
454 : 0 : instancemethod_richcompare(PyObject *self, PyObject *other, int op)
455 : : {
456 : : PyInstanceMethodObject *a, *b;
457 : : PyObject *res;
458 : : int eq;
459 : :
460 [ # # # # : 0 : if ((op != Py_EQ && op != Py_NE) ||
# # ]
461 [ # # ]: 0 : !PyInstanceMethod_Check(self) ||
462 : 0 : !PyInstanceMethod_Check(other))
463 : : {
464 : 0 : Py_RETURN_NOTIMPLEMENTED;
465 : : }
466 : 0 : a = (PyInstanceMethodObject *)self;
467 : 0 : b = (PyInstanceMethodObject *)other;
468 : 0 : eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ);
469 [ # # ]: 0 : if (eq < 0)
470 : 0 : return NULL;
471 [ # # ]: 0 : if (op == Py_EQ)
472 [ # # ]: 0 : res = eq ? Py_True : Py_False;
473 : : else
474 [ # # ]: 0 : res = eq ? Py_False : Py_True;
475 : 0 : Py_INCREF(res);
476 : 0 : return res;
477 : : }
478 : :
479 : : static PyObject *
480 : 0 : instancemethod_repr(PyObject *self)
481 : : {
482 : 0 : PyObject *func = PyInstanceMethod_Function(self);
483 : : PyObject *funcname, *result;
484 : 0 : const char *defname = "?";
485 : :
486 [ # # ]: 0 : if (func == NULL) {
487 : 0 : PyErr_BadInternalCall();
488 : 0 : return NULL;
489 : : }
490 : :
491 [ # # ]: 0 : if (_PyObject_LookupAttr(func, &_Py_ID(__name__), &funcname) < 0) {
492 : 0 : return NULL;
493 : : }
494 [ # # # # ]: 0 : if (funcname != NULL && !PyUnicode_Check(funcname)) {
495 : 0 : Py_DECREF(funcname);
496 : 0 : funcname = NULL;
497 : : }
498 : :
499 : 0 : result = PyUnicode_FromFormat("<instancemethod %V at %p>",
500 : : funcname, defname, self);
501 : :
502 : 0 : Py_XDECREF(funcname);
503 : 0 : 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 *
516 : 2 : instancemethod_new_impl(PyTypeObject *type, PyObject *function)
517 : : /*[clinic end generated code: output=5e0397b2bdb750be input=cfc54e8b973664a8]*/
518 : : {
519 [ - + ]: 2 : if (!PyCallable_Check(function)) {
520 : 0 : PyErr_SetString(PyExc_TypeError,
521 : : "first argument must be callable");
522 : 0 : return NULL;
523 : : }
524 : :
525 : 2 : 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 : : };
|