| /* Class object implementation (dead now except for methods) */ | 
 |  | 
 | #include "Python.h" | 
 | #include "structmember.h" | 
 |  | 
 | #define TP_DESCR_GET(t) ((t)->tp_descr_get) | 
 |  | 
 |  | 
 | PyObject * | 
 | PyMethod_Function(PyObject *im) | 
 | { | 
 | 	if (!PyMethod_Check(im)) { | 
 | 		PyErr_BadInternalCall(); | 
 | 		return NULL; | 
 | 	} | 
 | 	return ((PyMethodObject *)im)->im_func; | 
 | } | 
 |  | 
 | PyObject * | 
 | PyMethod_Self(PyObject *im) | 
 | { | 
 | 	if (!PyMethod_Check(im)) { | 
 | 		PyErr_BadInternalCall(); | 
 | 		return NULL; | 
 | 	} | 
 | 	return ((PyMethodObject *)im)->im_self; | 
 | } | 
 |  | 
 | PyObject * | 
 | PyMethod_Class(PyObject *im) | 
 | { | 
 | 	if (!PyMethod_Check(im)) { | 
 | 		PyErr_BadInternalCall(); | 
 | 		return NULL; | 
 | 	} | 
 | 	return ((PyMethodObject *)im)->im_class; | 
 | } | 
 |  | 
 |  | 
 | /* Method objects are used for two purposes: | 
 |    (a) as bound instance methods (returned by instancename.methodname) | 
 |    (b) as unbound methods (returned by ClassName.methodname) | 
 |    In case (b), im_self is NULL | 
 | */ | 
 |  | 
 | static PyMethodObject *free_list; | 
 |  | 
 | PyObject * | 
 | PyMethod_New(PyObject *func, PyObject *self, PyObject *klass) | 
 | { | 
 | 	register PyMethodObject *im; | 
 | 	if (!PyCallable_Check(func)) { | 
 | 		PyErr_BadInternalCall(); | 
 | 		return NULL; | 
 | 	} | 
 | 	im = free_list; | 
 | 	if (im != NULL) { | 
 | 		free_list = (PyMethodObject *)(im->im_self); | 
 | 		PyObject_INIT(im, &PyMethod_Type); | 
 | 	} | 
 | 	else { | 
 | 		im = PyObject_GC_New(PyMethodObject, &PyMethod_Type); | 
 | 		if (im == NULL) | 
 | 			return NULL; | 
 | 	} | 
 | 	im->im_weakreflist = NULL; | 
 | 	Py_INCREF(func); | 
 | 	im->im_func = func; | 
 | 	Py_XINCREF(self); | 
 | 	im->im_self = self; | 
 | 	Py_XINCREF(klass); | 
 | 	im->im_class = klass; | 
 | 	_PyObject_GC_TRACK(im); | 
 | 	return (PyObject *)im; | 
 | } | 
 |  | 
 | /* Descriptors for PyMethod attributes */ | 
 |  | 
 | /* im_class, im_func and im_self are stored in the PyMethod object */ | 
 |  | 
 | #define OFF(x) offsetof(PyMethodObject, x) | 
 |  | 
 | static PyMemberDef method_memberlist[] = { | 
 | 	{"im_class",	T_OBJECT,	OFF(im_class),	READONLY|RESTRICTED, | 
 | 	 "the class associated with a method"}, | 
 | 	{"im_func",	T_OBJECT,	OFF(im_func),	READONLY|RESTRICTED, | 
 | 	 "the function (or other callable) implementing a method"}, | 
 | 	{"im_self",	T_OBJECT,	OFF(im_self),	READONLY|RESTRICTED, | 
 | 	 "the instance to which a method is bound; None for unbound methods"}, | 
 | 	{NULL}	/* Sentinel */ | 
 | }; | 
 |  | 
 | /* 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 * | 
 | method_get_doc(PyMethodObject *im, void *context) | 
 | { | 
 | 	static PyObject *docstr; | 
 | 	if (docstr == NULL) { | 
 | 		docstr= PyString_InternFromString("__doc__"); | 
 | 		if (docstr == NULL) | 
 | 			return NULL; | 
 | 	} | 
 | 	return PyObject_GetAttr(im->im_func, docstr); | 
 | } | 
 |  | 
 | static PyGetSetDef method_getset[] = { | 
 | 	{"__doc__", (getter)method_get_doc, NULL, NULL}, | 
 | 	{0} | 
 | }; | 
 |  | 
 | static PyObject * | 
 | method_getattro(PyObject *obj, PyObject *name) | 
 | { | 
 | 	PyMethodObject *im = (PyMethodObject *)obj; | 
 | 	PyTypeObject *tp = obj->ob_type; | 
 | 	PyObject *descr = NULL; | 
 |  | 
 | 	{ | 
 | 		if (tp->tp_dict == NULL) { | 
 | 			if (PyType_Ready(tp) < 0) | 
 | 				return NULL; | 
 | 		} | 
 | 		descr = _PyType_Lookup(tp, name); | 
 | 	} | 
 |  | 
 | 	if (descr != NULL) { | 
 | 		descrgetfunc f = TP_DESCR_GET(descr->ob_type); | 
 | 		if (f != NULL) | 
 | 			return f(descr, obj, (PyObject *)obj->ob_type); | 
 | 		else { | 
 | 			Py_INCREF(descr); | 
 | 			return descr; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return PyObject_GetAttr(im->im_func, name); | 
 | } | 
 |  | 
 | PyDoc_STRVAR(method_doc, | 
 | "method(function, instance, class)\n\ | 
 | \n\ | 
 | Create an instance method object."); | 
 |  | 
 | static PyObject * | 
 | method_new(PyTypeObject* type, PyObject* args, PyObject *kw) | 
 | { | 
 | 	PyObject *func; | 
 | 	PyObject *self; | 
 | 	PyObject *classObj = NULL; | 
 |  | 
 | 	if (!_PyArg_NoKeywords("instancemethod", kw)) | 
 | 		return NULL; | 
 | 	if (!PyArg_UnpackTuple(args, "method", 2, 3, | 
 | 			      &func, &self, &classObj)) | 
 | 		return NULL; | 
 | 	if (!PyCallable_Check(func)) { | 
 | 		PyErr_SetString(PyExc_TypeError, | 
 | 				"first argument must be callable"); | 
 | 		return NULL; | 
 | 	} | 
 | 	if (self == Py_None) | 
 | 		self = NULL; | 
 | 	if (self == NULL && classObj == NULL) { | 
 | 		PyErr_SetString(PyExc_TypeError, | 
 | 			"unbound methods must have non-NULL im_class"); | 
 | 		return NULL; | 
 | 	} | 
 |  | 
 | 	return PyMethod_New(func, self, classObj); | 
 | } | 
 |  | 
 | static void | 
 | method_dealloc(register PyMethodObject *im) | 
 | { | 
 | 	_PyObject_GC_UNTRACK(im); | 
 | 	if (im->im_weakreflist != NULL) | 
 | 		PyObject_ClearWeakRefs((PyObject *)im); | 
 | 	Py_DECREF(im->im_func); | 
 | 	Py_XDECREF(im->im_self); | 
 | 	Py_XDECREF(im->im_class); | 
 | 	im->im_self = (PyObject *)free_list; | 
 | 	free_list = im; | 
 | } | 
 |  | 
 | static PyObject * | 
 | method_richcompare(PyObject *self, PyObject *other, int op) | 
 | { | 
 | 	PyMethodObject *a, *b; | 
 | 	PyObject *res; | 
 | 	int eq; | 
 |  | 
 | 	if ((op != Py_EQ && op != Py_NE) || | 
 | 	    !PyMethod_Check(self) || | 
 | 	    !PyMethod_Check(other)) | 
 | 	{ | 
 | 		Py_INCREF(Py_NotImplemented); | 
 | 		return Py_NotImplemented; | 
 | 	} | 
 | 	a = (PyMethodObject *)self; | 
 | 	b = (PyMethodObject *)other; | 
 | 	eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ); | 
 | 	if (eq == 1) { | 
 | 		if (a->im_self == NULL || b->im_self == NULL) | 
 | 			eq = a->im_self == b->im_self; | 
 | 		else | 
 | 			eq = PyObject_RichCompareBool(a->im_self, b->im_self, | 
 | 						      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; | 
 | } | 
 |  | 
 | static PyObject * | 
 | method_repr(PyMethodObject *a) | 
 | { | 
 | 	PyObject *self = a->im_self; | 
 | 	PyObject *func = a->im_func; | 
 | 	PyObject *klass = a->im_class; | 
 | 	PyObject *funcname = NULL, *klassname = NULL, *result = NULL; | 
 | 	char *sfuncname = "?", *sklassname = "?"; | 
 |  | 
 | 	funcname = PyObject_GetAttrString(func, "__name__"); | 
 | 	if (funcname == NULL) { | 
 | 		if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | 
 | 			return NULL; | 
 | 		PyErr_Clear(); | 
 | 	} | 
 | 	else if (!PyString_Check(funcname)) { | 
 | 		Py_DECREF(funcname); | 
 | 		funcname = NULL; | 
 | 	} | 
 | 	else | 
 | 		sfuncname = PyString_AS_STRING(funcname); | 
 | 	if (klass == NULL) | 
 | 		klassname = NULL; | 
 | 	else { | 
 | 		klassname = PyObject_GetAttrString(klass, "__name__"); | 
 | 		if (klassname == NULL) { | 
 | 			if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | 
 | 				return NULL; | 
 | 			PyErr_Clear(); | 
 | 		} | 
 | 		else if (!PyString_Check(klassname)) { | 
 | 			Py_DECREF(klassname); | 
 | 			klassname = NULL; | 
 | 		} | 
 | 		else | 
 | 			sklassname = PyString_AS_STRING(klassname); | 
 | 	} | 
 | 	if (self == NULL) | 
 | 		result = PyString_FromFormat("<unbound method %s.%s>", | 
 | 					     sklassname, sfuncname); | 
 | 	else { | 
 | 		/* XXX Shouldn't use repr() here! */ | 
 | 		PyObject *selfrepr = PyObject_Repr(self); | 
 | 		if (selfrepr == NULL) | 
 | 			goto fail; | 
 | 		if (!PyString_Check(selfrepr)) { | 
 | 			Py_DECREF(selfrepr); | 
 | 			goto fail; | 
 | 		} | 
 | 		result = PyString_FromFormat("<bound method %s.%s of %s>", | 
 | 					     sklassname, sfuncname, | 
 | 					     PyString_AS_STRING(selfrepr)); | 
 | 		Py_DECREF(selfrepr); | 
 | 	} | 
 |   fail: | 
 | 	Py_XDECREF(funcname); | 
 | 	Py_XDECREF(klassname); | 
 | 	return result; | 
 | } | 
 |  | 
 | static long | 
 | method_hash(PyMethodObject *a) | 
 | { | 
 | 	long x, y; | 
 | 	if (a->im_self == NULL) | 
 | 		x = PyObject_Hash(Py_None); | 
 | 	else | 
 | 		x = PyObject_Hash(a->im_self); | 
 | 	if (x == -1) | 
 | 		return -1; | 
 | 	y = PyObject_Hash(a->im_func); | 
 | 	if (y == -1) | 
 | 		return -1; | 
 | 	x = x ^ y; | 
 | 	if (x == -1) | 
 | 		x = -2; | 
 | 	return x; | 
 | } | 
 |  | 
 | static int | 
 | method_traverse(PyMethodObject *im, visitproc visit, void *arg) | 
 | { | 
 | 	Py_VISIT(im->im_func); | 
 | 	Py_VISIT(im->im_self); | 
 | 	Py_VISIT(im->im_class); | 
 | 	return 0; | 
 | } | 
 |  | 
 | static void | 
 | getclassname(PyObject *klass, char *buf, int bufsize) | 
 | { | 
 | 	PyObject *name; | 
 |  | 
 | 	assert(bufsize > 1); | 
 | 	strcpy(buf, "?"); /* Default outcome */ | 
 | 	if (klass == NULL) | 
 | 		return; | 
 | 	name = PyObject_GetAttrString(klass, "__name__"); | 
 | 	if (name == NULL) { | 
 | 		/* This function cannot return an exception */ | 
 | 		PyErr_Clear(); | 
 | 		return; | 
 | 	} | 
 | 	if (PyString_Check(name)) { | 
 | 		strncpy(buf, PyString_AS_STRING(name), bufsize); | 
 | 		buf[bufsize-1] = '\0'; | 
 | 	} | 
 | 	Py_DECREF(name); | 
 | } | 
 |  | 
 | static void | 
 | getinstclassname(PyObject *inst, char *buf, int bufsize) | 
 | { | 
 | 	PyObject *klass; | 
 |  | 
 | 	if (inst == NULL) { | 
 | 		assert(bufsize > 0 && (size_t)bufsize > strlen("nothing")); | 
 | 		strcpy(buf, "nothing"); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	klass = PyObject_GetAttrString(inst, "__class__"); | 
 | 	if (klass == NULL) { | 
 | 		/* This function cannot return an exception */ | 
 | 		PyErr_Clear(); | 
 | 		klass = (PyObject *)(inst->ob_type); | 
 | 		Py_INCREF(klass); | 
 | 	} | 
 | 	getclassname(klass, buf, bufsize); | 
 | 	Py_XDECREF(klass); | 
 | } | 
 |  | 
 | static PyObject * | 
 | method_call(PyObject *func, PyObject *arg, PyObject *kw) | 
 | { | 
 | 	PyObject *self = PyMethod_GET_SELF(func); | 
 | 	PyObject *klass = PyMethod_GET_CLASS(func); | 
 | 	PyObject *result; | 
 |  | 
 | 	func = PyMethod_GET_FUNCTION(func); | 
 | 	if (self == NULL) { | 
 | 		/* Unbound methods must be called with an instance of | 
 | 		   the class (or a derived class) as first argument */ | 
 | 		int ok; | 
 | 		if (PyTuple_Size(arg) >= 1) | 
 | 			self = PyTuple_GET_ITEM(arg, 0); | 
 | 		if (self == NULL) | 
 | 			ok = 0; | 
 | 		else { | 
 | 			ok = PyObject_IsInstance(self, klass); | 
 | 			if (ok < 0) | 
 | 				return NULL; | 
 | 		} | 
 | 		if (!ok) { | 
 | 			char clsbuf[256]; | 
 | 			char instbuf[256]; | 
 | 			getclassname(klass, clsbuf, sizeof(clsbuf)); | 
 | 			getinstclassname(self, instbuf, sizeof(instbuf)); | 
 | 			PyErr_Format(PyExc_TypeError, | 
 | 				     "unbound method %s%s must be called with " | 
 | 				     "%s instance as first argument " | 
 | 				     "(got %s%s instead)", | 
 | 				     PyEval_GetFuncName(func), | 
 | 				     PyEval_GetFuncDesc(func), | 
 | 				     clsbuf, | 
 | 				     instbuf, | 
 | 				     self == NULL ? "" : " instance"); | 
 | 			return NULL; | 
 | 		} | 
 | 		Py_INCREF(arg); | 
 | 	} | 
 | 	else { | 
 | 		Py_ssize_t argcount = PyTuple_Size(arg); | 
 | 		PyObject *newarg = PyTuple_New(argcount + 1); | 
 | 		int i; | 
 | 		if (newarg == NULL) | 
 | 			return NULL; | 
 | 		Py_INCREF(self); | 
 | 		PyTuple_SET_ITEM(newarg, 0, self); | 
 | 		for (i = 0; i < argcount; i++) { | 
 | 			PyObject *v = PyTuple_GET_ITEM(arg, i); | 
 | 			Py_XINCREF(v); | 
 | 			PyTuple_SET_ITEM(newarg, i+1, v); | 
 | 		} | 
 | 		arg = newarg; | 
 | 	} | 
 | 	result = PyObject_Call((PyObject *)func, arg, kw); | 
 | 	Py_DECREF(arg); | 
 | 	return result; | 
 | } | 
 |  | 
 | static PyObject * | 
 | method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls) | 
 | { | 
 | 	/* Don't rebind an already bound method, or an unbound method | 
 | 	   of a class that's not a base class of cls. */ | 
 |  | 
 | 	if (PyMethod_GET_SELF(meth) != NULL) { | 
 | 		/* Already bound */ | 
 | 		Py_INCREF(meth); | 
 | 		return meth; | 
 | 	} | 
 | 	/* No, it is an unbound method */ | 
 | 	if (PyMethod_GET_CLASS(meth) != NULL && cls != NULL) { | 
 | 		/* Do subclass test.  If it fails, return meth unchanged. */ | 
 | 		int ok = PyObject_IsSubclass(cls, PyMethod_GET_CLASS(meth)); | 
 | 		if (ok < 0) | 
 | 			return NULL; | 
 | 		if (!ok) { | 
 | 			Py_INCREF(meth); | 
 | 			return meth; | 
 | 		} | 
 | 	} | 
 | 	/* Bind it to obj */ | 
 | 	return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, cls); | 
 | } | 
 |  | 
 | PyTypeObject PyMethod_Type = { | 
 | 	PyObject_HEAD_INIT(&PyType_Type) | 
 | 	0, | 
 | 	"method", | 
 | 	sizeof(PyMethodObject), | 
 | 	0, | 
 | 	(destructor)method_dealloc,		/* tp_dealloc */ | 
 | 	0,					/* tp_print */ | 
 | 	0,					/* tp_getattr */ | 
 | 	0,					/* tp_setattr */ | 
 | 	0,					/* tp_compare */ | 
 | 	(reprfunc)method_repr,			/* tp_repr */ | 
 | 	0,					/* tp_as_number */ | 
 | 	0,					/* tp_as_sequence */ | 
 | 	0,					/* tp_as_mapping */ | 
 | 	(hashfunc)method_hash,			/* tp_hash */ | 
 | 	method_call,				/* tp_call */ | 
 | 	0,					/* tp_str */ | 
 | 	method_getattro,			/* tp_getattro */ | 
 | 	PyObject_GenericSetAttr,		/* tp_setattro */ | 
 | 	0,					/* tp_as_buffer */ | 
 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ | 
 | 	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 */ | 
 | 	0,					/* tp_methods */ | 
 | 	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 */ | 
 | }; | 
 |  | 
 | /* Clear out the free list */ | 
 |  | 
 | void | 
 | PyMethod_Fini(void) | 
 | { | 
 | 	while (free_list) { | 
 | 		PyMethodObject *im = free_list; | 
 | 		free_list = (PyMethodObject *)(im->im_self); | 
 | 		PyObject_GC_Del(im); | 
 | 	} | 
 | } |