diff options
author | Benjamin Peterson <benjamin@python.org> | 2009-05-16 21:44:25 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2009-05-16 21:44:25 (GMT) |
commit | fb6fb062e8f677dd63943f3a4b8a45c6665b3418 (patch) | |
tree | 47ebfca4866021ac2ed5499d7d1dd6ad944dde08 /Objects | |
parent | 757b3c90e63d323ae25cffbfce84112042320e58 (diff) | |
download | cpython-fb6fb062e8f677dd63943f3a4b8a45c6665b3418.zip cpython-fb6fb062e8f677dd63943f3a4b8a45c6665b3418.tar.gz cpython-fb6fb062e8f677dd63943f3a4b8a45c6665b3418.tar.bz2 |
properly lookup __instancecheck__ and __subclasscheck__
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/abstract.c | 38 | ||||
-rw-r--r-- | Objects/typeobject.c | 21 |
2 files changed, 29 insertions, 30 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 4da7e00..5fb7bfc 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2926,14 +2926,19 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls) Py_LeaveRecursiveCall(); return r; } - if (name == NULL) { - name = PyString_InternFromString("__instancecheck__"); - if (name == NULL) - return -1; + + if (PyInstance_Check(cls)) { + checker = PyObject_GetAttrString(cls, "__instancecheck__"); + if (checker == NULL) { + if (PyErr_ExceptionMatches(PyExc_AttributeError)) + PyErr_Clear(); + else + return -1; + } + } + else { + checker = _PyObject_LookupSpecial(cls, "__instancecheck__", &name); } - checker = PyObject_GetAttr(cls, name); - if (checker == NULL && PyErr_Occurred()) - PyErr_Clear(); if (checker != NULL) { PyObject *res; int ok = -1; @@ -3008,14 +3013,21 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls) Py_LeaveRecursiveCall(); return r; } - if (name == NULL) { - name = PyString_InternFromString("__subclasscheck__"); - if (name == NULL) + if (PyInstance_Check(cls)) { + PyErr_Fetch(&t, &v, &tb); + checker = PyObject_GetAttr(cls, name); + if (checker == NULL && + !PyErr_ExceptionMatches(PyExc_AttributeError)) { + Py_XDECREF(t); + Py_XDECREF(v); + Py_XDECREF(tb); return -1; + } + PyErr_Restore(t, v, tb); + } + else { + checker = _PyObject_LookupSpecial(cls, "__subclasscheck__", &name); } - PyErr_Fetch(&t, &v, &tb); - checker = PyObject_GetAttr(cls, name); - PyErr_Restore(t, v, tb); if (checker != NULL) { PyObject *res; int ok = -1; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index fabdd9d..8c49096 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -586,14 +586,6 @@ type___instancecheck__(PyObject *type, PyObject *inst) static PyObject * -type_get_instancecheck(PyObject *type, void *context) -{ - static PyMethodDef ml = {"__instancecheck__", - type___instancecheck__, METH_O }; - return PyCFunction_New(&ml, type); -} - -static PyObject * type___subclasscheck__(PyObject *type, PyObject *inst) { switch (_PyObject_RealIsSubclass(inst, type)) { @@ -606,13 +598,6 @@ type___subclasscheck__(PyObject *type, PyObject *inst) } } -static PyObject * -type_get_subclasscheck(PyObject *type, void *context) -{ - static PyMethodDef ml = {"__subclasscheck__", - type___subclasscheck__, METH_O }; - return PyCFunction_New(&ml, type); -} static PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, (setter)type_set_name, NULL}, @@ -622,8 +607,6 @@ static PyGetSetDef type_getsets[] = { (setter)type_set_abstractmethods, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, {"__doc__", (getter)type_get_doc, NULL, NULL}, - {"__instancecheck__", (getter)type_get_instancecheck, NULL, NULL}, - {"__subclasscheck__", (getter)type_get_subclasscheck, NULL, NULL}, {0} }; @@ -2674,6 +2657,10 @@ static PyMethodDef type_methods[] = { PyDoc_STR("mro() -> list\nreturn a type's method resolution order")}, {"__subclasses__", (PyCFunction)type_subclasses, METH_NOARGS, PyDoc_STR("__subclasses__() -> list of immediate subclasses")}, + {"__instancecheck__", type___instancecheck__, METH_O, + PyDoc_STR("__instancecheck__() -> check if an object is an instance")}, + {"__subclasscheck__", type___subclasscheck__, METH_O, + PyDoc_STR("__subclasschck__ -> check if an class is a subclass")}, {0} }; |