# Tests some corner cases with isinstance() and issubclass().  While these
# tests use new style classes and properties, they actually do whitebox
# testing of error conditions uncovered when using extension types.

import unittest
import sys
import typing
from test import support



class TestIsInstanceExceptions(unittest.TestCase):
    # Test to make sure that an AttributeError when accessing the instance's
    # class's bases is masked.  This was actually a bug in Python 2.2 and
    # 2.2.1 where the exception wasn't caught but it also wasn't being cleared
    # (leading to an "undetected error" in the debug build).  Set up is,
    # isinstance(inst, cls) where:
    #
    # - cls isn't a type, or a tuple
    # - cls has a __bases__ attribute
    # - inst has a __class__ attribute
    # - inst.__class__ as no __bases__ attribute
    #
    # Sounds complicated, I know, but this mimics a situation where an
    # extension type raises an AttributeError when its __bases__ attribute is
    # gotten.  In that case, isinstance() should return False.
    def test_class_has_no_bases(self):
        class I(object):
            def getclass(self):
                # This must return an object that has no __bases__ attribute
                return None
            __class__ = property(getclass)

        class C(object):
            def getbases(self):
                return ()
            __bases__ = property(getbases)

        self.assertEqual(False, isinstance(I(), C()))

    # Like above except that inst.__class__.__bases__ raises an exception
    # other than AttributeError
    def test_bases_raises_other_than_attribute_error(self):
        class E(object):
            def getbases(self):
                raise RuntimeError
            __bases__ = property(getbases)

        class I(object):
            def getclass(self):
                return E()
            __class__ = property(getclass)

        class C(object):
            def getbases(self):
                return ()
            __bases__ = property(getbases)

        self.assertRaises(RuntimeError, isinstance, I(), C())

    # Here's a situation where getattr(cls, '__bases__') raises an exception.
    # If that exception is not AttributeError, it should not get masked
    def test_dont_mask_non_attribute_error(self):
        class I: pass

        class C(object):
            def getbases(self):
                raise RuntimeError
            __bases__ = property(getbases)

        self.assertRaises(RuntimeError, isinstance, I(), C())

    # Like above, except that getattr(cls, '__bases__') raises an
    # AttributeError, which /should/ get masked as a TypeError
    def test_mask_attribute_error(self):
        class I: pass

        class C(object):
            def getbases(self):
                raise AttributeError
            __bases__ = property(getbases)

        self.assertRaises(TypeError, isinstance, I(), C())

    # check that we don't mask non AttributeErrors
    # see: http://bugs.python.org/issue1574217
    def test_isinstance_dont_mask_non_attribute_error(self):
        class C(object):
            def getclass(self):
                raise RuntimeError
            __class__ = property(getclass)

        c = C()
        self.assertRaises(RuntimeError, isinstance, c, bool)

        # test another code path
        class D: pass
        self.assertRaises(RuntimeError, isinstance, c, D)


# These tests are similar to above, but tickle certain code paths in
# issubclass() instead of isinstance() -- really PyObject_IsSubclass()
# vs. PyObject_IsInstance().
class TestIsSubclassExceptions(unittest.TestCase):
    def test_dont_mask_non_attribute_error(self):
        class C(object):
            def getbases(self):
                raise RuntimeError
            __bases__ = property(getbases)

        class S(C): pass

        self.assertRaises(RuntimeError, issubclass, C(), S())

    def test_mask_attribute_error(self):
        class C(object):
            def getbases(self):
                raise AttributeError
            __bases__ = property(getbases)

        class S(C): pass

        self.assertRaises(TypeError, issubclass, C(), S())

    # Like above, but test the second branch, where the __bases__ of the
    # second arg (the cls arg) is tested.  This means the first arg must
    # return a valid __bases__, and it's okay for it to be a normal --
    # unrelated by inheritance -- class.
    def test_dont_mask_non_attribute_error_in_cls_arg(self):
        class B: pass

        class C(object):
            def getbases(self):
                raise RuntimeError
            __bases__ = property(getbases)

        self.assertRaises(RuntimeError, issubclass, B, C())

    def test_mask_attribute_error_in_cls_arg(self):
        class B: pass

        class C(object):
            def getbases(self):
                raise AttributeError
            __bases__ = property(getbases)

        self.assertRaises(TypeError, issubclass, B, C())



