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 * 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 /* Don't rebind an already bound method, or an unbound method
of a class that's not a base class of class */ of a class that's not a base class of cls. */
if (PyMethod_GET_SELF(meth) != NULL ||
(PyMethod_GET_CLASS(meth) != NULL && if (PyMethod_GET_SELF(meth) != NULL) {
!PyObject_IsSubclass(class, PyMethod_GET_CLASS(meth)))) { /* Already bound */
Py_INCREF(meth); Py_INCREF(meth);
return meth; return meth;
} }
if (obj == Py_None) /* No, it is an unbound method */
obj = NULL; if (PyMethod_GET_CLASS(meth) != NULL && cls != NULL) {
return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, class); /* 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 = { PyTypeObject PyMethod_Type = {