1 /* Class object implementation (dead now except for methods) */
2
3 #include "Python.h"
4 #include "pycore_object.h"
5 #include "pycore_pyerrors.h"
6 #include "pycore_pystate.h" // _PyThreadState_GET()
7 #include "structmember.h" // PyMemberDef
8
9 #define TP_DESCR_GET(t) ((t)->tp_descr_get)
10
11 _Py_IDENTIFIER(__name__);
12 _Py_IDENTIFIER(__qualname__);
13
14 PyObject *
PyMethod_Function(PyObject * im)15 PyMethod_Function(PyObject *im)
16 {
17 if (!PyMethod_Check(im)) {
18 PyErr_BadInternalCall();
19 return NULL;
20 }
21 return ((PyMethodObject *)im)->im_func;
22 }
23
24 PyObject *
PyMethod_Self(PyObject * im)25 PyMethod_Self(PyObject *im)
26 {
27 if (!PyMethod_Check(im)) {
28 PyErr_BadInternalCall();
29 return NULL;
30 }
31 return ((PyMethodObject *)im)->im_self;
32 }
33
34
35 static PyObject *
method_vectorcall(PyObject * method,PyObject * const * args,size_t nargsf,PyObject * kwnames)36 method_vectorcall(PyObject *method, PyObject *const *args,
37 size_t nargsf, PyObject *kwnames)
38 {
39 assert(Py_IS_TYPE(method, &PyMethod_Type));
40
41 PyThreadState *tstate = _PyThreadState_GET();
42 PyObject *self = PyMethod_GET_SELF(method);
43 PyObject *func = PyMethod_GET_FUNCTION(method);
44 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
45
46 PyObject *result;
47 if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) {
48 /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */
49 PyObject **newargs = (PyObject**)args - 1;
50 nargs += 1;
51 PyObject *tmp = newargs[0];
52 newargs[0] = self;
53 result = _PyObject_VectorcallTstate(tstate, func, newargs,
54 nargs, kwnames);
55 newargs[0] = tmp;
56 }
57 else {
58 Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames);
59 Py_ssize_t totalargs = nargs + nkwargs;
60 if (totalargs == 0) {
61 return _PyObject_VectorcallTstate(tstate, func, &self, 1, NULL);
62 }
63
64 PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK];
65 PyObject **newargs;
66 if (totalargs <= (Py_ssize_t)Py_ARRAY_LENGTH(newargs_stack) - 1) {
67 newargs = newargs_stack;
68 }
69 else {
70 newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *));
71 if (newargs == NULL) {
72 _PyErr_NoMemory(tstate);
73 return NULL;
74 }
75 }
76 /* use borrowed references */
77 newargs[0] = self;
78 /* bpo-37138: since totalargs > 0, it's impossible that args is NULL.
79 * We need this, since calling memcpy() with a NULL pointer is
80 * undefined behaviour. */
81 assert(args != NULL);
82 memcpy(newargs + 1, args, totalargs * sizeof(PyObject *));
83 result = _PyObject_VectorcallTstate(tstate, func,
84 newargs, nargs+1, kwnames);
85 if (newargs != newargs_stack) {
86 PyMem_Free(newargs);
87 }
88 }
89 return result;
90 }
91
92
93 /* Method objects are used for bound instance methods returned by
94 instancename.methodname. ClassName.methodname returns an ordinary
95 function.
96 */
97
98 PyObject *
PyMethod_New(PyObject * func,PyObject * self)99 PyMethod_New(PyObject *func, PyObject *self)
100 {
101 if (self == NULL) {
102 PyErr_BadInternalCall();
103 return NULL;
104 }
105 PyMethodObject *im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
106 if (im == NULL) {
107 return NULL;
108 }
109 im->im_weakreflist = NULL;
110 Py_INCREF(func);
111 im->im_func = func;
112 Py_INCREF(self);
113 im->im_self = self;
114 im->vectorcall = method_vectorcall;
115 _PyObject_GC_TRACK(im);
116 return (PyObject *)im;
117 }
118
119 static PyObject *
method_reduce(PyMethodObject * im,PyObject * Py_UNUSED (ignored))120 method_reduce(PyMethodObject *im, PyObject *Py_UNUSED(ignored))
121 {
122 PyObject *self = PyMethod_GET_SELF(im);
123 PyObject *func = PyMethod_GET_FUNCTION(im);
124 PyObject *funcname;
125 _Py_IDENTIFIER(getattr);
126
127 funcname = _PyObject_GetAttrId(func, &PyId___name__);
128 if (funcname == NULL) {
129 return NULL;
130 }
131 return Py_BuildValue("N(ON)", _PyEval_GetBuiltinId(&PyId_getattr),
132 self, funcname);
133 }
134
135 static PyMethodDef method_methods[] = {
136 {"__reduce__", (PyCFunction)method_reduce, METH_NOARGS, NULL},
137 {NULL, NULL}
138 };
139
140 /* Descriptors for PyMethod attributes */
141
142 /* im_func and im_self are stored in the PyMethod object */
143
144 #define MO_OFF(x) offsetof(PyMethodObject, x)
145
146 static PyMemberDef method_memberlist[] = {
147 {"__func__", T_OBJECT, MO_OFF(im_func), READONLY,
148 "the function (or other callable) implementing a method"},
149 {"__self__", T_OBJECT, MO_OFF(im_self), READONLY,
150 "the instance to which a method is bound"},
151 {NULL} /* Sentinel */
152 };
153
154 /* Christian Tismer argued convincingly that method attributes should
155 (nearly) always override function attributes.
156 The one exception is __doc__; there's a default __doc__ which
157 should only be used for the class, not for instances */
158
159 static PyObject *
method_get_doc(PyMethodObject * im,void * context)160 method_get_doc(PyMethodObject *im, void *context)
161 {
162 static PyObject *docstr;
163 if (docstr == NULL) {
164 docstr= PyUnicode_InternFromString("__doc__");
165 if (docstr == NULL)
166 return NULL;
167 }
168 return PyObject_GetAttr(im->im_func, docstr);
169 }
170
171 static PyGetSetDef method_getset[] = {
172 {"__doc__", (getter)method_get_doc, NULL, NULL},
173 {0}
174 };
175
176 static PyObject *
method_getattro(PyObject * obj,PyObject * name)177 method_getattro(PyObject *obj, PyObject *name)
178 {
179 PyMethodObject *im = (PyMethodObject *)obj;
180 PyTypeObject *tp = Py_TYPE(obj);
181 PyObject *descr = NULL;
182
183 {
184 if (tp->tp_dict == NULL) {
185 if (PyType_Ready(tp) < 0)
186 return NULL;
187 }
188 descr = _PyType_Lookup(tp, name);
189 }
190
191 if (descr != NULL) {
192 descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr));
193 if (f != NULL)
194 return f(descr, obj, (PyObject *)Py_TYPE(obj));
195 else {
196 Py_INCREF(descr);
197 return descr;
198 }
199 }
200
201 return PyObject_GetAttr(im->im_func, name);
202 }
203
204 PyDoc_STRVAR(method_doc,
205 "method(function, instance)\n\
206 \n\
207 Create a bound instance method object.");
208
209 static PyObject *
method_new(PyTypeObject * type,PyObject * args,PyObject * kw)210 method_new(PyTypeObject* type, PyObject* args, PyObject *kw)
211 {
212 PyObject *func;
213 PyObject *self;
214
215 if (!_PyArg_NoKeywords("method", kw))
216 return NULL;
217 if (!PyArg_UnpackTuple(args, "method", 2, 2,
218 &func, &self))
219 return NULL;
220 if (!PyCallable_Check(func)) {
221 PyErr_SetString(PyExc_TypeError,
222 "first argument must be callable");
223 return NULL;
224 }
225 if (self == NULL || self == Py_None) {
226 PyErr_SetString(PyExc_TypeError,
227 "self must not be None");
228 return NULL;
229 }
230
231 return PyMethod_New(func, self);
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_LookupAttrId(func, &PyId___qualname__, &funcname) < 0 ||
283 (funcname == NULL &&
284 _PyObject_LookupAttrId(func, &PyId___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 static PyObject *
method_descr_get(PyObject * meth,PyObject * obj,PyObject * cls)325 method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls)
326 {
327 Py_INCREF(meth);
328 return meth;
329 }
330
331 PyTypeObject PyMethod_Type = {
332 PyVarObject_HEAD_INIT(&PyType_Type, 0)
333 "method",
334 sizeof(PyMethodObject),
335 0,
336 (destructor)method_dealloc, /* tp_dealloc */
337 offsetof(PyMethodObject, vectorcall), /* tp_vectorcall_offset */
338 0, /* tp_getattr */
339 0, /* tp_setattr */
340 0, /* tp_as_async */
341 (reprfunc)method_repr, /* tp_repr */
342 0, /* tp_as_number */
343 0, /* tp_as_sequence */
344 0, /* tp_as_mapping */
345 (hashfunc)method_hash, /* tp_hash */
346 PyVectorcall_Call, /* tp_call */
347 0, /* tp_str */
348 method_getattro, /* tp_getattro */
349 PyObject_GenericSetAttr, /* tp_setattro */
350 0, /* tp_as_buffer */
351 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
352 Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */
353 method_doc, /* tp_doc */
354 (traverseproc)method_traverse, /* tp_traverse */
355 0, /* tp_clear */
356 method_richcompare, /* tp_richcompare */
357 offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */
358 0, /* tp_iter */
359 0, /* tp_iternext */
360 method_methods, /* tp_methods */
361 method_memberlist, /* tp_members */
362 method_getset, /* tp_getset */
363 0, /* tp_base */
364 0, /* tp_dict */
365 method_descr_get, /* tp_descr_get */
366 0, /* tp_descr_set */
367 0, /* tp_dictoffset */
368 0, /* tp_init */
369 0, /* tp_alloc */
370 method_new, /* tp_new */
371 };
372
373 /* ------------------------------------------------------------------------
374 * instance method
375 */
376
377 PyObject *
PyInstanceMethod_New(PyObject * func)378 PyInstanceMethod_New(PyObject *func) {
379 PyInstanceMethodObject *method;
380 method = PyObject_GC_New(PyInstanceMethodObject,
381 &PyInstanceMethod_Type);
382 if (method == NULL) return NULL;
383 Py_INCREF(func);
384 method->func = func;
385 _PyObject_GC_TRACK(method);
386 return (PyObject *)method;
387 }
388
389 PyObject *
PyInstanceMethod_Function(PyObject * im)390 PyInstanceMethod_Function(PyObject *im)
391 {
392 if (!PyInstanceMethod_Check(im)) {
393 PyErr_BadInternalCall();
394 return NULL;
395 }
396 return PyInstanceMethod_GET_FUNCTION(im);
397 }
398
399 #define IMO_OFF(x) offsetof(PyInstanceMethodObject, x)
400
401 static PyMemberDef instancemethod_memberlist[] = {
402 {"__func__", T_OBJECT, IMO_OFF(func), READONLY,
403 "the function (or other callable) implementing a method"},
404 {NULL} /* Sentinel */
405 };
406
407 static PyObject *
instancemethod_get_doc(PyObject * self,void * context)408 instancemethod_get_doc(PyObject *self, void *context)
409 {
410 static PyObject *docstr;
411 if (docstr == NULL) {
412 docstr = PyUnicode_InternFromString("__doc__");
413 if (docstr == NULL)
414 return NULL;
415 }
416 return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), docstr);
417 }
418
419 static PyGetSetDef instancemethod_getset[] = {
420 {"__doc__", (getter)instancemethod_get_doc, NULL, NULL},
421 {0}
422 };
423
424 static PyObject *
instancemethod_getattro(PyObject * self,PyObject * name)425 instancemethod_getattro(PyObject *self, PyObject *name)
426 {
427 PyTypeObject *tp = Py_TYPE(self);
428 PyObject *descr = NULL;
429
430 if (tp->tp_dict == NULL) {
431 if (PyType_Ready(tp) < 0)
432 return NULL;
433 }
434 descr = _PyType_Lookup(tp, name);
435
436 if (descr != NULL) {
437 descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr));
438 if (f != NULL)
439 return f(descr, self, (PyObject *)Py_TYPE(self));
440 else {
441 Py_INCREF(descr);
442 return descr;
443 }
444 }
445
446 return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name);
447 }
448
449 static void
instancemethod_dealloc(PyObject * self)450 instancemethod_dealloc(PyObject *self) {
451 _PyObject_GC_UNTRACK(self);
452 Py_DECREF(PyInstanceMethod_GET_FUNCTION(self));
453 PyObject_GC_Del(self);
454 }
455
456 static int
instancemethod_traverse(PyObject * self,visitproc visit,void * arg)457 instancemethod_traverse(PyObject *self, visitproc visit, void *arg) {
458 Py_VISIT(PyInstanceMethod_GET_FUNCTION(self));
459 return 0;
460 }
461
462 static PyObject *
instancemethod_call(PyObject * self,PyObject * arg,PyObject * kw)463 instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw)
464 {
465 return PyObject_Call(PyMethod_GET_FUNCTION(self), arg, kw);
466 }
467
468 static PyObject *
instancemethod_descr_get(PyObject * descr,PyObject * obj,PyObject * type)469 instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) {
470 PyObject *func = PyInstanceMethod_GET_FUNCTION(descr);
471 if (obj == NULL) {
472 Py_INCREF(func);
473 return func;
474 }
475 else
476 return PyMethod_New(func, obj);
477 }
478
479 static PyObject *
instancemethod_richcompare(PyObject * self,PyObject * other,int op)480 instancemethod_richcompare(PyObject *self, PyObject *other, int op)
481 {
482 PyInstanceMethodObject *a, *b;
483 PyObject *res;
484 int eq;
485
486 if ((op != Py_EQ && op != Py_NE) ||
487 !PyInstanceMethod_Check(self) ||
488 !PyInstanceMethod_Check(other))
489 {
490 Py_RETURN_NOTIMPLEMENTED;
491 }
492 a = (PyInstanceMethodObject *)self;
493 b = (PyInstanceMethodObject *)other;
494 eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ);
495 if (eq < 0)
496 return NULL;
497 if (op == Py_EQ)
498 res = eq ? Py_True : Py_False;
499 else
500 res = eq ? Py_False : Py_True;
501 Py_INCREF(res);
502 return res;
503 }
504
505 static PyObject *
instancemethod_repr(PyObject * self)506 instancemethod_repr(PyObject *self)
507 {
508 PyObject *func = PyInstanceMethod_Function(self);
509 PyObject *funcname, *result;
510 const char *defname = "?";
511
512 if (func == NULL) {
513 PyErr_BadInternalCall();
514 return NULL;
515 }
516
517 if (_PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0) {
518 return NULL;
519 }
520 if (funcname != NULL && !PyUnicode_Check(funcname)) {
521 Py_DECREF(funcname);
522 funcname = NULL;
523 }
524
525 result = PyUnicode_FromFormat("<instancemethod %V at %p>",
526 funcname, defname, self);
527
528 Py_XDECREF(funcname);
529 return result;
530 }
531
532 /*
533 static long
534 instancemethod_hash(PyObject *self)
535 {
536 long x, y;
537 x = (long)self;
538 y = PyObject_Hash(PyInstanceMethod_GET_FUNCTION(self));
539 if (y == -1)
540 return -1;
541 x = x ^ y;
542 if (x == -1)
543 x = -2;
544 return x;
545 }
546 */
547
548 PyDoc_STRVAR(instancemethod_doc,
549 "instancemethod(function)\n\
550 \n\
551 Bind a function to a class.");
552
553 static PyObject *
instancemethod_new(PyTypeObject * type,PyObject * args,PyObject * kw)554 instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw)
555 {
556 PyObject *func;
557
558 if (!_PyArg_NoKeywords("instancemethod", kw))
559 return NULL;
560 if (!PyArg_UnpackTuple(args, "instancemethod", 1, 1, &func))
561 return NULL;
562 if (!PyCallable_Check(func)) {
563 PyErr_SetString(PyExc_TypeError,
564 "first argument must be callable");
565 return NULL;
566 }
567
568 return PyInstanceMethod_New(func);
569 }
570
571 PyTypeObject PyInstanceMethod_Type = {
572 PyVarObject_HEAD_INIT(&PyType_Type, 0)
573 "instancemethod", /* tp_name */
574 sizeof(PyInstanceMethodObject), /* tp_basicsize */
575 0, /* tp_itemsize */
576 instancemethod_dealloc, /* tp_dealloc */
577 0, /* tp_vectorcall_offset */
578 0, /* tp_getattr */
579 0, /* tp_setattr */
580 0, /* tp_as_async */
581 (reprfunc)instancemethod_repr, /* tp_repr */
582 0, /* tp_as_number */
583 0, /* tp_as_sequence */
584 0, /* tp_as_mapping */
585 0, /*(hashfunc)instancemethod_hash, tp_hash */
586 instancemethod_call, /* tp_call */
587 0, /* tp_str */
588 instancemethod_getattro, /* tp_getattro */
589 PyObject_GenericSetAttr, /* tp_setattro */
590 0, /* tp_as_buffer */
591 Py_TPFLAGS_DEFAULT
592 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
593 instancemethod_doc, /* tp_doc */
594 instancemethod_traverse, /* tp_traverse */
595 0, /* tp_clear */
596 instancemethod_richcompare, /* tp_richcompare */
597 0, /* tp_weaklistoffset */
598 0, /* tp_iter */
599 0, /* tp_iternext */
600 0, /* tp_methods */
601 instancemethod_memberlist, /* tp_members */
602 instancemethod_getset, /* tp_getset */
603 0, /* tp_base */
604 0, /* tp_dict */
605 instancemethod_descr_get, /* tp_descr_get */
606 0, /* tp_descr_set */
607 0, /* tp_dictoffset */
608 0, /* tp_init */
609 0, /* tp_alloc */
610 instancemethod_new, /* tp_new */
611 };
612