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 9998710 : method_vectorcall(PyObject *method, PyObject *const *args,
43 : size_t nargsf, PyObject *kwnames)
44 : {
45 9998710 : assert(Py_IS_TYPE(method, &PyMethod_Type));
46 :
47 9998710 : PyThreadState *tstate = _PyThreadState_GET();
48 9998710 : PyObject *self = PyMethod_GET_SELF(method);
49 9998710 : PyObject *func = PyMethod_GET_FUNCTION(method);
50 9998710 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
51 :
52 : PyObject *result;
53 9998710 : if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) {
54 : /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */
55 3855030 : PyObject **newargs = (PyObject**)args - 1;
56 3855030 : nargs += 1;
57 3855030 : PyObject *tmp = newargs[0];
58 3855030 : newargs[0] = self;
59 3855030 : result = _PyObject_VectorcallTstate(tstate, func, newargs,
60 : nargs, kwnames);
61 3855030 : newargs[0] = tmp;
62 : }
63 : else {
64 6143680 : Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames);
65 6143680 : Py_ssize_t totalargs = nargs + nkwargs;
66 6143680 : if (totalargs == 0) {
67 3041100 : return _PyObject_VectorcallTstate(tstate, func, &self, 1, NULL);
68 : }
69 :
70 : PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK];
71 : PyObject **newargs;
72 3102580 : if (totalargs <= (Py_ssize_t)Py_ARRAY_LENGTH(newargs_stack) - 1) {
73 3024350 : newargs = newargs_stack;
74 : }
75 : else {
76 78234 : newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *));
77 78234 : if (newargs == NULL) {
78 0 : _PyErr_NoMemory(tstate);
79 0 : return NULL;
80 : }
81 : }
82 : /* use borrowed references */
83 3102580 : 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 3102580 : assert(args != NULL);
88 3102580 : memcpy(newargs + 1, args, totalargs * sizeof(PyObject *));
89 3102580 : result = _PyObject_VectorcallTstate(tstate, func,
90 3102580 : newargs, nargs+1, kwnames);
91 3102540 : if (newargs != newargs_stack) {
92 78234 : PyMem_Free(newargs);
93 : }
94 : }
95 6957570 : 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 27823600 : PyMethod_New(PyObject *func, PyObject *self)
106 : {
107 27823600 : if (self == NULL) {
108 0 : PyErr_BadInternalCall();
109 0 : return NULL;
110 : }
111 27823600 : PyMethodObject *im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
112 27823600 : if (im == NULL) {
113 0 : return NULL;
114 : }
115 27823600 : im->im_weakreflist = NULL;
116 27823600 : Py_INCREF(func);
117 27823600 : im->im_func = func;
118 27823600 : Py_INCREF(self);
119 27823600 : im->im_self = self;
120 27823600 : im->vectorcall = method_vectorcall;
121 27823600 : _PyObject_GC_TRACK(im);
122 27823600 : 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 215301 : method_get_doc(PyMethodObject *im, void *context)
169 : {
170 215301 : 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 341905 : method_getattro(PyObject *obj, PyObject *name)
180 : {
181 341905 : PyMethodObject *im = (PyMethodObject *)obj;
182 341905 : PyTypeObject *tp = Py_TYPE(obj);
183 341905 : PyObject *descr = NULL;
184 :
185 : {
186 341905 : if (tp->tp_dict == NULL) {
187 0 : if (PyType_Ready(tp) < 0)
188 0 : return NULL;
189 : }
190 341905 : descr = _PyType_Lookup(tp, name);
191 : }
192 :
193 341905 : if (descr != NULL) {
194 230010 : descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr));
195 230010 : if (f != NULL)
196 229950 : return f(descr, obj, (PyObject *)Py_TYPE(obj));
197 : else {
198 60 : Py_INCREF(descr);
199 60 : return descr;
200 : }
201 : }
202 :
203 111895 : 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 1006 : method_new_impl(PyTypeObject *type, PyObject *function, PyObject *instance)
218 : /*[clinic end generated code: output=d33ef4ebf702e1f7 input=4e32facc3c3108ae]*/
219 : {
220 1006 : if (!PyCallable_Check(function)) {
221 0 : PyErr_SetString(PyExc_TypeError,
222 : "first argument must be callable");
223 0 : return NULL;
224 : }
225 1006 : 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 1006 : return PyMethod_New(function, instance);
232 : }
233 :
234 : static void
235 27823300 : method_dealloc(PyMethodObject *im)
236 : {
237 27823300 : _PyObject_GC_UNTRACK(im);
238 27823300 : if (im->im_weakreflist != NULL)
239 1 : PyObject_ClearWeakRefs((PyObject *)im);
240 27823300 : Py_DECREF(im->im_func);
241 27823300 : Py_XDECREF(im->im_self);
242 27823300 : PyObject_GC_Del(im);
243 27823300 : }
244 :
245 : static PyObject *
246 79 : method_richcompare(PyObject *self, PyObject *other, int op)
247 : {
248 : PyMethodObject *a, *b;
249 : PyObject *res;
250 : int eq;
251 :
252 150 : if ((op != Py_EQ && op != Py_NE) ||
253 142 : !PyMethod_Check(self) ||
254 71 : !PyMethod_Check(other))
255 : {
256 12 : Py_RETURN_NOTIMPLEMENTED;
257 : }
258 67 : a = (PyMethodObject *)self;
259 67 : b = (PyMethodObject *)other;
260 67 : eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ);
261 67 : if (eq == 1) {
262 65 : eq = (a->im_self == b->im_self);
263 : }
264 2 : else if (eq < 0)
265 0 : return NULL;
266 67 : if (op == Py_EQ)
267 34 : res = eq ? Py_True : Py_False;
268 : else
269 33 : res = eq ? Py_False : Py_True;
270 67 : Py_INCREF(res);
271 67 : return res;
272 : }
273 :
274 : static PyObject *
275 1796 : method_repr(PyMethodObject *a)
276 : {
277 1796 : PyObject *self = a->im_self;
278 1796 : PyObject *func = a->im_func;
279 : PyObject *funcname, *result;
280 1796 : const char *defname = "?";
281 :
282 1796 : if (_PyObject_LookupAttr(func, &_Py_ID(__qualname__), &funcname) < 0 ||
283 1799 : (funcname == NULL &&
284 3 : _PyObject_LookupAttr(func, &_Py_ID(__name__), &funcname) < 0))
285 : {
286 0 : return NULL;
287 : }
288 :
289 1796 : 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 1796 : result = PyUnicode_FromFormat("<bound method %V of %R>",
296 : funcname, defname, self);
297 :
298 1796 : Py_XDECREF(funcname);
299 1796 : return result;
300 : }
301 :
302 : static Py_hash_t
303 100 : method_hash(PyMethodObject *a)
304 : {
305 : Py_hash_t x, y;
306 100 : x = _Py_HashPointer(a->im_self);
307 100 : y = PyObject_Hash(a->im_func);
308 100 : if (y == -1)
309 0 : return -1;
310 100 : x = x ^ y;
311 100 : if (x == -1)
312 0 : x = -2;
313 100 : return x;
314 : }
315 :
316 : static int
317 7823080 : method_traverse(PyMethodObject *im, visitproc visit, void *arg)
318 : {
319 7823080 : Py_VISIT(im->im_func);
320 7823070 : Py_VISIT(im->im_self);
321 7823070 : 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 208 : instancemethod_traverse(PyObject *self, visitproc visit, void *arg) {
432 208 : Py_VISIT(PyInstanceMethod_GET_FUNCTION(self));
433 208 : 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 : };
|