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 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 *
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 *
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 assert(nargs == 0 || args[nargs-1]);
52
53 PyObject *result;
54 if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) {
55 /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */
56 PyObject **newargs = (PyObject**)args - 1;
57 nargs += 1;
58 PyObject *tmp = newargs[0];
59 newargs[0] = self;
60 assert(newargs[nargs-1]);
61 result = _PyObject_VectorcallTstate(tstate, func, newargs,
62 nargs, kwnames);
63 newargs[0] = tmp;
64 }
65 else {
66 Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames);
67 Py_ssize_t totalargs = nargs + nkwargs;
68 if (totalargs == 0) {
69 return _PyObject_VectorcallTstate(tstate, func, &self, 1, NULL);
70 }
71
72 PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK];
73 PyObject **newargs;
74 if (totalargs <= (Py_ssize_t)Py_ARRAY_LENGTH(newargs_stack) - 1) {
75 newargs = newargs_stack;
76 }
77 else {
78 newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *));
79 if (newargs == NULL) {
80 _PyErr_NoMemory(tstate);
81 return NULL;
82 }
83 }
84 /* use borrowed references */
85 newargs[0] = self;
86 /* bpo-37138: since totalargs > 0, it's impossible that args is NULL.
87 * We need this, since calling memcpy() with a NULL pointer is
88 * undefined behaviour. */
89 assert(args != NULL);
90 memcpy(newargs + 1, args, totalargs * sizeof(PyObject *));
91 result = _PyObject_VectorcallTstate(tstate, func,
92 newargs, nargs+1, kwnames);
93 if (newargs != newargs_stack) {
94 PyMem_Free(newargs);
95 }
96 }
97 return result;
98 }
99
100
101 /* Method objects are used for bound instance methods returned by
102 instancename.methodname. ClassName.methodname returns an ordinary
103 function.
104 */
105
106 PyObject *
107 PyMethod_New(PyObject *func, PyObject *self)
108 {
109 if (self == NULL) {
110 PyErr_BadInternalCall();
111 return NULL;
112 }
113 PyMethodObject *im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
114 if (im == NULL) {
115 return NULL;
116 }
117 im->im_weakreflist = NULL;
118 im->im_func = Py_NewRef(func);
119 im->im_self = Py_NewRef(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 *
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 *
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 *
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 (!_PyType_IsReady(tp)) {
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 return Py_NewRef(descr);
199 }
200 }
201
202 return PyObject_GetAttr(im->im_func, name);
203 }
204
205 /*[clinic input]
206 @classmethod
207 method.__new__ as method_new
208 function: object
209 instance: object
210 /
211
212 Create a bound instance method object.
213 [clinic start generated code]*/
214
215 static PyObject *
216 method_new_impl(PyTypeObject *type, PyObject *function, PyObject *instance)
217 /*[clinic end generated code: output=d33ef4ebf702e1f7 input=4e32facc3c3108ae]*/
218 {
219 if (!PyCallable_Check(function)) {
220 PyErr_SetString(PyExc_TypeError,
221 "first argument must be callable");
222 return NULL;
223 }
224 if (instance == NULL || instance == Py_None) {
225 PyErr_SetString(PyExc_TypeError,
226 "instance must not be None");
227 return NULL;
228 }
229
230 return PyMethod_New(function, instance);
231 }
232
233 static void
234 method_dealloc(PyMethodObject *im)
235 {
236 _PyObject_GC_UNTRACK(im);
237 if (im->im_weakreflist != NULL)
238 PyObject_ClearWeakRefs((PyObject *)im);
239 Py_DECREF(im->im_func);
240 Py_XDECREF(im->im_self);
241 PyObject_GC_Del(im);
242 }
243
244 static PyObject *
245 method_richcompare(PyObject *self, PyObject *other, int op)
246 {
247 PyMethodObject *a, *b;
248 PyObject *res;
249 int eq;
250
251 if ((op != Py_EQ && op != Py_NE) ||
252 !PyMethod_Check(self) ||
253 !PyMethod_Check(other))
254 {
255 Py_RETURN_NOTIMPLEMENTED;
256 }
257 a = (PyMethodObject *)self;
258 b = (PyMethodObject *)other;
259 eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ);
260 if (eq == 1) {
261 eq = (a->im_self == b->im_self);
262 }
263 else if (eq < 0)
264 return NULL;
265 if (op == Py_EQ)
266 res = eq ? Py_True : Py_False;
267 else
268 res = eq ? Py_False : Py_True;
269 return Py_NewRef(res);
270 }
271
272 static PyObject *
273 method_repr(PyMethodObject *a)
274 {
275 PyObject *self = a->im_self;
276 PyObject *func = a->im_func;
277 PyObject *funcname, *result;
278 const char *defname = "?";
279
280 if (_PyObject_LookupAttr(func, &_Py_ID(__qualname__), &funcname) < 0 ||
281 (funcname == NULL &&
282 _PyObject_LookupAttr(func, &_Py_ID(__name__), &funcname) < 0))
283 {
284 return NULL;
285 }
286
287 if (funcname != NULL && !PyUnicode_Check(funcname)) {
288 Py_SETREF(funcname, NULL);
289 }
290
291 /* XXX Shouldn't use repr()/%R here! */
292 result = PyUnicode_FromFormat("<bound method %V of %R>",
293 funcname, defname, self);
294
295 Py_XDECREF(funcname);
296 return result;
297 }
298
299 static Py_hash_t
300 method_hash(PyMethodObject *a)
301 {
302 Py_hash_t x, y;
303 x = _Py_HashPointer(a->im_self);
304 y = PyObject_Hash(a->im_func);
305 if (y == -1)
306 return -1;
307 x = x ^ y;
308 if (x == -1)
309 x = -2;
310 return x;
311 }
312
313 static int
314 method_traverse(PyMethodObject *im, visitproc visit, void *arg)
315 {
316 Py_VISIT(im->im_func);
317 Py_VISIT(im->im_self);
318 return 0;
319 }
320
321 PyTypeObject PyMethod_Type = {
322 PyVarObject_HEAD_INIT(&PyType_Type, 0)
323 .tp_name = "method",
324 .tp_basicsize = sizeof(PyMethodObject),
325 .tp_dealloc = (destructor)method_dealloc,
326 .tp_vectorcall_offset = offsetof(PyMethodObject, vectorcall),
327 .tp_repr = (reprfunc)method_repr,
328 .tp_hash = (hashfunc)method_hash,
329 .tp_call = PyVectorcall_Call,
330 .tp_getattro = method_getattro,
331 .tp_setattro = PyObject_GenericSetAttr,
332 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
333 Py_TPFLAGS_HAVE_VECTORCALL,
334 .tp_doc = method_new__doc__,
335 .tp_traverse = (traverseproc)method_traverse,
336 .tp_richcompare = method_richcompare,
337 .tp_weaklistoffset = offsetof(PyMethodObject, im_weakreflist),
338 .tp_methods = method_methods,
339 .tp_members = method_memberlist,
340 .tp_getset = method_getset,
341 .tp_new = method_new,
342 };
343
344 /* ------------------------------------------------------------------------
345 * instance method
346 */
347
348 /*[clinic input]
349 class instancemethod "PyInstanceMethodObject *" "&PyInstanceMethod_Type"
350 [clinic start generated code]*/
351 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=28c9762a9016f4d2]*/
352
353 PyObject *
354 PyInstanceMethod_New(PyObject *func) {
355 PyInstanceMethodObject *method;
356 method = PyObject_GC_New(PyInstanceMethodObject,
357 &PyInstanceMethod_Type);
358 if (method == NULL) return NULL;
359 method->func = Py_NewRef(func);
360 _PyObject_GC_TRACK(method);
361 return (PyObject *)method;
362 }
363
364 PyObject *
365 PyInstanceMethod_Function(PyObject *im)
366 {
367 if (!PyInstanceMethod_Check(im)) {
368 PyErr_BadInternalCall();
369 return NULL;
370 }
371 return PyInstanceMethod_GET_FUNCTION(im);
372 }
373
374 #define IMO_OFF(x) offsetof(PyInstanceMethodObject, x)
375
376 static PyMemberDef instancemethod_memberlist[] = {
377 {"__func__", T_OBJECT, IMO_OFF(func), READONLY,
378 "the function (or other callable) implementing a method"},
379 {NULL} /* Sentinel */
380 };
381
382 static PyObject *
383 instancemethod_get_doc(PyObject *self, void *context)
384 {
385 return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self),
386 &_Py_ID(__doc__));
387 }
388
389 static PyGetSetDef instancemethod_getset[] = {
390 {"__doc__", (getter)instancemethod_get_doc, NULL, NULL},
391 {0}
392 };
393
394 static PyObject *
395 instancemethod_getattro(PyObject *self, PyObject *name)
396 {
397 PyTypeObject *tp = Py_TYPE(self);
398 PyObject *descr = NULL;
399
400 if (!_PyType_IsReady(tp)) {
401 if (PyType_Ready(tp) < 0)
402 return NULL;
403 }
404 descr = _PyType_Lookup(tp, name);
405
406 if (descr != NULL) {
407 descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr));
408 if (f != NULL)
409 return f(descr, self, (PyObject *)Py_TYPE(self));
410 else {
411 return Py_NewRef(descr);
412 }
413 }
414
415 return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name);
416 }
417
418 static void
419 instancemethod_dealloc(PyObject *self) {
420 _PyObject_GC_UNTRACK(self);
421 Py_DECREF(PyInstanceMethod_GET_FUNCTION(self));
422 PyObject_GC_Del(self);
423 }
424
425 static int
426 instancemethod_traverse(PyObject *self, visitproc visit, void *arg) {
427 Py_VISIT(PyInstanceMethod_GET_FUNCTION(self));
428 return 0;
429 }
430
431 static PyObject *
432 instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw)
433 {
434 return PyObject_Call(PyInstanceMethod_GET_FUNCTION(self), arg, kw);
435 }
436
437 static PyObject *
438 instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) {
439 PyObject *func = PyInstanceMethod_GET_FUNCTION(descr);
440 if (obj == NULL) {
441 return Py_NewRef(func);
442 }
443 else
444 return PyMethod_New(func, obj);
445 }
446
447 static PyObject *
448 instancemethod_richcompare(PyObject *self, PyObject *other, int op)
449 {
450 PyInstanceMethodObject *a, *b;
451 PyObject *res;
452 int eq;
453
454 if ((op != Py_EQ && op != Py_NE) ||
455 !PyInstanceMethod_Check(self) ||
456 !PyInstanceMethod_Check(other))
457 {
458 Py_RETURN_NOTIMPLEMENTED;
459 }
460 a = (PyInstanceMethodObject *)self;
461 b = (PyInstanceMethodObject *)other;
462 eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ);
463 if (eq < 0)
464 return NULL;
465 if (op == Py_EQ)
466 res = eq ? Py_True : Py_False;
467 else
468 res = eq ? Py_False : Py_True;
469 return Py_NewRef(res);
470 }
471
472 static PyObject *
473 instancemethod_repr(PyObject *self)
474 {
475 PyObject *func = PyInstanceMethod_Function(self);
476 PyObject *funcname, *result;
477 const char *defname = "?";
478
479 if (func == NULL) {
480 PyErr_BadInternalCall();
481 return NULL;
482 }
483
484 if (_PyObject_LookupAttr(func, &_Py_ID(__name__), &funcname) < 0) {
485 return NULL;
486 }
487 if (funcname != NULL && !PyUnicode_Check(funcname)) {
488 Py_SETREF(funcname, NULL);
489 }
490
491 result = PyUnicode_FromFormat("<instancemethod %V at %p>",
492 funcname, defname, self);
493
494 Py_XDECREF(funcname);
495 return result;
496 }
497
498 /*[clinic input]
499 @classmethod
500 instancemethod.__new__ as instancemethod_new
501 function: object
502 /
503
504 Bind a function to a class.
505 [clinic start generated code]*/
506
507 static PyObject *
508 instancemethod_new_impl(PyTypeObject *type, PyObject *function)
509 /*[clinic end generated code: output=5e0397b2bdb750be input=cfc54e8b973664a8]*/
510 {
511 if (!PyCallable_Check(function)) {
512 PyErr_SetString(PyExc_TypeError,
513 "first argument must be callable");
514 return NULL;
515 }
516
517 return PyInstanceMethod_New(function);
518 }
519
520 PyTypeObject PyInstanceMethod_Type = {
521 PyVarObject_HEAD_INIT(&PyType_Type, 0)
522 .tp_name = "instancemethod",
523 .tp_basicsize = sizeof(PyInstanceMethodObject),
524 .tp_dealloc = instancemethod_dealloc,
525 .tp_repr = (reprfunc)instancemethod_repr,
526 .tp_call = instancemethod_call,
527 .tp_getattro = instancemethod_getattro,
528 .tp_setattro = PyObject_GenericSetAttr,
529 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
530 .tp_doc = instancemethod_new__doc__,
531 .tp_traverse = instancemethod_traverse,
532 .tp_richcompare = instancemethod_richcompare,
533 .tp_members = instancemethod_memberlist,
534 .tp_getset = instancemethod_getset,
535 .tp_descr_get = instancemethod_descr_get,
536 .tp_new = instancemethod_new,
537 };