# meta classes for creating abstract classes and instances
class AbstractClass(object):
    def __init__(self, bases):
        self.bases = bases

    def getbases(self):
        return self.bases
    __bases__ = property(getbases)

    def __call__(self):
        return AbstractInstance(self)

class AbstractInstance(object):
    def __init__(self, klass):
        self.klass = klass

    def getclass(self):
        return self.klass
    __class__ = property(getclass)

# abstract classes
AbstractSuper = AbstractClass(bases=())

AbstractChild = AbstractClass(bases=(AbstractSuper,))

# normal classes
class Super:
    pass

class Child(Super):
    pass

class TestIsInstanceIsSubclass(unittest.TestCase):
    # Tests to ensure that isinstance and issubclass work on abstract
    # classes and instances.  Before the 2.2 release, TypeErrors were
    # raised when boolean values should have been returned.  The bug was
    # triggered by mixing 'normal' classes and instances were with
    # 'abstract' classes and instances.  This case tries to test all
    # combinations.

    def test_isinstance_normal(self):
        # normal instances
        self.assertEqual(True, isinstance(Super(), Super))
        self.assertEqual(False, isinstance(Super(), Child))
        self.assertEqual(False, isinstance(Super(), AbstractSuper))
        self.assertEqual(False, isinstance(Super(), AbstractChild))

        self.assertEqual(True, isinstance(Child(), Super))
        self.assertEqual(False, isinstance(Child(), AbstractSuper))

    def test_isinstance_abstract(self):
        # abstract instances
        self.assertEqual(True, isinstance(AbstractSuper(), AbstractSuper))
        self.assertEqual(False, isinstance(AbstractSuper(), AbstractChild))
        self.assertEqual(False, isinstance(AbstractSuper(), Super))
        self.assertEqual(False, isinstance(AbstractSuper(), Child))

        self.assertEqual(True, isinstance(AbstractChild(), AbstractChild))
        self.assertEqual(True, isinstance(AbstractChild(), AbstractSuper))
        self.assertEqual(False, isinstance(AbstractChild(), Super))
        self.assertEqual(False, isinstance(AbstractChild(), Child))

    def test_isinstance_with_or_union(self):
        self.assertTrue(isinstance(Super(), Super | int))
        self.assertFalse(isinstance(None, str | int))
        self.assertTrue(isinstance(3, str | int))
        self.assertTrue(isinstance("", str | int))
        self.assertTrue(isinstance([], typing.List | typing.Tuple))
        self.assertTrue(isinstance(2, typing.List | int))
        self.assertFalse(isinstance(2, typing.List | typing.Tuple))
        self.assertTrue(isinstance(None, int | None))
        self.assertFalse(isinstance(3.14, int | str))
        with self.assertRaises(TypeError):
            isinstance(2, list[int])
        with self.assertRaises(TypeError):
            isinstance(2, list[int] | int)
        with self.assertRaises(TypeError):
            isinstance(2, float | str | list[int] | int)



    def test_subclass_normal(self):
        # normal classes
        self.assertEqual(True, issubclass(Super, Super))
        self.assertEqual(False, issubclass(Super, AbstractSuper))
        self.assertEqual(False, issubclass(Super, Child))

        self.assertEqual(True, issubclass(Child, Child))
        self.assertEqual(True, issubclass(Child, Super))
        self.assertEqual(False, issubclass(Child, AbstractSuper))
        self.assertTrue(issubclass(typing.List, typing.List|typing.Tuple))
        self.assertFalse(issubclass(int, typing.List|typing.Tuple))

    def test_subclass_abstract(self):
        # abstract classes
        self.assertEqual(True, issubclass(AbstractSuper, AbstractSuper))
        self.assertEqual(False, issubclass(AbstractSuper, AbstractChild))
        self.assertEqual(False, issubclass(AbstractSuper, Child))

        self.assertEqual(True, issubclass(AbstractChild, AbstractChild))
        self.assertEqual(True, issubclass(AbstractChild, AbstractSuper))
        self.assertEqual(False, issubclass(AbstractChild, Super))
        self.assertEqual(False, issubclass(AbstractChild, Child))

    def test_subclass_tuple(self):
        # test with a tuple as the second argument classes
        self.assertEqual(True, issubclass(Child, (Child,)))
        self.assertEqual(True, issubclass(Child, (Super,)))
        self.assertEqual(False, issubclass(Super, (Child,)))
        self.assertEqual(True, issubclass(Super, (Child, Super)))
        self.assertEqual(False, issubclass(Child, ()))
        self.assertEqual(True, issubclass(Super, (Child, (Super,))))

        self.assertEqual(True, issubclass(int, (int, (float, int))))
        self.assertEqual(True, issubclass(str, (str, (Child, str))))

    def test_subclass_recursion_limit(self):
        # make sure that issubclass raises RecursionError before the C stack is
        # blown
        with support.infinite_recursion():
            self.assertRaises(RecursionError, blowstack, issubclass, str, str)

    def test_isinstance_recursion_limit(self):
        # make sure that issubclass raises RecursionError before the C stack is
        # blown
        with support.infinite_recursion():
            self.assertRaises(RecursionError, blowstack, isinstance, '', str)

    def test_subclass_with_union(self):
        self.assertTrue(issubclass(int, int | float | int))
        self.assertTrue(issubclass(str, str | Child | str))
        self.assertFalse(issubclass(dict, float|str))
        self.assertFalse(issubclass(object, float|str))
        with self.assertRaises(TypeError):
            issubclass(2, Child | Super)
        with self.assertRaises(TypeError):
            issubclass(int, list[int] | Child)

    def test_issubclass_refcount_handling(self):
        # bpo-39382: abstract_issubclass() didn't hold item reference while
        # peeking in the bases tuple, in the single inheritance case.
        class A:
            @property
            def __bases__(self):
                return (int, )

        class B:
            def __init__(self):
                # setting this here increases the chances of exhibiting the bug,
                # probably due to memory layout changes.
                self.x = 1

            @property
            def __bases__(self):
                return (A(), )

        self.assertEqual(True, issubclass(B(), int))

    def test_infinite_recursion_in_bases(self):
        class X:
            @property
            def __bases__(self):
                return self.__bases__
        with support.infinite_recursion():
            self.assertRaises(RecursionError, issubclass, X(), int)
            self.assertRaises(RecursionError, issubclass, int, X())
            self.assertRaises(RecursionError, isinstance, 1, X())

    def test_infinite_recursion_via_bases_tuple(self):
        """Regression test for bpo-30570."""
        class Failure(object):
            def __getattr__(self, attr):
                return (self, None)
        with support.infinite_recursion():
            with self.assertRaises(RecursionError):
                issubclass(Failure(), int)

    def test_infinite_cycle_in_bases(self):
        """Regression test for bpo-30570."""
        class X:
            @property
            def __bases__(self):
                return (self, self, self)
        with support.infinite_recursion():
            self.assertRaises(RecursionError, issubclass, X(), int)

    def test_infinitely_many_bases(self):
        """Regression test for bpo-30570."""
        class X:
            def __getattr__(self, attr):
                self.assertEqual(attr, "__bases__")
                class A:
                    pass
                class B:
                    pass
                A.__getattr__ = B.__getattr__ = X.__getattr__
                return (A(), B())
        with support.infinite_recursion():
            self.assertRaises(RecursionError, issubclass, X(), int)


def blowstack(fxn, arg, compare_to):
    # Make sure that calling isinstance with a deeply nested tuple for its
    # argument will raise RecursionError eventually.
    tuple_arg = (compare_to,)
    for cnt in range(support.EXCEEDS_RECURSION_LIMIT):
        tuple_arg = (tuple_arg,)
        fxn(arg, tuple_arg)


if __name__ == '__main__':
    unittest.main()
