Refactor instancemethod_descr_get() to (a) be more clear, (b) be safe

in the light of weird args, and (c) not to expect None (which is now
changed to NULL by slot_tp_descr_get()).
This commit is contained in:
Guido van Rossum 2003-02-11 18:43:00 +00:00
parent 5f322d3dfd
commit 6bae46d8c1
1 changed files with 18 additions and 8 deletions

View File

@ -2414,19 +2414,29 @@ instancemethod_call(PyObject *func, PyObject *arg, PyObject *kw)
}
static PyObject *
instancemethod_descr_get(PyObject *meth, PyObject *obj, PyObject *class)
instancemethod_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 class */
if (PyMethod_GET_SELF(meth) != NULL ||
(PyMethod_GET_CLASS(meth) != NULL &&
!PyObject_IsSubclass(class, PyMethod_GET_CLASS(meth)))) {
of a class that's not a base class of cls. */
if (PyMethod_GET_SELF(meth) != NULL) {
/* Already bound */
Py_INCREF(meth);
return meth;
}
if (obj == Py_None)
obj = NULL;
return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, class);
/* 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 = {