/src/cpython/Objects/classobject.c
Line | Count | Source |
1 | | /* Class object implementation (dead now except for methods) */ |
2 | | |
3 | | #include "Python.h" |
4 | | #include "pycore_call.h" // _PyObject_VectorcallTstate() |
5 | | #include "pycore_ceval.h" // _PyEval_GetBuiltin() |
6 | | #include "pycore_freelist.h" |
7 | | #include "pycore_object.h" |
8 | | #include "pycore_pyerrors.h" |
9 | | #include "pycore_pystate.h" // _PyThreadState_GET() |
10 | | #include "pycore_symtable.h" // _Py_Mangle() |
11 | | #include "pycore_weakref.h" // FT_CLEAR_WEAKREFS() |
12 | | |
13 | | |
14 | | #include "clinic/classobject.c.h" |
15 | | |
16 | 48.9M | #define _PyMethodObject_CAST(op) _Py_CAST(PyMethodObject*, (op)) |
17 | 60 | #define TP_DESCR_GET(t) ((t)->tp_descr_get) |
18 | | |
19 | | /*[clinic input] |
20 | | class method "PyMethodObject *" "&PyMethod_Type" |
21 | | [clinic start generated code]*/ |
22 | | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b16e47edf6107c23]*/ |
23 | | |
24 | | |
25 | | PyObject * |
26 | | PyMethod_Function(PyObject *im) |
27 | 0 | { |
28 | 0 | if (!PyMethod_Check(im)) { |
29 | 0 | PyErr_BadInternalCall(); |
30 | 0 | return NULL; |
31 | 0 | } |
32 | 0 | return ((PyMethodObject *)im)->im_func; |
33 | 0 | } |
34 | | |
35 | | PyObject * |
36 | | PyMethod_Self(PyObject *im) |
37 | 0 | { |
38 | 0 | if (!PyMethod_Check(im)) { |
39 | 0 | PyErr_BadInternalCall(); |
40 | 0 | return NULL; |
41 | 0 | } |
42 | 0 | return ((PyMethodObject *)im)->im_self; |
43 | 0 | } |
44 | | |
45 | | |
46 | | static PyObject * |
47 | | method_vectorcall(PyObject *method, PyObject *const *args, |
48 | | size_t nargsf, PyObject *kwnames) |
49 | 41.3M | { |
50 | 41.3M | assert(Py_IS_TYPE(method, &PyMethod_Type)); |
51 | | |
52 | 41.3M | PyThreadState *tstate = _PyThreadState_GET(); |
53 | 41.3M | PyObject *self = PyMethod_GET_SELF(method); |
54 | 41.3M | PyObject *func = PyMethod_GET_FUNCTION(method); |
55 | 41.3M | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
56 | 41.3M | assert(nargs == 0 || args[nargs-1]); |
57 | | |
58 | 41.3M | PyObject *result; |
59 | 41.3M | if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) { |
60 | | /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */ |
61 | 751k | PyObject **newargs = (PyObject**)args - 1; |
62 | 751k | nargs += 1; |
63 | 751k | PyObject *tmp = newargs[0]; |
64 | 751k | newargs[0] = self; |
65 | 751k | assert(newargs[nargs-1]); |
66 | 751k | result = _PyObject_VectorcallTstate(tstate, func, newargs, |
67 | 751k | nargs, kwnames); |
68 | 751k | newargs[0] = tmp; |
69 | 751k | } |
70 | 40.6M | else { |
71 | 40.6M | Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); |
72 | 40.6M | Py_ssize_t totalargs = nargs + nkwargs; |
73 | 40.6M | if (totalargs == 0) { |
74 | 548 | return _PyObject_VectorcallTstate(tstate, func, &self, 1, NULL); |
75 | 548 | } |
76 | | |
77 | 40.6M | PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK]; |
78 | 40.6M | PyObject **newargs; |
79 | 40.6M | if (totalargs <= (Py_ssize_t)Py_ARRAY_LENGTH(newargs_stack) - 1) { |
80 | 40.6M | newargs = newargs_stack; |
81 | 40.6M | } |
82 | 1.63k | else { |
83 | 1.63k | newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *)); |
84 | 1.63k | if (newargs == NULL) { |
85 | 0 | _PyErr_NoMemory(tstate); |
86 | 0 | return NULL; |
87 | 0 | } |
88 | 1.63k | } |
89 | | /* use borrowed references */ |
90 | 40.6M | newargs[0] = self; |
91 | | /* bpo-37138: since totalargs > 0, it's impossible that args is NULL. |
92 | | * We need this, since calling memcpy() with a NULL pointer is |
93 | | * undefined behaviour. */ |
94 | 40.6M | assert(args != NULL); |
95 | 40.6M | memcpy(newargs + 1, args, totalargs * sizeof(PyObject *)); |
96 | 40.6M | result = _PyObject_VectorcallTstate(tstate, func, |
97 | 40.6M | newargs, nargs+1, kwnames); |
98 | 40.6M | if (newargs != newargs_stack) { |
99 | 1.63k | PyMem_Free(newargs); |
100 | 1.63k | } |
101 | 40.6M | } |
102 | 41.3M | return result; |
103 | 41.3M | } |
104 | | |
105 | | |
106 | | /* Method objects are used for bound instance methods returned by |
107 | | instancename.methodname. ClassName.methodname returns an ordinary |
108 | | function. |
109 | | */ |
110 | | |
111 | | PyObject * |
112 | | PyMethod_New(PyObject *func, PyObject *self) |
113 | 47.1M | { |
114 | 47.1M | if (self == NULL) { |
115 | 0 | PyErr_BadInternalCall(); |
116 | 0 | return NULL; |
117 | 0 | } |
118 | 47.1M | PyMethodObject *im = _Py_FREELIST_POP(PyMethodObject, pymethodobjects); |
119 | 47.1M | if (im == NULL) { |
120 | 898k | im = PyObject_GC_New(PyMethodObject, &PyMethod_Type); |
121 | 898k | if (im == NULL) { |
122 | 0 | return NULL; |
123 | 0 | } |
124 | 898k | } |
125 | 47.1M | im->im_weakreflist = NULL; |
126 | 47.1M | im->im_func = Py_NewRef(func); |
127 | 47.1M | im->im_self = Py_NewRef(self); |
128 | 47.1M | im->vectorcall = method_vectorcall; |
129 | 47.1M | _PyObject_GC_TRACK(im); |
130 | 47.1M | return (PyObject *)im; |
131 | 47.1M | } |
132 | | |
133 | | /*[clinic input] |
134 | | method.__reduce__ |
135 | | [clinic start generated code]*/ |
136 | | |
137 | | static PyObject * |
138 | | method___reduce___impl(PyMethodObject *self) |
139 | | /*[clinic end generated code: output=6c04506d0fa6fdcb input=143a0bf5e96de6e8]*/ |
140 | 0 | { |
141 | 0 | PyObject *funcself = PyMethod_GET_SELF(self); |
142 | 0 | PyObject *func = PyMethod_GET_FUNCTION(self); |
143 | 0 | PyObject *funcname = PyObject_GetAttr(func, &_Py_ID(__name__)); |
144 | 0 | if (funcname == NULL) { |
145 | 0 | return NULL; |
146 | 0 | } |
147 | 0 | if (_Py_IsPrivateName(funcname)) { |
148 | 0 | PyObject *classname = PyType_Check(funcself) |
149 | 0 | ? PyType_GetName((PyTypeObject *)funcself) |
150 | 0 | : PyType_GetName(Py_TYPE(funcself)); |
151 | 0 | if (classname == NULL) { |
152 | 0 | Py_DECREF(funcname); |
153 | 0 | return NULL; |
154 | 0 | } |
155 | 0 | Py_SETREF(funcname, _Py_Mangle(classname, funcname)); |
156 | 0 | Py_DECREF(classname); |
157 | 0 | if (funcname == NULL) { |
158 | 0 | return NULL; |
159 | 0 | } |
160 | 0 | } |
161 | 0 | return Py_BuildValue( |
162 | 0 | "N(ON)", _PyEval_GetBuiltin(&_Py_ID(getattr)), funcself, funcname); |
163 | 0 | } |
164 | | |
165 | | static PyMethodDef method_methods[] = { |
166 | | METHOD___REDUCE___METHODDEF |
167 | | {NULL, NULL} |
168 | | }; |
169 | | |
170 | | /* Descriptors for PyMethod attributes */ |
171 | | |
172 | | /* im_func and im_self are stored in the PyMethod object */ |
173 | | |
174 | | #define MO_OFF(x) offsetof(PyMethodObject, x) |
175 | | |
176 | | static PyMemberDef method_memberlist[] = { |
177 | | {"__func__", _Py_T_OBJECT, MO_OFF(im_func), Py_READONLY, |
178 | | "the function (or other callable) implementing a method"}, |
179 | | {"__self__", _Py_T_OBJECT, MO_OFF(im_self), Py_READONLY, |
180 | | "the instance to which a method is bound"}, |
181 | | {NULL} /* Sentinel */ |
182 | | }; |
183 | | |
184 | | /* Christian Tismer argued convincingly that method attributes should |
185 | | (nearly) always override function attributes. |
186 | | The one exception is __doc__; there's a default __doc__ which |
187 | | should only be used for the class, not for instances */ |
188 | | |
189 | | static PyObject * |
190 | | method_get_doc(PyObject *self, void *context) |
191 | 10 | { |
192 | 10 | PyMethodObject *im = _PyMethodObject_CAST(self); |
193 | 10 | return PyObject_GetAttr(im->im_func, &_Py_ID(__doc__)); |
194 | 10 | } |
195 | | |
196 | | static PyGetSetDef method_getset[] = { |
197 | | {"__doc__", method_get_doc, NULL, NULL}, |
198 | | {0} |
199 | | }; |
200 | | |
201 | | static PyObject * |
202 | | method_getattro(PyObject *obj, PyObject *name) |
203 | 124 | { |
204 | 124 | PyMethodObject *im = (PyMethodObject *)obj; |
205 | 124 | PyTypeObject *tp = Py_TYPE(obj); |
206 | 124 | PyObject *descr = NULL; |
207 | | |
208 | 124 | { |
209 | 124 | if (!_PyType_IsReady(tp)) { |
210 | 0 | if (PyType_Ready(tp) < 0) |
211 | 0 | return NULL; |
212 | 0 | } |
213 | 124 | descr = _PyType_LookupRef(tp, name); |
214 | 124 | } |
215 | | |
216 | 124 | if (descr != NULL) { |
217 | 60 | descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr)); |
218 | 60 | if (f != NULL) { |
219 | 60 | PyObject *res = f(descr, obj, (PyObject *)Py_TYPE(obj)); |
220 | 60 | Py_DECREF(descr); |
221 | 60 | return res; |
222 | 60 | } |
223 | 0 | else { |
224 | 0 | return descr; |
225 | 0 | } |
226 | 60 | } |
227 | | |
228 | 64 | return PyObject_GetAttr(im->im_func, name); |
229 | 124 | } |
230 | | |
231 | | /*[clinic input] |
232 | | @classmethod |
233 | | method.__new__ as method_new |
234 | | function: object |
235 | | instance: object |
236 | | / |
237 | | |
238 | | Create a bound instance method object. |
239 | | [clinic start generated code]*/ |
240 | | |
241 | | static PyObject * |
242 | | method_new_impl(PyTypeObject *type, PyObject *function, PyObject *instance) |
243 | | /*[clinic end generated code: output=d33ef4ebf702e1f7 input=4e32facc3c3108ae]*/ |
244 | 10 | { |
245 | 10 | if (!PyCallable_Check(function)) { |
246 | 0 | PyErr_SetString(PyExc_TypeError, |
247 | 0 | "first argument must be callable"); |
248 | 0 | return NULL; |
249 | 0 | } |
250 | 10 | if (instance == NULL || instance == Py_None) { |
251 | 0 | PyErr_SetString(PyExc_TypeError, |
252 | 0 | "instance must not be None"); |
253 | 0 | return NULL; |
254 | 0 | } |
255 | | |
256 | 10 | return PyMethod_New(function, instance); |
257 | 10 | } |
258 | | |
259 | | static void |
260 | | method_dealloc(PyObject *self) |
261 | 47.1M | { |
262 | 47.1M | PyMethodObject *im = _PyMethodObject_CAST(self); |
263 | 47.1M | _PyObject_GC_UNTRACK(im); |
264 | 47.1M | FT_CLEAR_WEAKREFS(self, im->im_weakreflist); |
265 | 47.1M | Py_DECREF(im->im_func); |
266 | 47.1M | Py_XDECREF(im->im_self); |
267 | 47.1M | assert(Py_IS_TYPE(self, &PyMethod_Type)); |
268 | 47.1M | _Py_FREELIST_FREE(pymethodobjects, (PyObject *)im, PyObject_GC_Del); |
269 | 47.1M | } |
270 | | |
271 | | static PyObject * |
272 | | method_richcompare(PyObject *self, PyObject *other, int op) |
273 | 0 | { |
274 | 0 | PyMethodObject *a, *b; |
275 | 0 | PyObject *res; |
276 | 0 | int eq; |
277 | |
|
278 | 0 | if ((op != Py_EQ && op != Py_NE) || |
279 | 0 | !PyMethod_Check(self) || |
280 | 0 | !PyMethod_Check(other)) |
281 | 0 | { |
282 | 0 | Py_RETURN_NOTIMPLEMENTED; |
283 | 0 | } |
284 | 0 | a = (PyMethodObject *)self; |
285 | 0 | b = (PyMethodObject *)other; |
286 | 0 | eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ); |
287 | 0 | if (eq == 1) { |
288 | 0 | eq = (a->im_self == b->im_self); |
289 | 0 | } |
290 | 0 | else if (eq < 0) |
291 | 0 | return NULL; |
292 | 0 | if (op == Py_EQ) |
293 | 0 | res = eq ? Py_True : Py_False; |
294 | 0 | else |
295 | 0 | res = eq ? Py_False : Py_True; |
296 | 0 | return Py_NewRef(res); |
297 | 0 | } |
298 | | |
299 | | static PyObject * |
300 | | method_repr(PyObject *op) |
301 | 0 | { |
302 | 0 | PyMethodObject *a = _PyMethodObject_CAST(op); |
303 | 0 | PyObject *self = a->im_self; |
304 | 0 | PyObject *func = a->im_func; |
305 | 0 | PyObject *funcname, *result; |
306 | 0 | const char *defname = "?"; |
307 | |
|
308 | 0 | if (PyObject_GetOptionalAttr(func, &_Py_ID(__qualname__), &funcname) < 0 || |
309 | 0 | (funcname == NULL && |
310 | 0 | PyObject_GetOptionalAttr(func, &_Py_ID(__name__), &funcname) < 0)) |
311 | 0 | { |
312 | 0 | return NULL; |
313 | 0 | } |
314 | | |
315 | 0 | if (funcname != NULL && !PyUnicode_Check(funcname)) { |
316 | 0 | Py_SETREF(funcname, NULL); |
317 | 0 | } |
318 | | |
319 | | /* XXX Shouldn't use repr()/%R here! */ |
320 | 0 | result = PyUnicode_FromFormat("<bound method %V of %R>", |
321 | 0 | funcname, defname, self); |
322 | |
|
323 | 0 | Py_XDECREF(funcname); |
324 | 0 | return result; |
325 | 0 | } |
326 | | |
327 | | static Py_hash_t |
328 | | method_hash(PyObject *self) |
329 | 0 | { |
330 | 0 | PyMethodObject *a = _PyMethodObject_CAST(self); |
331 | 0 | Py_hash_t x = PyObject_GenericHash(a->im_self); |
332 | 0 | Py_hash_t y = PyObject_Hash(a->im_func); |
333 | 0 | if (y == -1) { |
334 | 0 | return -1; |
335 | 0 | } |
336 | | |
337 | 0 | x = x ^ y; |
338 | 0 | if (x == -1) { |
339 | 0 | x = -2; |
340 | 0 | } |
341 | 0 | return x; |
342 | 0 | } |
343 | | |
344 | | static int |
345 | | method_traverse(PyObject *self, visitproc visit, void *arg) |
346 | 1.75M | { |
347 | 1.75M | PyMethodObject *im = _PyMethodObject_CAST(self); |
348 | 1.75M | Py_VISIT(im->im_func); |
349 | 1.75M | Py_VISIT(im->im_self); |
350 | 1.75M | return 0; |
351 | 1.75M | } |
352 | | |
353 | | static PyObject * |
354 | | method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls) |
355 | 21 | { |
356 | 21 | Py_INCREF(meth); |
357 | 21 | return meth; |
358 | 21 | } |
359 | | |
360 | | PyTypeObject PyMethod_Type = { |
361 | | PyVarObject_HEAD_INIT(&PyType_Type, 0) |
362 | | .tp_name = "method", |
363 | | .tp_basicsize = sizeof(PyMethodObject), |
364 | | .tp_dealloc = method_dealloc, |
365 | | .tp_vectorcall_offset = offsetof(PyMethodObject, vectorcall), |
366 | | .tp_repr = method_repr, |
367 | | .tp_hash = method_hash, |
368 | | .tp_call = PyVectorcall_Call, |
369 | | .tp_getattro = method_getattro, |
370 | | .tp_setattro = PyObject_GenericSetAttr, |
371 | | .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | |
372 | | Py_TPFLAGS_HAVE_VECTORCALL, |
373 | | .tp_doc = method_new__doc__, |
374 | | .tp_traverse = method_traverse, |
375 | | .tp_richcompare = method_richcompare, |
376 | | .tp_weaklistoffset = offsetof(PyMethodObject, im_weakreflist), |
377 | | .tp_methods = method_methods, |
378 | | .tp_members = method_memberlist, |
379 | | .tp_getset = method_getset, |
380 | | .tp_descr_get = method_descr_get, |
381 | | .tp_new = method_new, |
382 | | }; |
383 | | |
384 | | /* ------------------------------------------------------------------------ |
385 | | * instance method |
386 | | */ |
387 | | |
388 | | /*[clinic input] |
389 | | class instancemethod "PyInstanceMethodObject *" "&PyInstanceMethod_Type" |
390 | | [clinic start generated code]*/ |
391 | | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=28c9762a9016f4d2]*/ |
392 | | |
393 | | PyObject * |
394 | 0 | PyInstanceMethod_New(PyObject *func) { |
395 | 0 | PyInstanceMethodObject *method; |
396 | 0 | method = PyObject_GC_New(PyInstanceMethodObject, |
397 | 0 | &PyInstanceMethod_Type); |
398 | 0 | if (method == NULL) return NULL; |
399 | 0 | method->func = Py_NewRef(func); |
400 | 0 | _PyObject_GC_TRACK(method); |
401 | 0 | return (PyObject *)method; |
402 | 0 | } |
403 | | |
404 | | PyObject * |
405 | | PyInstanceMethod_Function(PyObject *im) |
406 | 0 | { |
407 | 0 | if (!PyInstanceMethod_Check(im)) { |
408 | 0 | PyErr_BadInternalCall(); |
409 | 0 | return NULL; |
410 | 0 | } |
411 | 0 | return PyInstanceMethod_GET_FUNCTION(im); |
412 | 0 | } |
413 | | |
414 | | #define IMO_OFF(x) offsetof(PyInstanceMethodObject, x) |
415 | | |
416 | | static PyMemberDef instancemethod_memberlist[] = { |
417 | | {"__func__", _Py_T_OBJECT, IMO_OFF(func), Py_READONLY, |
418 | | "the function (or other callable) implementing a method"}, |
419 | | {NULL} /* Sentinel */ |
420 | | }; |
421 | | |
422 | | static PyObject * |
423 | | instancemethod_get_doc(PyObject *self, void *context) |
424 | 0 | { |
425 | 0 | return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), |
426 | 0 | &_Py_ID(__doc__)); |
427 | 0 | } |
428 | | |
429 | | static PyGetSetDef instancemethod_getset[] = { |
430 | | {"__doc__", instancemethod_get_doc, NULL, NULL}, |
431 | | {0} |
432 | | }; |
433 | | |
434 | | static PyObject * |
435 | | instancemethod_getattro(PyObject *self, PyObject *name) |
436 | 0 | { |
437 | 0 | PyTypeObject *tp = Py_TYPE(self); |
438 | 0 | PyObject *descr = NULL; |
439 | |
|
440 | 0 | if (!_PyType_IsReady(tp)) { |
441 | 0 | if (PyType_Ready(tp) < 0) |
442 | 0 | return NULL; |
443 | 0 | } |
444 | 0 | descr = _PyType_LookupRef(tp, name); |
445 | |
|
446 | 0 | if (descr != NULL) { |
447 | 0 | descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr)); |
448 | 0 | if (f != NULL) { |
449 | 0 | PyObject *res = f(descr, self, (PyObject *)Py_TYPE(self)); |
450 | 0 | Py_DECREF(descr); |
451 | 0 | return res; |
452 | 0 | } |
453 | 0 | else { |
454 | 0 | return descr; |
455 | 0 | } |
456 | 0 | } |
457 | | |
458 | 0 | return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name); |
459 | 0 | } |
460 | | |
461 | | static void |
462 | 0 | instancemethod_dealloc(PyObject *self) { |
463 | 0 | _PyObject_GC_UNTRACK(self); |
464 | 0 | Py_DECREF(PyInstanceMethod_GET_FUNCTION(self)); |
465 | 0 | PyObject_GC_Del(self); |
466 | 0 | } |
467 | | |
468 | | static int |
469 | 0 | instancemethod_traverse(PyObject *self, visitproc visit, void *arg) { |
470 | 0 | Py_VISIT(PyInstanceMethod_GET_FUNCTION(self)); |
471 | 0 | return 0; |
472 | 0 | } |
473 | | |
474 | | static PyObject * |
475 | | instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw) |
476 | 0 | { |
477 | 0 | return PyObject_Call(PyInstanceMethod_GET_FUNCTION(self), arg, kw); |
478 | 0 | } |
479 | | |
480 | | static PyObject * |
481 | 0 | instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) { |
482 | 0 | PyObject *func = PyInstanceMethod_GET_FUNCTION(descr); |
483 | 0 | if (obj == NULL) { |
484 | 0 | return Py_NewRef(func); |
485 | 0 | } |
486 | 0 | else |
487 | 0 | return PyMethod_New(func, obj); |
488 | 0 | } |
489 | | |
490 | | static PyObject * |
491 | | instancemethod_richcompare(PyObject *self, PyObject *other, int op) |
492 | 0 | { |
493 | 0 | PyInstanceMethodObject *a, *b; |
494 | 0 | PyObject *res; |
495 | 0 | int eq; |
496 | |
|
497 | 0 | if ((op != Py_EQ && op != Py_NE) || |
498 | 0 | !PyInstanceMethod_Check(self) || |
499 | 0 | !PyInstanceMethod_Check(other)) |
500 | 0 | { |
501 | 0 | Py_RETURN_NOTIMPLEMENTED; |
502 | 0 | } |
503 | 0 | a = (PyInstanceMethodObject *)self; |
504 | 0 | b = (PyInstanceMethodObject *)other; |
505 | 0 | eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ); |
506 | 0 | if (eq < 0) |
507 | 0 | return NULL; |
508 | 0 | if (op == Py_EQ) |
509 | 0 | res = eq ? Py_True : Py_False; |
510 | 0 | else |
511 | 0 | res = eq ? Py_False : Py_True; |
512 | 0 | return Py_NewRef(res); |
513 | 0 | } |
514 | | |
515 | | static PyObject * |
516 | | instancemethod_repr(PyObject *self) |
517 | 0 | { |
518 | 0 | PyObject *func = PyInstanceMethod_Function(self); |
519 | 0 | PyObject *funcname, *result; |
520 | 0 | const char *defname = "?"; |
521 | |
|
522 | 0 | if (func == NULL) { |
523 | 0 | PyErr_BadInternalCall(); |
524 | 0 | return NULL; |
525 | 0 | } |
526 | | |
527 | 0 | if (PyObject_GetOptionalAttr(func, &_Py_ID(__name__), &funcname) < 0) { |
528 | 0 | return NULL; |
529 | 0 | } |
530 | 0 | if (funcname != NULL && !PyUnicode_Check(funcname)) { |
531 | 0 | Py_SETREF(funcname, NULL); |
532 | 0 | } |
533 | |
|
534 | 0 | result = PyUnicode_FromFormat("<instancemethod %V at %p>", |
535 | 0 | funcname, defname, self); |
536 | |
|
537 | 0 | Py_XDECREF(funcname); |
538 | 0 | return result; |
539 | 0 | } |
540 | | |
541 | | /*[clinic input] |
542 | | @classmethod |
543 | | instancemethod.__new__ as instancemethod_new |
544 | | function: object |
545 | | / |
546 | | |
547 | | Bind a function to a class. |
548 | | [clinic start generated code]*/ |
549 | | |
550 | | static PyObject * |
551 | | instancemethod_new_impl(PyTypeObject *type, PyObject *function) |
552 | | /*[clinic end generated code: output=5e0397b2bdb750be input=cfc54e8b973664a8]*/ |
553 | 0 | { |
554 | 0 | if (!PyCallable_Check(function)) { |
555 | 0 | PyErr_SetString(PyExc_TypeError, |
556 | 0 | "first argument must be callable"); |
557 | 0 | return NULL; |
558 | 0 | } |
559 | | |
560 | 0 | return PyInstanceMethod_New(function); |
561 | 0 | } |
562 | | |
563 | | PyTypeObject PyInstanceMethod_Type = { |
564 | | PyVarObject_HEAD_INIT(&PyType_Type, 0) |
565 | | .tp_name = "instancemethod", |
566 | | .tp_basicsize = sizeof(PyInstanceMethodObject), |
567 | | .tp_dealloc = instancemethod_dealloc, |
568 | | .tp_repr = instancemethod_repr, |
569 | | .tp_call = instancemethod_call, |
570 | | .tp_getattro = instancemethod_getattro, |
571 | | .tp_setattro = PyObject_GenericSetAttr, |
572 | | .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, |
573 | | .tp_doc = instancemethod_new__doc__, |
574 | | .tp_traverse = instancemethod_traverse, |
575 | | .tp_richcompare = instancemethod_richcompare, |
576 | | .tp_members = instancemethod_memberlist, |
577 | | .tp_getset = instancemethod_getset, |
578 | | .tp_descr_get = instancemethod_descr_get, |
579 | | .tp_new = instancemethod_new, |
580 | | }; |