• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Class object implementation (dead now except for methods) */
2 
3 #include "Python.h"
4 #include "internal/mem.h"
5 #include "internal/pystate.h"
6 #include "structmember.h"
7 
8 #define TP_DESCR_GET(t) ((t)->tp_descr_get)
9 
10 /* Free list for method objects to safe malloc/free overhead
11  * The im_self element is used to chain the elements.
12  */
13 static PyMethodObject *free_list;
14 static int numfree = 0;
15 #ifndef PyMethod_MAXFREELIST
16 #define PyMethod_MAXFREELIST 256
17 #endif
18 
19 _Py_IDENTIFIER(__name__);
20 _Py_IDENTIFIER(__qualname__);
21 
22 PyObject *
PyMethod_Function(PyObject * im)23 PyMethod_Function(PyObject *im)
24 {
25     if (!PyMethod_Check(im)) {
26         PyErr_BadInternalCall();
27         return NULL;
28     }
29     return ((PyMethodObject *)im)->im_func;
30 }
31 
32 PyObject *
PyMethod_Self(PyObject * im)33 PyMethod_Self(PyObject *im)
34 {
35     if (!PyMethod_Check(im)) {
36         PyErr_BadInternalCall();
37         return NULL;
38     }
39     return ((PyMethodObject *)im)->im_self;
40 }
41 
42 /* Method objects are used for bound instance methods returned by
43    instancename.methodname. ClassName.methodname returns an ordinary
44    function.
45 */
46 
47 PyObject *
PyMethod_New(PyObject * func,PyObject * self)48 PyMethod_New(PyObject *func, PyObject *self)
49 {
50     PyMethodObject *im;
51     if (self == NULL) {
52         PyErr_BadInternalCall();
53         return NULL;
54     }
55     im = free_list;
56     if (im != NULL) {
57         free_list = (PyMethodObject *)(im->im_self);
58         (void)PyObject_INIT(im, &PyMethod_Type);
59         numfree--;
60     }
61     else {
62         im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
63         if (im == NULL)
64             return NULL;
65     }
66     im->im_weakreflist = NULL;
67     Py_INCREF(func);
68     im->im_func = func;
69     Py_XINCREF(self);
70     im->im_self = self;
71     _PyObject_GC_TRACK(im);
72     return (PyObject *)im;
73 }
74 
75 static PyObject *
method_reduce(PyMethodObject * im)76 method_reduce(PyMethodObject *im)
77 {
78     PyObject *self = PyMethod_GET_SELF(im);
79     PyObject *func = PyMethod_GET_FUNCTION(im);
80     PyObject *funcname;
81     _Py_IDENTIFIER(getattr);
82 
83     funcname = _PyObject_GetAttrId(func, &PyId___name__);
84     if (funcname == NULL) {
85         return NULL;
86     }
87     return Py_BuildValue("N(ON)", _PyEval_GetBuiltinId(&PyId_getattr),
88                          self, funcname);
89 }
90 
91 static PyMethodDef method_methods[] = {
92     {"__reduce__", (PyCFunction)method_reduce, METH_NOARGS, NULL},
93     {NULL, NULL}
94 };
95 
96 /* Descriptors for PyMethod attributes */
97 
98 /* im_func and im_self are stored in the PyMethod object */
99 
100 #define MO_OFF(x) offsetof(PyMethodObject, x)
101 
102 static PyMemberDef method_memberlist[] = {
103     {"__func__", T_OBJECT, MO_OFF(im_func), READONLY|RESTRICTED,
104      "the function (or other callable) implementing a method"},
105     {"__self__", T_OBJECT, MO_OFF(im_self), READONLY|RESTRICTED,
106      "the instance to which a method is bound"},
107     {NULL}      /* Sentinel */
108 };
109 
110 /* Christian Tismer argued convincingly that method attributes should
111    (nearly) always override function attributes.
112    The one exception is __doc__; there's a default __doc__ which
113    should only be used for the class, not for instances */
114 
115 static PyObject *
method_get_doc(PyMethodObject * im,void * context)116 method_get_doc(PyMethodObject *im, void *context)
117 {
118     static PyObject *docstr;
119     if (docstr == NULL) {
120         docstr= PyUnicode_InternFromString("__doc__");
121         if (docstr == NULL)
122             return NULL;
123     }
124     return PyObject_GetAttr(im->im_func, docstr);
125 }
126 
127 static PyGetSetDef method_getset[] = {
128     {"__doc__", (getter)method_get_doc, NULL, NULL},
129     {0}
130 };
131 
132 static PyObject *
method_getattro(PyObject * obj,PyObject * name)133 method_getattro(PyObject *obj, PyObject *name)
134 {
135     PyMethodObject *im = (PyMethodObject *)obj;
136     PyTypeObject *tp = obj->ob_type;
137     PyObject *descr = NULL;
138 
139     {
140         if (tp->tp_dict == NULL) {
141             if (PyType_Ready(tp) < 0)
142                 return NULL;
143         }
144         descr = _PyType_Lookup(tp, name);
145     }
146 
147     if (descr != NULL) {
148         descrgetfunc f = TP_DESCR_GET(descr->ob_type);
149         if (f != NULL)
150             return f(descr, obj, (PyObject *)obj->ob_type);
151         else {
152             Py_INCREF(descr);
153             return descr;
154         }
155     }
156 
157     return PyObject_GetAttr(im->im_func, name);
158 }
159 
160 PyDoc_STRVAR(method_doc,
161 "method(function, instance)\n\
162 \n\
163 Create a bound instance method object.");
164 
165 static PyObject *
method_new(PyTypeObject * type,PyObject * args,PyObject * kw)166 method_new(PyTypeObject* type, PyObject* args, PyObject *kw)
167 {
168     PyObject *func;
169     PyObject *self;
170 
171     if (!_PyArg_NoKeywords("method", kw))
172         return NULL;
173     if (!PyArg_UnpackTuple(args, "method", 2, 2,
174                           &func, &self))
175         return NULL;
176     if (!PyCallable_Check(func)) {
177         PyErr_SetString(PyExc_TypeError,
178                         "first argument must be callable");
179         return NULL;
180     }
181     if (self == NULL || self == Py_None) {
182         PyErr_SetString(PyExc_TypeError,
183             "self must not be None");
184         return NULL;
185     }
186 
187     return PyMethod_New(func, self);
188 }
189 
190 static void
method_dealloc(PyMethodObject * im)191 method_dealloc(PyMethodObject *im)
192 {
193     _PyObject_GC_UNTRACK(im);
194     if (im->im_weakreflist != NULL)
195         PyObject_ClearWeakRefs((PyObject *)im);
196     Py_DECREF(im->im_func);
197     Py_XDECREF(im->im_self);
198     if (numfree < PyMethod_MAXFREELIST) {
199         im->im_self = (PyObject *)free_list;
200         free_list = im;
201         numfree++;
202     }
203     else {
204         PyObject_GC_Del(im);
205     }
206 }
207 
208 static PyObject *
method_richcompare(PyObject * self,PyObject * other,int op)209 method_richcompare(PyObject *self, PyObject *other, int op)
210 {
211     PyMethodObject *a, *b;
212     PyObject *res;
213     int eq;
214 
215     if ((op != Py_EQ && op != Py_NE) ||
216         !PyMethod_Check(self) ||
217         !PyMethod_Check(other))
218     {
219         Py_RETURN_NOTIMPLEMENTED;
220     }
221     a = (PyMethodObject *)self;
222     b = (PyMethodObject *)other;
223     eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ);
224     if (eq == 1) {
225         if (a->im_self == NULL || b->im_self == NULL)
226             eq = a->im_self == b->im_self;
227         else
228             eq = PyObject_RichCompareBool(a->im_self, b->im_self,
229                                           Py_EQ);
230     }
231     if (eq < 0)
232         return NULL;
233     if (op == Py_EQ)
234         res = eq ? Py_True : Py_False;
235     else
236         res = eq ? Py_False : Py_True;
237     Py_INCREF(res);
238     return res;
239 }
240 
241 static PyObject *
method_repr(PyMethodObject * a)242 method_repr(PyMethodObject *a)
243 {
244     PyObject *self = a->im_self;
245     PyObject *func = a->im_func;
246     PyObject *funcname, *result;
247     const char *defname = "?";
248 
249     if (_PyObject_LookupAttrId(func, &PyId___qualname__, &funcname) < 0 ||
250         (funcname == NULL &&
251          _PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0))
252     {
253         return NULL;
254     }
255 
256     if (funcname != NULL && !PyUnicode_Check(funcname)) {
257         Py_DECREF(funcname);
258         funcname = NULL;
259     }
260 
261     /* XXX Shouldn't use repr()/%R here! */
262     result = PyUnicode_FromFormat("<bound method %V of %R>",
263                                   funcname, defname, self);
264 
265     Py_XDECREF(funcname);
266     return result;
267 }
268 
269 static Py_hash_t
method_hash(PyMethodObject * a)270 method_hash(PyMethodObject *a)
271 {
272     Py_hash_t x, y;
273     if (a->im_self == NULL)
274         x = PyObject_Hash(Py_None);
275     else
276         x = PyObject_Hash(a->im_self);
277     if (x == -1)
278         return -1;
279     y = PyObject_Hash(a->im_func);
280     if (y == -1)
281         return -1;
282     x = x ^ y;
283     if (x == -1)
284         x = -2;
285     return x;
286 }
287 
288 static int
method_traverse(PyMethodObject * im,visitproc visit,void * arg)289 method_traverse(PyMethodObject *im, visitproc visit, void *arg)
290 {
291     Py_VISIT(im->im_func);
292     Py_VISIT(im->im_self);
293     return 0;
294 }
295 
296 static PyObject *
method_call(PyObject * method,PyObject * args,PyObject * kwargs)297 method_call(PyObject *method, PyObject *args, PyObject *kwargs)
298 {
299     PyObject *self, *func;
300 
301     self = PyMethod_GET_SELF(method);
302     if (self == NULL) {
303         PyErr_BadInternalCall();
304         return NULL;
305     }
306 
307     func = PyMethod_GET_FUNCTION(method);
308 
309     return _PyObject_Call_Prepend(func, self, args, kwargs);
310 }
311 
312 static PyObject *
method_descr_get(PyObject * meth,PyObject * obj,PyObject * cls)313 method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls)
314 {
315     /* Don't rebind an already bound method of a class that's not a base
316        class of cls. */
317     if (PyMethod_GET_SELF(meth) != NULL) {
318         /* Already bound */
319         Py_INCREF(meth);
320         return meth;
321     }
322     /* Bind it to obj */
323     return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj);
324 }
325 
326 PyTypeObject PyMethod_Type = {
327     PyVarObject_HEAD_INIT(&PyType_Type, 0)
328     "method",
329     sizeof(PyMethodObject),
330     0,
331     (destructor)method_dealloc,                 /* tp_dealloc */
332     0,                                          /* tp_print */
333     0,                                          /* tp_getattr */
334     0,                                          /* tp_setattr */
335     0,                                          /* tp_reserved */
336     (reprfunc)method_repr,                      /* tp_repr */
337     0,                                          /* tp_as_number */
338     0,                                          /* tp_as_sequence */
339     0,                                          /* tp_as_mapping */
340     (hashfunc)method_hash,                      /* tp_hash */
341     method_call,                                /* tp_call */
342     0,                                          /* tp_str */
343     method_getattro,                            /* tp_getattro */
344     PyObject_GenericSetAttr,                    /* tp_setattro */
345     0,                                          /* tp_as_buffer */
346     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
347     method_doc,                                 /* tp_doc */
348     (traverseproc)method_traverse,              /* tp_traverse */
349     0,                                          /* tp_clear */
350     method_richcompare,                         /* tp_richcompare */
351     offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */
352     0,                                          /* tp_iter */
353     0,                                          /* tp_iternext */
354     method_methods,                             /* tp_methods */
355     method_memberlist,                          /* tp_members */
356     method_getset,                              /* tp_getset */
357     0,                                          /* tp_base */
358     0,                                          /* tp_dict */
359     method_descr_get,                           /* tp_descr_get */
360     0,                                          /* tp_descr_set */
361     0,                                          /* tp_dictoffset */
362     0,                                          /* tp_init */
363     0,                                          /* tp_alloc */
364     method_new,                                 /* tp_new */
365 };
366 
367 /* Clear out the free list */
368 
369 int
PyMethod_ClearFreeList(void)370 PyMethod_ClearFreeList(void)
371 {
372     int freelist_size = numfree;
373 
374     while (free_list) {
375         PyMethodObject *im = free_list;
376         free_list = (PyMethodObject *)(im->im_self);
377         PyObject_GC_Del(im);
378         numfree--;
379     }
380     assert(numfree == 0);
381     return freelist_size;
382 }
383 
384 void
PyMethod_Fini(void)385 PyMethod_Fini(void)
386 {
387     (void)PyMethod_ClearFreeList();
388 }
389 
390 /* Print summary info about the state of the optimized allocator */
391 void
_PyMethod_DebugMallocStats(FILE * out)392 _PyMethod_DebugMallocStats(FILE *out)
393 {
394     _PyDebugAllocatorStats(out,
395                            "free PyMethodObject",
396                            numfree, sizeof(PyMethodObject));
397 }
398 
399 /* ------------------------------------------------------------------------
400  * instance method
401  */
402 
403 PyObject *
PyInstanceMethod_New(PyObject * func)404 PyInstanceMethod_New(PyObject *func) {
405     PyInstanceMethodObject *method;
406     method = PyObject_GC_New(PyInstanceMethodObject,
407                              &PyInstanceMethod_Type);
408     if (method == NULL) return NULL;
409     Py_INCREF(func);
410     method->func = func;
411     _PyObject_GC_TRACK(method);
412     return (PyObject *)method;
413 }
414 
415 PyObject *
PyInstanceMethod_Function(PyObject * im)416 PyInstanceMethod_Function(PyObject *im)
417 {
418     if (!PyInstanceMethod_Check(im)) {
419         PyErr_BadInternalCall();
420         return NULL;
421     }
422     return PyInstanceMethod_GET_FUNCTION(im);
423 }
424 
425 #define IMO_OFF(x) offsetof(PyInstanceMethodObject, x)
426 
427 static PyMemberDef instancemethod_memberlist[] = {
428     {"__func__", T_OBJECT, IMO_OFF(func), READONLY|RESTRICTED,
429      "the function (or other callable) implementing a method"},
430     {NULL}      /* Sentinel */
431 };
432 
433 static PyObject *
instancemethod_get_doc(PyObject * self,void * context)434 instancemethod_get_doc(PyObject *self, void *context)
435 {
436     static PyObject *docstr;
437     if (docstr == NULL) {
438         docstr = PyUnicode_InternFromString("__doc__");
439         if (docstr == NULL)
440             return NULL;
441     }
442     return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), docstr);
443 }
444 
445 static PyGetSetDef instancemethod_getset[] = {
446     {"__doc__", (getter)instancemethod_get_doc, NULL, NULL},
447     {0}
448 };
449 
450 static PyObject *
instancemethod_getattro(PyObject * self,PyObject * name)451 instancemethod_getattro(PyObject *self, PyObject *name)
452 {
453     PyTypeObject *tp = self->ob_type;
454     PyObject *descr = NULL;
455 
456     if (tp->tp_dict == NULL) {
457         if (PyType_Ready(tp) < 0)
458             return NULL;
459     }
460     descr = _PyType_Lookup(tp, name);
461 
462     if (descr != NULL) {
463         descrgetfunc f = TP_DESCR_GET(descr->ob_type);
464         if (f != NULL)
465             return f(descr, self, (PyObject *)self->ob_type);
466         else {
467             Py_INCREF(descr);
468             return descr;
469         }
470     }
471 
472     return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name);
473 }
474 
475 static void
instancemethod_dealloc(PyObject * self)476 instancemethod_dealloc(PyObject *self) {
477     _PyObject_GC_UNTRACK(self);
478     Py_DECREF(PyInstanceMethod_GET_FUNCTION(self));
479     PyObject_GC_Del(self);
480 }
481 
482 static int
instancemethod_traverse(PyObject * self,visitproc visit,void * arg)483 instancemethod_traverse(PyObject *self, visitproc visit, void *arg) {
484     Py_VISIT(PyInstanceMethod_GET_FUNCTION(self));
485     return 0;
486 }
487 
488 static PyObject *
instancemethod_call(PyObject * self,PyObject * arg,PyObject * kw)489 instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw)
490 {
491     return PyObject_Call(PyMethod_GET_FUNCTION(self), arg, kw);
492 }
493 
494 static PyObject *
instancemethod_descr_get(PyObject * descr,PyObject * obj,PyObject * type)495 instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) {
496     PyObject *func = PyInstanceMethod_GET_FUNCTION(descr);
497     if (obj == NULL) {
498         Py_INCREF(func);
499         return func;
500     }
501     else
502         return PyMethod_New(func, obj);
503 }
504 
505 static PyObject *
instancemethod_richcompare(PyObject * self,PyObject * other,int op)506 instancemethod_richcompare(PyObject *self, PyObject *other, int op)
507 {
508     PyInstanceMethodObject *a, *b;
509     PyObject *res;
510     int eq;
511 
512     if ((op != Py_EQ && op != Py_NE) ||
513         !PyInstanceMethod_Check(self) ||
514         !PyInstanceMethod_Check(other))
515     {
516         Py_RETURN_NOTIMPLEMENTED;
517     }
518     a = (PyInstanceMethodObject *)self;
519     b = (PyInstanceMethodObject *)other;
520     eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ);
521     if (eq < 0)
522         return NULL;
523     if (op == Py_EQ)
524         res = eq ? Py_True : Py_False;
525     else
526         res = eq ? Py_False : Py_True;
527     Py_INCREF(res);
528     return res;
529 }
530 
531 static PyObject *
instancemethod_repr(PyObject * self)532 instancemethod_repr(PyObject *self)
533 {
534     PyObject *func = PyInstanceMethod_Function(self);
535     PyObject *funcname, *result;
536     const char *defname = "?";
537 
538     if (func == NULL) {
539         PyErr_BadInternalCall();
540         return NULL;
541     }
542 
543     if (_PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0) {
544         return NULL;
545     }
546     if (funcname != NULL && !PyUnicode_Check(funcname)) {
547         Py_DECREF(funcname);
548         funcname = NULL;
549     }
550 
551     result = PyUnicode_FromFormat("<instancemethod %V at %p>",
552                                   funcname, defname, self);
553 
554     Py_XDECREF(funcname);
555     return result;
556 }
557 
558 /*
559 static long
560 instancemethod_hash(PyObject *self)
561 {
562     long x, y;
563     x = (long)self;
564     y = PyObject_Hash(PyInstanceMethod_GET_FUNCTION(self));
565     if (y == -1)
566         return -1;
567     x = x ^ y;
568     if (x == -1)
569         x = -2;
570     return x;
571 }
572 */
573 
574 PyDoc_STRVAR(instancemethod_doc,
575 "instancemethod(function)\n\
576 \n\
577 Bind a function to a class.");
578 
579 static PyObject *
instancemethod_new(PyTypeObject * type,PyObject * args,PyObject * kw)580 instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw)
581 {
582     PyObject *func;
583 
584     if (!_PyArg_NoKeywords("instancemethod", kw))
585         return NULL;
586     if (!PyArg_UnpackTuple(args, "instancemethod", 1, 1, &func))
587         return NULL;
588     if (!PyCallable_Check(func)) {
589         PyErr_SetString(PyExc_TypeError,
590                         "first argument must be callable");
591         return NULL;
592     }
593 
594     return PyInstanceMethod_New(func);
595 }
596 
597 PyTypeObject PyInstanceMethod_Type = {
598     PyVarObject_HEAD_INIT(&PyType_Type, 0)
599     "instancemethod",                           /* tp_name */
600     sizeof(PyInstanceMethodObject),             /* tp_basicsize */
601     0,                                          /* tp_itemsize */
602     instancemethod_dealloc,                     /* tp_dealloc */
603     0,                                          /* tp_print */
604     0,                                          /* tp_getattr */
605     0,                                          /* tp_setattr */
606     0,                                          /* tp_reserved */
607     (reprfunc)instancemethod_repr,              /* tp_repr */
608     0,                                          /* tp_as_number */
609     0,                                          /* tp_as_sequence */
610     0,                                          /* tp_as_mapping */
611     0, /*(hashfunc)instancemethod_hash,         tp_hash  */
612     instancemethod_call,                        /* tp_call */
613     0,                                          /* tp_str */
614     instancemethod_getattro,                    /* tp_getattro */
615     PyObject_GenericSetAttr,                    /* tp_setattro */
616     0,                                          /* tp_as_buffer */
617     Py_TPFLAGS_DEFAULT
618         | Py_TPFLAGS_HAVE_GC,                   /* tp_flags */
619     instancemethod_doc,                         /* tp_doc */
620     instancemethod_traverse,                    /* tp_traverse */
621     0,                                          /* tp_clear */
622     instancemethod_richcompare,                 /* tp_richcompare */
623     0,                                          /* tp_weaklistoffset */
624     0,                                          /* tp_iter */
625     0,                                          /* tp_iternext */
626     0,                                          /* tp_methods */
627     instancemethod_memberlist,                  /* tp_members */
628     instancemethod_getset,                      /* tp_getset */
629     0,                                          /* tp_base */
630     0,                                          /* tp_dict */
631     instancemethod_descr_get,                   /* tp_descr_get */
632     0,                                          /* tp_descr_set */
633     0,                                          /* tp_dictoffset */
634     0,                                          /* tp_init */
635     0,                                          /* tp_alloc */
636     instancemethod_new,                         /* tp_new */
637 };
638