"""Unit tests for __instancecheck__ and __subclasscheck__."""

import unittest
from test import test_support


class ABC(type):

    def __instancecheck__(cls, inst):
        """Implement isinstance(inst, cls)."""
        return any(cls.__subclasscheck__(c)
                   for c in set([type(inst), inst.__class__]))

    def __subclasscheck__(cls, sub):
        """Implement issubclass(sub, cls)."""
        candidates = cls.__dict__.get("__subclass__", set()) | set([cls])
        return any(c in candidates for c in sub.mro())


class Integer:

    __metaclass__ = ABC

    __subclass__ = set([int])


class SubInt(Integer):

    pass


class TypeChecksTest(unittest.TestCase):

    def testIsSubclassInternal(self):
        self.assertEqual(Integer.__subclasscheck__(int), True)
        self.assertEqual(Integer.__subclasscheck__(float), False)

    def testIsSubclassBuiltin(self):
        self.assertEqual(issubclass(int, Integer), True)
        self.assertEqual(issubclass(int, (Integer,)), True)
        self.assertEqual(issubclass(float, Integer), False)
        self.assertEqual(issubclass(float, (Integer,)), False)

    def testIsInstanceBuiltin(self):
        self.assertEqual(isinstance(42, Integer), True)
        self.assertEqual(isinstance(42, (Integer,)), True)
        self.assertEqual(isinstance(3.14, Integer), False)
        self.assertEqual(isinstance(3.14, (Integer,)), False)

    def testIsInstanceActual(self):
        self.assertEqual(isinstance(Integer(), Integer), True)
        self.assertEqual(isinstance(Integer(), (Integer,)), True)

    def testIsSubclassActual(self):
        self.assertEqual(issubclass(Integer, Integer), True)
        self.assertEqual(issubclass(Integer, (Integer,)), True)

    def testSubclassBehavior(self):
        self.assertEqual(issubclass(SubInt, Integer), True)
        self.assertEqual(issubclass(SubInt, (Integer,)), True)
        self.assertEqual(issubclass(SubInt, SubInt), True)
        self.assertEqual(issubclass(SubInt, (SubInt,)), True)
        self.assertEqual(issubclass(Integer, SubInt), False)
        self.assertEqual(issubclass(Integer, (SubInt,)), False)
        self.assertEqual(issubclass(int, SubInt), False)
        self.assertEqual(issubclass(int, (SubInt,)), False)
        self.assertEqual(isinstance(SubInt(), Integer), True)
        self.assertEqual(isinstance(SubInt(), (Integer,)), True)
        self.assertEqual(isinstance(SubInt(), SubInt), True)
        self.assertEqual(isinstance(SubInt(), (SubInt,)), True)
        self.assertEqual(isinstance(42, SubInt), False)
        self.assertEqual(isinstance(42, (SubInt,)), False)

    def test_oldstyle(self):
        # These should just be ignored.
        class X:
            def __instancecheck__(self, inst):
                return True
            def __subclasscheck__(self, cls):
                return True
        class Sub(X): pass
        self.assertNotIsInstance(3, X)
        self.assertIsInstance(X(), X)
        self.assertFalse(issubclass(int, X))
        self.assertTrue(issubclass(Sub, X))


def test_main():
    test_support.run_unittest(TypeChecksTest)


if __name__ == "__main__":
    unittest.main()
