| 
									
										
										
										
											2006-08-17 05:42:55 +00:00
										 |  |  | /* Class object implementation (dead now except for methods) */ | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-21 22:27:47 +01:00
										 |  |  | #include "pycore_object.h"
 | 
					
						
							| 
									
										
										
										
											2019-11-08 10:05:17 +01:00
										 |  |  | #include "pycore_pyerrors.h"
 | 
					
						
							| 
									
										
										
										
											2020-04-15 02:35:41 +02:00
										 |  |  | #include "pycore_pystate.h"       // _PyThreadState_GET()
 | 
					
						
							|  |  |  | #include "structmember.h"         // PyMemberDef
 | 
					
						
							| 
									
										
										
										
											1992-08-12 15:35:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-27 21:53:35 +00:00
										 |  |  | #define TP_DESCR_GET(t) ((t)->tp_descr_get)
 | 
					
						
							| 
									
										
										
										
											2001-10-17 20:26:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-14 10:20:37 +02:00
										 |  |  | _Py_IDENTIFIER(__name__); | 
					
						
							| 
									
										
										
										
											2014-08-20 18:41:57 -05:00
										 |  |  | _Py_IDENTIFIER(__qualname__); | 
					
						
							| 
									
										
										
										
											2011-10-10 18:11:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-09-05 22:52:50 +00:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyMethod_Function(PyObject *im) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (!PyMethod_Check(im)) { | 
					
						
							|  |  |  |         PyErr_BadInternalCall(); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ((PyMethodObject *)im)->im_func; | 
					
						
							| 
									
										
										
										
											2001-09-05 22:52:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | PyMethod_Self(PyObject *im) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (!PyMethod_Check(im)) { | 
					
						
							|  |  |  |         PyErr_BadInternalCall(); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ((PyMethodObject *)im)->im_self; | 
					
						
							| 
									
										
										
										
											2001-09-05 22:52:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | method_vectorcall(PyObject *method, PyObject *const *args, | 
					
						
							|  |  |  |                   size_t nargsf, PyObject *kwnames) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-17 19:09:15 +09:00
										 |  |  |     assert(Py_IS_TYPE(method, &PyMethod_Type)); | 
					
						
							| 
									
										
										
										
											2019-11-08 10:05:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							|  |  |  |     PyObject *self = PyMethod_GET_SELF(method); | 
					
						
							|  |  |  |     PyObject *func = PyMethod_GET_FUNCTION(method); | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-08 10:05:17 +01:00
										 |  |  |     PyObject *result; | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) { | 
					
						
							|  |  |  |         /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */ | 
					
						
							|  |  |  |         PyObject **newargs = (PyObject**)args - 1; | 
					
						
							|  |  |  |         nargs += 1; | 
					
						
							|  |  |  |         PyObject *tmp = newargs[0]; | 
					
						
							|  |  |  |         newargs[0] = self; | 
					
						
							| 
									
										
										
										
											2019-11-08 10:05:17 +01:00
										 |  |  |         result = _PyObject_VectorcallTstate(tstate, func, newargs, | 
					
						
							|  |  |  |                                             nargs, kwnames); | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |         newargs[0] = tmp; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); | 
					
						
							|  |  |  |         Py_ssize_t totalargs = nargs + nkwargs; | 
					
						
							| 
									
										
										
										
											2019-07-03 12:54:00 +02:00
										 |  |  |         if (totalargs == 0) { | 
					
						
							| 
									
										
										
										
											2019-11-08 10:05:17 +01:00
										 |  |  |             return _PyObject_VectorcallTstate(tstate, func, &self, 1, NULL); | 
					
						
							| 
									
										
										
										
											2019-07-03 12:54:00 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-18 10:56:53 +02:00
										 |  |  |         PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK]; | 
					
						
							| 
									
										
										
										
											2019-07-03 12:54:00 +02:00
										 |  |  |         PyObject **newargs; | 
					
						
							| 
									
										
										
										
											2019-06-18 10:56:53 +02:00
										 |  |  |         if (totalargs <= (Py_ssize_t)Py_ARRAY_LENGTH(newargs_stack) - 1) { | 
					
						
							|  |  |  |             newargs = newargs_stack; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *)); | 
					
						
							|  |  |  |             if (newargs == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-08 10:05:17 +01:00
										 |  |  |                 _PyErr_NoMemory(tstate); | 
					
						
							| 
									
										
										
										
											2019-06-18 10:56:53 +02:00
										 |  |  |                 return NULL; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         /* use borrowed references */ | 
					
						
							|  |  |  |         newargs[0] = self; | 
					
						
							| 
									
										
										
										
											2019-07-03 12:54:00 +02:00
										 |  |  |         /* bpo-37138: since totalargs > 0, it's impossible that args is NULL.
 | 
					
						
							|  |  |  |          * We need this, since calling memcpy() with a NULL pointer is | 
					
						
							|  |  |  |          * undefined behaviour. */ | 
					
						
							|  |  |  |         assert(args != NULL); | 
					
						
							|  |  |  |         memcpy(newargs + 1, args, totalargs * sizeof(PyObject *)); | 
					
						
							| 
									
										
										
										
											2019-11-08 10:05:17 +01:00
										 |  |  |         result = _PyObject_VectorcallTstate(tstate, func, | 
					
						
							|  |  |  |                                             newargs, nargs+1, kwnames); | 
					
						
							| 
									
										
										
										
											2019-06-18 10:56:53 +02:00
										 |  |  |         if (newargs != newargs_stack) { | 
					
						
							|  |  |  |             PyMem_Free(newargs); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-27 10:40:20 +00:00
										 |  |  | /* Method objects are used for bound instance methods returned by
 | 
					
						
							|  |  |  |    instancename.methodname. ClassName.methodname returns an ordinary | 
					
						
							|  |  |  |    function. | 
					
						
							| 
									
										
										
										
											1993-05-20 14:24:46 +00:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyObject * | 
					
						
							| 
									
										
										
										
											2007-11-27 10:40:20 +00:00
										 |  |  | PyMethod_New(PyObject *func, PyObject *self) | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (self == NULL) { | 
					
						
							|  |  |  |         PyErr_BadInternalCall(); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-07-26 15:05:50 +09:00
										 |  |  |     PyMethodObject *im = PyObject_GC_New(PyMethodObject, &PyMethod_Type); | 
					
						
							|  |  |  |     if (im == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     im->im_weakreflist = NULL; | 
					
						
							|  |  |  |     Py_INCREF(func); | 
					
						
							|  |  |  |     im->im_func = func; | 
					
						
							| 
									
										
										
										
											2019-06-17 04:19:19 +08:00
										 |  |  |     Py_INCREF(self); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     im->im_self = self; | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     im->vectorcall = method_vectorcall; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     _PyObject_GC_TRACK(im); | 
					
						
							|  |  |  |     return (PyObject *)im; | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-23 18:59:12 +01:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2018-04-30 00:29:33 +05:30
										 |  |  | method_reduce(PyMethodObject *im, PyObject *Py_UNUSED(ignored)) | 
					
						
							| 
									
										
										
										
											2013-11-23 18:59:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject *self = PyMethod_GET_SELF(im); | 
					
						
							|  |  |  |     PyObject *func = PyMethod_GET_FUNCTION(im); | 
					
						
							|  |  |  |     PyObject *funcname; | 
					
						
							|  |  |  |     _Py_IDENTIFIER(getattr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     funcname = _PyObject_GetAttrId(func, &PyId___name__); | 
					
						
							|  |  |  |     if (funcname == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-12-11 08:28:18 +02:00
										 |  |  |     return Py_BuildValue("N(ON)", _PyEval_GetBuiltinId(&PyId_getattr), | 
					
						
							|  |  |  |                          self, funcname); | 
					
						
							| 
									
										
										
										
											2013-11-23 18:59:12 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef method_methods[] = { | 
					
						
							|  |  |  |     {"__reduce__", (PyCFunction)method_reduce, METH_NOARGS, NULL}, | 
					
						
							|  |  |  |     {NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-09-18 03:53:24 +00:00
										 |  |  | /* Descriptors for PyMethod attributes */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-27 10:40:20 +00:00
										 |  |  | /* im_func and im_self are stored in the PyMethod object */ | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | #define MO_OFF(x) offsetof(PyMethodObject, x)
 | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-24 00:41:19 +00:00
										 |  |  | static PyMemberDef method_memberlist[] = { | 
					
						
							| 
									
										
										
										
											2020-02-18 14:14:46 +01:00
										 |  |  |     {"__func__", T_OBJECT, MO_OFF(im_func), READONLY, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |      "the function (or other callable) implementing a method"}, | 
					
						
							| 
									
										
										
										
											2020-02-18 14:14:46 +01:00
										 |  |  |     {"__self__", T_OBJECT, MO_OFF(im_self), READONLY, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |      "the instance to which a method is bound"}, | 
					
						
							|  |  |  |     {NULL}      /* Sentinel */ | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-11-22 23:55:50 +00:00
										 |  |  | /* Christian Tismer argued convincingly that method attributes should
 | 
					
						
							|  |  |  |    (nearly) always override function attributes. | 
					
						
							|  |  |  |    The one exception is __doc__; there's a default __doc__ which | 
					
						
							|  |  |  |    should only be used for the class, not for instances */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2006-08-24 00:41:19 +00:00
										 |  |  | method_get_doc(PyMethodObject *im, void *context) | 
					
						
							| 
									
										
										
										
											2003-11-22 23:55:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     static PyObject *docstr; | 
					
						
							|  |  |  |     if (docstr == NULL) { | 
					
						
							|  |  |  |         docstr= PyUnicode_InternFromString("__doc__"); | 
					
						
							|  |  |  |         if (docstr == NULL) | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyObject_GetAttr(im->im_func, docstr); | 
					
						
							| 
									
										
										
										
											2003-11-22 23:55:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-24 00:41:19 +00:00
										 |  |  | static PyGetSetDef method_getset[] = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     {"__doc__", (getter)method_get_doc, NULL, NULL}, | 
					
						
							|  |  |  |     {0} | 
					
						
							| 
									
										
										
										
											2003-11-22 23:55:50 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2001-01-15 20:40:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2006-08-24 00:41:19 +00:00
										 |  |  | method_getattro(PyObject *obj, PyObject *name) | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyMethodObject *im = (PyMethodObject *)obj; | 
					
						
							| 
									
										
										
										
											2020-02-07 03:04:21 +01:00
										 |  |  |     PyTypeObject *tp = Py_TYPE(obj); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *descr = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (tp->tp_dict == NULL) { | 
					
						
							|  |  |  |             if (PyType_Ready(tp) < 0) | 
					
						
							|  |  |  |                 return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         descr = _PyType_Lookup(tp, name); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (descr != NULL) { | 
					
						
							| 
									
										
										
										
											2020-02-07 03:04:21 +01:00
										 |  |  |         descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr)); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         if (f != NULL) | 
					
						
							| 
									
										
										
										
											2020-02-07 03:04:21 +01:00
										 |  |  |             return f(descr, obj, (PyObject *)Py_TYPE(obj)); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         else { | 
					
						
							|  |  |  |             Py_INCREF(descr); | 
					
						
							|  |  |  |             return descr; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PyObject_GetAttr(im->im_func, name); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-24 00:41:19 +00:00
										 |  |  | PyDoc_STRVAR(method_doc, | 
					
						
							| 
									
										
										
										
											2007-11-27 10:40:20 +00:00
										 |  |  | "method(function, instance)\n\
 | 
					
						
							| 
									
										
										
										
											2002-06-14 20:41:17 +00:00
										 |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | Create a bound instance method object."); | 
					
						
							| 
									
										
										
										
											2002-06-14 20:41:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2006-08-24 00:41:19 +00:00
										 |  |  | method_new(PyTypeObject* type, PyObject* args, PyObject *kw) | 
					
						
							| 
									
										
										
										
											2002-06-14 20:41:17 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *func; | 
					
						
							|  |  |  |     PyObject *self; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!_PyArg_NoKeywords("method", kw)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     if (!PyArg_UnpackTuple(args, "method", 2, 2, | 
					
						
							|  |  |  |                           &func, &self)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     if (!PyCallable_Check(func)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                         "first argument must be callable"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (self == NULL || self == Py_None) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |             "self must not be None"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PyMethod_New(func, self); | 
					
						
							| 
									
										
										
										
											2002-06-14 20:41:17 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2013-08-13 20:18:52 +02:00
										 |  |  | method_dealloc(PyMethodObject *im) | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     _PyObject_GC_UNTRACK(im); | 
					
						
							|  |  |  |     if (im->im_weakreflist != NULL) | 
					
						
							|  |  |  |         PyObject_ClearWeakRefs((PyObject *)im); | 
					
						
							|  |  |  |     Py_DECREF(im->im_func); | 
					
						
							|  |  |  |     Py_XDECREF(im->im_self); | 
					
						
							| 
									
										
										
										
											2019-07-26 15:05:50 +09:00
										 |  |  |     PyObject_GC_Del(im); | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-24 00:41:19 +00:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | method_richcompare(PyObject *self, PyObject *other, int op) | 
					
						
							| 
									
										
										
										
											1992-09-03 20:39:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyMethodObject *a, *b; | 
					
						
							|  |  |  |     PyObject *res; | 
					
						
							|  |  |  |     int eq; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((op != Py_EQ && op != Py_NE) || | 
					
						
							|  |  |  |         !PyMethod_Check(self) || | 
					
						
							|  |  |  |         !PyMethod_Check(other)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-08-10 20:28:54 -05:00
										 |  |  |         Py_RETURN_NOTIMPLEMENTED; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     a = (PyMethodObject *)self; | 
					
						
							|  |  |  |     b = (PyMethodObject *)other; | 
					
						
							|  |  |  |     eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ); | 
					
						
							|  |  |  |     if (eq == 1) { | 
					
						
							| 
									
										
										
										
											2018-07-31 09:18:24 +03:00
										 |  |  |         eq = (a->im_self == b->im_self); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-07-31 09:18:24 +03:00
										 |  |  |     else if (eq < 0) | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     if (op == Py_EQ) | 
					
						
							|  |  |  |         res = eq ? Py_True : Py_False; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         res = eq ? Py_False : Py_True; | 
					
						
							|  |  |  |     Py_INCREF(res); | 
					
						
							|  |  |  |     return res; | 
					
						
							| 
									
										
										
										
											1992-09-03 20:39:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2006-08-24 00:41:19 +00:00
										 |  |  | method_repr(PyMethodObject *a) | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *self = a->im_self; | 
					
						
							|  |  |  |     PyObject *func = a->im_func; | 
					
						
							| 
									
										
										
										
											2018-01-25 10:49:40 +02:00
										 |  |  |     PyObject *funcname, *result; | 
					
						
							| 
									
										
										
										
											2014-08-20 18:41:57 -05:00
										 |  |  |     const char *defname = "?"; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-25 10:49:40 +02:00
										 |  |  |     if (_PyObject_LookupAttrId(func, &PyId___qualname__, &funcname) < 0 || | 
					
						
							|  |  |  |         (funcname == NULL && | 
					
						
							|  |  |  |          _PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2014-08-20 18:41:57 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-03-18 21:53:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 18:41:57 -05:00
										 |  |  |     if (funcname != NULL && !PyUnicode_Check(funcname)) { | 
					
						
							|  |  |  |         Py_DECREF(funcname); | 
					
						
							|  |  |  |         funcname = NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* XXX Shouldn't use repr()/%R here! */ | 
					
						
							| 
									
										
										
										
											2014-08-20 18:41:57 -05:00
										 |  |  |     result = PyUnicode_FromFormat("<bound method %V of %R>", | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                                   funcname, defname, self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_XDECREF(funcname); | 
					
						
							|  |  |  |     return result; | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-17 20:54:53 +00:00
										 |  |  | static Py_hash_t | 
					
						
							| 
									
										
										
										
											2006-08-24 00:41:19 +00:00
										 |  |  | method_hash(PyMethodObject *a) | 
					
						
							| 
									
										
										
										
											1993-03-29 10:43:31 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-17 20:54:53 +00:00
										 |  |  |     Py_hash_t x, y; | 
					
						
							| 
									
										
										
										
											2019-03-05 05:19:34 +00:00
										 |  |  |     x = _Py_HashPointer(a->im_self); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     y = PyObject_Hash(a->im_func); | 
					
						
							|  |  |  |     if (y == -1) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     x = x ^ y; | 
					
						
							|  |  |  |     if (x == -1) | 
					
						
							|  |  |  |         x = -2; | 
					
						
							|  |  |  |     return x; | 
					
						
							| 
									
										
										
										
											1993-03-29 10:43:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-06-23 14:18:11 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2006-08-24 00:41:19 +00:00
										 |  |  | method_traverse(PyMethodObject *im, visitproc visit, void *arg) | 
					
						
							| 
									
										
										
										
											2000-06-23 14:18:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_VISIT(im->im_func); | 
					
						
							|  |  |  |     Py_VISIT(im->im_self); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2000-06-23 14:18:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-15 17:52:31 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2006-08-24 00:41:19 +00:00
										 |  |  | method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls) | 
					
						
							| 
									
										
										
										
											2001-08-15 17:52:31 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-05 05:19:34 +00:00
										 |  |  |     Py_INCREF(meth); | 
					
						
							|  |  |  |     return meth; | 
					
						
							| 
									
										
										
										
											2001-08-15 17:52:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyTypeObject PyMethod_Type = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
					
						
							|  |  |  |     "method", | 
					
						
							|  |  |  |     sizeof(PyMethodObject), | 
					
						
							|  |  |  |     0, | 
					
						
							|  |  |  |     (destructor)method_dealloc,                 /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     offsetof(PyMethodObject, vectorcall),       /* tp_vectorcall_offset */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                          /* tp_getattr */ | 
					
						
							|  |  |  |     0,                                          /* tp_setattr */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                          /* tp_as_async */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     (reprfunc)method_repr,                      /* tp_repr */ | 
					
						
							|  |  |  |     0,                                          /* tp_as_number */ | 
					
						
							|  |  |  |     0,                                          /* tp_as_sequence */ | 
					
						
							|  |  |  |     0,                                          /* tp_as_mapping */ | 
					
						
							|  |  |  |     (hashfunc)method_hash,                      /* tp_hash */ | 
					
						
							| 
									
										
										
										
											2019-06-18 10:50:28 +02:00
										 |  |  |     PyVectorcall_Call,                          /* tp_call */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                          /* tp_str */ | 
					
						
							|  |  |  |     method_getattro,                            /* tp_getattro */ | 
					
						
							|  |  |  |     PyObject_GenericSetAttr,                    /* tp_setattro */ | 
					
						
							|  |  |  |     0,                                          /* tp_as_buffer */ | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | | 
					
						
							| 
									
										
										
										
											2020-02-11 17:46:57 +01:00
										 |  |  |     Py_TPFLAGS_HAVE_VECTORCALL,                 /* tp_flags */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     method_doc,                                 /* tp_doc */ | 
					
						
							|  |  |  |     (traverseproc)method_traverse,              /* tp_traverse */ | 
					
						
							|  |  |  |     0,                                          /* tp_clear */ | 
					
						
							|  |  |  |     method_richcompare,                         /* tp_richcompare */ | 
					
						
							|  |  |  |     offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */ | 
					
						
							|  |  |  |     0,                                          /* tp_iter */ | 
					
						
							|  |  |  |     0,                                          /* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2013-11-23 18:59:12 +01:00
										 |  |  |     method_methods,                             /* tp_methods */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     method_memberlist,                          /* tp_members */ | 
					
						
							|  |  |  |     method_getset,                              /* tp_getset */ | 
					
						
							|  |  |  |     0,                                          /* tp_base */ | 
					
						
							|  |  |  |     0,                                          /* tp_dict */ | 
					
						
							|  |  |  |     method_descr_get,                           /* tp_descr_get */ | 
					
						
							|  |  |  |     0,                                          /* tp_descr_set */ | 
					
						
							|  |  |  |     0,                                          /* tp_dictoffset */ | 
					
						
							|  |  |  |     0,                                          /* tp_init */ | 
					
						
							|  |  |  |     0,                                          /* tp_alloc */ | 
					
						
							|  |  |  |     method_new,                                 /* tp_new */ | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											1997-08-05 02:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | /* ------------------------------------------------------------------------
 | 
					
						
							|  |  |  |  * instance method | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | PyInstanceMethod_New(PyObject *func) { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyInstanceMethodObject *method; | 
					
						
							|  |  |  |     method = PyObject_GC_New(PyInstanceMethodObject, | 
					
						
							|  |  |  |                              &PyInstanceMethod_Type); | 
					
						
							|  |  |  |     if (method == NULL) return NULL; | 
					
						
							|  |  |  |     Py_INCREF(func); | 
					
						
							|  |  |  |     method->func = func; | 
					
						
							|  |  |  |     _PyObject_GC_TRACK(method); | 
					
						
							|  |  |  |     return (PyObject *)method; | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | PyInstanceMethod_Function(PyObject *im) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (!PyInstanceMethod_Check(im)) { | 
					
						
							|  |  |  |         PyErr_BadInternalCall(); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyInstanceMethod_GET_FUNCTION(im); | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define IMO_OFF(x) offsetof(PyInstanceMethodObject, x)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMemberDef instancemethod_memberlist[] = { | 
					
						
							| 
									
										
										
										
											2020-02-18 14:14:46 +01:00
										 |  |  |     {"__func__", T_OBJECT, IMO_OFF(func), READONLY, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |      "the function (or other callable) implementing a method"}, | 
					
						
							|  |  |  |     {NULL}      /* Sentinel */ | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | instancemethod_get_doc(PyObject *self, void *context) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     static PyObject *docstr; | 
					
						
							|  |  |  |     if (docstr == NULL) { | 
					
						
							|  |  |  |         docstr = PyUnicode_InternFromString("__doc__"); | 
					
						
							|  |  |  |         if (docstr == NULL) | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), docstr); | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyGetSetDef instancemethod_getset[] = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     {"__doc__", (getter)instancemethod_get_doc, NULL, NULL}, | 
					
						
							|  |  |  |     {0} | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | instancemethod_getattro(PyObject *self, PyObject *name) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-07 03:04:21 +01:00
										 |  |  |     PyTypeObject *tp = Py_TYPE(self); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *descr = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (tp->tp_dict == NULL) { | 
					
						
							|  |  |  |         if (PyType_Ready(tp) < 0) | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     descr = _PyType_Lookup(tp, name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (descr != NULL) { | 
					
						
							| 
									
										
										
										
											2020-02-07 03:04:21 +01:00
										 |  |  |         descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr)); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         if (f != NULL) | 
					
						
							| 
									
										
										
										
											2020-02-07 03:04:21 +01:00
										 |  |  |             return f(descr, self, (PyObject *)Py_TYPE(self)); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         else { | 
					
						
							|  |  |  |             Py_INCREF(descr); | 
					
						
							|  |  |  |             return descr; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name); | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | instancemethod_dealloc(PyObject *self) { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     _PyObject_GC_UNTRACK(self); | 
					
						
							|  |  |  |     Py_DECREF(PyInstanceMethod_GET_FUNCTION(self)); | 
					
						
							|  |  |  |     PyObject_GC_Del(self); | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | instancemethod_traverse(PyObject *self, visitproc visit, void *arg) { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_VISIT(PyInstanceMethod_GET_FUNCTION(self)); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return PyObject_Call(PyMethod_GET_FUNCTION(self), arg, kw); | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) { | 
					
						
							| 
									
										
										
										
											2013-08-13 20:18:52 +02:00
										 |  |  |     PyObject *func = PyInstanceMethod_GET_FUNCTION(descr); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (obj == NULL) { | 
					
						
							|  |  |  |         Py_INCREF(func); | 
					
						
							|  |  |  |         return func; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         return PyMethod_New(func, obj); | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | instancemethod_richcompare(PyObject *self, PyObject *other, int op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyInstanceMethodObject *a, *b; | 
					
						
							|  |  |  |     PyObject *res; | 
					
						
							|  |  |  |     int eq; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((op != Py_EQ && op != Py_NE) || | 
					
						
							|  |  |  |         !PyInstanceMethod_Check(self) || | 
					
						
							|  |  |  |         !PyInstanceMethod_Check(other)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-08-10 20:28:54 -05:00
										 |  |  |         Py_RETURN_NOTIMPLEMENTED; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     a = (PyInstanceMethodObject *)self; | 
					
						
							|  |  |  |     b = (PyInstanceMethodObject *)other; | 
					
						
							|  |  |  |     eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ); | 
					
						
							|  |  |  |     if (eq < 0) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     if (op == Py_EQ) | 
					
						
							|  |  |  |         res = eq ? Py_True : Py_False; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         res = eq ? Py_False : Py_True; | 
					
						
							|  |  |  |     Py_INCREF(res); | 
					
						
							|  |  |  |     return res; | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | instancemethod_repr(PyObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *func = PyInstanceMethod_Function(self); | 
					
						
							| 
									
										
										
										
											2018-01-25 10:49:40 +02:00
										 |  |  |     PyObject *funcname, *result; | 
					
						
							| 
									
										
										
										
											2017-11-11 13:06:26 +02:00
										 |  |  |     const char *defname = "?"; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (func == NULL) { | 
					
						
							|  |  |  |         PyErr_BadInternalCall(); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-25 10:49:40 +02:00
										 |  |  |     if (_PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-25 10:49:40 +02:00
										 |  |  |     if (funcname != NULL && !PyUnicode_Check(funcname)) { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         Py_DECREF(funcname); | 
					
						
							|  |  |  |         funcname = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     result = PyUnicode_FromFormat("<instancemethod %V at %p>", | 
					
						
							|  |  |  |                                   funcname, defname, self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_XDECREF(funcname); | 
					
						
							|  |  |  |     return result; | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | static long | 
					
						
							|  |  |  | instancemethod_hash(PyObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     long x, y; | 
					
						
							|  |  |  |     x = (long)self; | 
					
						
							|  |  |  |     y = PyObject_Hash(PyInstanceMethod_GET_FUNCTION(self)); | 
					
						
							|  |  |  |     if (y == -1) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     x = x ^ y; | 
					
						
							|  |  |  |     if (x == -1) | 
					
						
							|  |  |  |         x = -2; | 
					
						
							|  |  |  |     return x; | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(instancemethod_doc, | 
					
						
							|  |  |  | "instancemethod(function)\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Bind a function to a class."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *func; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!_PyArg_NoKeywords("instancemethod", kw)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     if (!PyArg_UnpackTuple(args, "instancemethod", 1, 1, &func)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     if (!PyCallable_Check(func)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                         "first argument must be callable"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PyInstanceMethod_New(func); | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyTypeObject PyInstanceMethod_Type = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
					
						
							|  |  |  |     "instancemethod",                           /* tp_name */ | 
					
						
							|  |  |  |     sizeof(PyInstanceMethodObject),             /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                          /* tp_itemsize */ | 
					
						
							|  |  |  |     instancemethod_dealloc,                     /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                          /* tp_vectorcall_offset */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                          /* tp_getattr */ | 
					
						
							|  |  |  |     0,                                          /* tp_setattr */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                          /* tp_as_async */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     (reprfunc)instancemethod_repr,              /* tp_repr */ | 
					
						
							|  |  |  |     0,                                          /* tp_as_number */ | 
					
						
							|  |  |  |     0,                                          /* tp_as_sequence */ | 
					
						
							|  |  |  |     0,                                          /* tp_as_mapping */ | 
					
						
							|  |  |  |     0, /*(hashfunc)instancemethod_hash,         tp_hash  */ | 
					
						
							|  |  |  |     instancemethod_call,                        /* tp_call */ | 
					
						
							|  |  |  |     0,                                          /* tp_str */ | 
					
						
							|  |  |  |     instancemethod_getattro,                    /* tp_getattro */ | 
					
						
							|  |  |  |     PyObject_GenericSetAttr,                    /* tp_setattro */ | 
					
						
							|  |  |  |     0,                                          /* tp_as_buffer */ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | 
					
						
							|  |  |  |         | Py_TPFLAGS_HAVE_GC,                   /* tp_flags */ | 
					
						
							|  |  |  |     instancemethod_doc,                         /* tp_doc */ | 
					
						
							|  |  |  |     instancemethod_traverse,                    /* tp_traverse */ | 
					
						
							|  |  |  |     0,                                          /* tp_clear */ | 
					
						
							|  |  |  |     instancemethod_richcompare,                 /* tp_richcompare */ | 
					
						
							|  |  |  |     0,                                          /* tp_weaklistoffset */ | 
					
						
							|  |  |  |     0,                                          /* tp_iter */ | 
					
						
							|  |  |  |     0,                                          /* tp_iternext */ | 
					
						
							|  |  |  |     0,                                          /* tp_methods */ | 
					
						
							|  |  |  |     instancemethod_memberlist,                  /* tp_members */ | 
					
						
							|  |  |  |     instancemethod_getset,                      /* tp_getset */ | 
					
						
							|  |  |  |     0,                                          /* tp_base */ | 
					
						
							|  |  |  |     0,                                          /* tp_dict */ | 
					
						
							|  |  |  |     instancemethod_descr_get,                   /* tp_descr_get */ | 
					
						
							|  |  |  |     0,                                          /* tp_descr_set */ | 
					
						
							|  |  |  |     0,                                          /* tp_dictoffset */ | 
					
						
							|  |  |  |     0,                                          /* tp_init */ | 
					
						
							|  |  |  |     0,                                          /* tp_alloc */ | 
					
						
							|  |  |  |     instancemethod_new,                         /* tp_new */ | 
					
						
							| 
									
										
										
										
											2007-12-11 19:56:40 +00:00
										 |  |  | }; |