diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 39d57c5f5b61c9..24d57965b3f814 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -909,6 +909,40 @@ def __subclasscheck__(cls, sub): self.assertIsSubclass(int, x) self.assertRaises(ZeroDivisionError, issubclass, list, x) + def test_custom_instancecheck(self): + class CustomIsInstanceMeta(type): + def __instancecheck__(cls, instance): + return type(instance) is int + + class CustomIsInstance(metaclass=CustomIsInstanceMeta): + ... + + class CustomIsInstanceSubclass(CustomIsInstance): + ... + + self.assertTrue(isinstance(5, CustomIsInstance)) + self.assertFalse(isinstance(CustomIsInstance(), CustomIsInstance)) + self.assertFalse(isinstance(CustomIsInstanceSubclass(), CustomIsInstance)) + + def test_custom_subclasscheck(self): + class CustomIsSubclassMeta(type): + def __subclasscheck__(cls, subcls): + return subcls is int + + class CustomIsSubclass(metaclass=CustomIsSubclassMeta): + ... + + class CustomIsSubclassSubclass(CustomIsSubclass): + ... + + self.assertTrue(issubclass(int, CustomIsSubclass)) + self.assertFalse(isinstance(4, CustomIsSubclass)) + self.assertFalse(issubclass(CustomIsSubclass, CustomIsSubclass)) + self.assertTrue(isinstance(CustomIsSubclass(), CustomIsSubclass)) + self.assertFalse(issubclass(CustomIsSubclassSubclass, CustomIsSubclass)) + self.assertTrue(isinstance(CustomIsSubclassSubclass(), CustomIsSubclass)) + + def test_or_type_operator_with_TypeVar(self): TV = typing.TypeVar('T') self.assertEqual(TV | str, typing.Union[TV, str]) diff --git a/Objects/abstract.c b/Objects/abstract.c index f2c7de3d1ef1ad..a6cc046375c7ec 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2638,11 +2638,6 @@ object_isinstance(PyObject *inst, PyObject *cls) static int object_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls) { - /* Quick test for an exact match */ - if (Py_IS_TYPE(inst, (PyTypeObject *)cls)) { - return 1; - } - /* We know what type's __instancecheck__ does. */ if (PyType_CheckExact(cls)) { return object_isinstance(inst, cls);