diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4235,6 +4235,22 @@ with self.assertRaises(AttributeError): del X.__abstractmethods__ + def test_methoddescr_raises_TypeError(self): + class FakeStr: + # This makes isinstance(FakeStr(), str) true + __class__ = str + + with self.assertRaises(TypeError): + str.split(FakeStr()) + + def test_wrapperdescr_raises_TypeError(self): + class FakeStr: + # This makes isinstance(FakeStr(), str) true + __class__ = str + + with self.assertRaises(TypeError): + str.__add__(FakeStr(), "") + class DictProxyTests(unittest.TestCase): def setUp(self): diff --git a/Objects/descrobject.c b/Objects/descrobject.c --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -226,7 +226,8 @@ return NULL; } self = PyTuple_GET_ITEM(args, 0); - if (!PyObject_IsInstance(self, (PyObject *)PyDescr_TYPE(descr))) { + if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), + (PyObject *)PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, "descriptor '%V' " "requires a '%.100s' object " @@ -284,7 +285,8 @@ return NULL; } self = PyTuple_GET_ITEM(args, 0); - if (!PyObject_IsInstance(self, (PyObject *)PyDescr_TYPE(descr))) { + if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), + (PyObject *)PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, "descriptor '%V' " "requires a '%.100s' object "