[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/attackgithub/pythonnet/pypy/src/tests/test_exceptions.py [Back]  [Original]

# -*- coding: utf-8 -*-

import sys
import unittest

import System

from _compat import PY2, PY3, pickle, text_type


class ExceptionTests(unittest.TestCase):
    """Test exception support."""

    def test_unified_exception_semantics(self):
        """Test unified exception semantics."""
        e = System.Exception('Something bad happened')
        self.assertTrue(isinstance(e, Exception))
        self.assertTrue(isinstance(e, System.Exception))

    def test_standard_exception_attributes(self):
        """Test accessing standard exception attributes."""
        from System import OverflowException
        from Python.Test import ExceptionTest

        e = ExceptionTest.GetExplicitException()
        self.assertTrue(isinstance(e, OverflowException))

        self.assertTrue(e.Message == 'error')

        e.Source = 'Test Suite'
        self.assertTrue(e.Source == 'Test Suite')

        v = e.ToString()
        self.assertTrue(len(v) > 0)

    def test_extended_exception_attributes(self):
        """Test accessing extended exception attributes."""
        from Python.Test import ExceptionTest, ExtendedException
        from System import OverflowException

        e = ExceptionTest.GetExtendedException()
        self.assertTrue(isinstance(e, ExtendedException))
        self.assertTrue(isinstance(e, OverflowException))
        self.assertTrue(isinstance(e, System.Exception))

        self.assertTrue(e.Message == 'error')

        e.Source = 'Test Suite'
        self.assertTrue(e.Source == 'Test Suite')

        v = e.ToString()
        self.assertTrue(len(v) > 0)

        self.assertTrue(e.ExtraProperty == 'extra')
        e.ExtraProperty = 'changed'
        self.assertTrue(e.ExtraProperty == 'changed')

        self.assertTrue(e.GetExtraInfo() == 'changed')

    def test_raise_class_exception(self):
        """Test class exception propagation."""
        from System import NullReferenceException

        with self.assertRaises(NullReferenceException) as cm:
            raise NullReferenceException

        exc = cm.exception
        self.assertTrue(isinstance(exc, NullReferenceException))

    def test_exc_info(self):
        """Test class exception propagation.
        Behavior of exc_info changed in Py3. Refactoring its test"""
        from System import NullReferenceException
        try:
            raise NullReferenceException("message")
        except Exception as exc:
            type_, value, tb = sys.exc_info()
            self.assertTrue(type_ is NullReferenceException)
            self.assertTrue(value.Message == "message")
            self.assertTrue(exc.Message == "message")
            # FIXME: Lower-case message isn't implemented
            # self.assertTrue(exc.message == "message")
            self.assertTrue(value is exc)

    def test_raise_class_exception_with_value(self):
        """Test class exception propagation with associated value."""
        from System import NullReferenceException

        with self.assertRaises(NullReferenceException) as cm:
            raise NullReferenceException('Aiiieee!')

        exc = cm.exception
        self.assertTrue(isinstance(exc, NullReferenceException))
        self.assertTrue(exc.Message == 'Aiiieee!')

    def test_raise_instance_exception(self):
        """Test instance exception propagation."""
        from System import NullReferenceException

        with self.assertRaises(NullReferenceException) as cm:
            raise NullReferenceException()

        exc = cm.exception
        self.assertTrue(isinstance(exc, NullReferenceException))
        self.assertTrue(len(exc.Message) > 0)

    def test_raise_instance_exception_with_args(self):
        """Test instance exception propagation with args."""
        from System import NullReferenceException

        with self.assertRaises(NullReferenceException) as cm:
            raise NullReferenceException("Aiiieee!")

        exc = cm.exception
        self.assertTrue(isinstance(exc, NullReferenceException))
        self.assertTrue(exc.Message == 'Aiiieee!')

    def test_managed_exception_propagation(self):
        """Test propagation of exceptions raised in managed code."""
        from System import Decimal, OverflowException

        with self.assertRaises(OverflowException):
            Decimal.ToInt64(Decimal.MaxValue)

    def test_managed_exception_conversion(self):
        """Test conversion of managed exceptions."""
        from System import OverflowException
        from Python.Test import ExceptionTest

        e = ExceptionTest.GetBaseException()
        self.assertTrue(isinstance(e, System.Exception))

        e = ExceptionTest.GetExplicitException()
        self.assertTrue(isinstance(e, OverflowException))
        self.assertTrue(isinstance(e, System.Exception))

        e = ExceptionTest.GetWidenedException()
        self.assertTrue(isinstance(e, OverflowException))
        self.assertTrue(isinstance(e, System.Exception))

        v = ExceptionTest.SetBaseException(System.Exception('error'))
        self.assertTrue(v)

        v = ExceptionTest.SetExplicitException(OverflowException('error'))
        self.assertTrue(v)

        v = ExceptionTest.SetWidenedException(OverflowException('error'))
        self.assertTrue(v)

    def test_catch_exception_from_managed_method(self):
        """Test catching an exception from a managed method."""
        from Python.Test import ExceptionTest
        from System import OverflowException

        with self.assertRaises(OverflowException) as cm:
            ExceptionTest().ThrowException()

        e = cm.exception
        self.assertTrue(isinstance(e, OverflowException))

    def test_catch_exception_from_managed_property(self):
        """Test catching an exception from a managed property."""
        from Python.Test import ExceptionTest
        from System import OverflowException

        with self.assertRaises(OverflowException) as cm:
            _ = ExceptionTest().ThrowProperty

        e = cm.exception
        self.assertTrue(isinstance(e, OverflowException))

        with self.assertRaises(OverflowException) as cm:
            ExceptionTest().ThrowProperty = 1

        e = cm.exception
        self.assertTrue(isinstance(e, OverflowException))

    def test_catch_exception_managed_class(self):
        """Test catching the managed class of an exception."""
        from System import OverflowException

        with self.assertRaises(OverflowException):
            raise OverflowException('overflow')

    def test_catch_exception_python_class(self):
        """Test catching the python class of an exception."""
        from System import OverflowException

        with self.assertRaises(Exception):
            raise OverflowException('overflow')

    def test_catch_exception_base_class(self):
        """Test catching the base of an exception."""
        from System import OverflowException, ArithmeticException

        with self.assertRaises(ArithmeticException):
            raise OverflowException('overflow')

    def test_catch_exception_nested_base_class(self):
        """Test catching the nested base of an exception."""
        from System import OverflowException, SystemException

        with self.assertRaises(SystemException):
            raise OverflowException('overflow')

    def test_catch_exception_with_assignment(self):
        """Test catching an exception with assignment."""
        from System import OverflowException

        with self.assertRaises(OverflowException) as cm:
            raise OverflowException('overflow')

        e = cm.exception
        self.assertTrue(isinstance(e, OverflowException))

    def test_catch_exception_unqualified(self):
        """Test catching an unqualified exception."""
        from System import OverflowException

        try:
            raise OverflowException('overflow')
        except:
            pass
        else:
            self.fail("failed to catch unqualified exception")

    def test_catch_baseexception(self):
        """Test catching an unqualified exception with BaseException."""
        from System import OverflowException

        with self.assertRaises(BaseException):
            raise OverflowException('overflow')

    def test_apparent_module_of_exception(self):
        """Test the apparent module of an exception."""
        from System import OverflowException

        self.assertTrue(System.Exception.__module__ == 'System')
        self.assertTrue(OverflowException.__module__ == 'System')

    def test_str_of_exception(self):
        """Test the str() representation of an exception."""
        from System import NullReferenceException, Convert, FormatException

        e = NullReferenceException('')
        self.assertEqual(str(e), '')

        e = NullReferenceException('Something bad happened')
        self.assertTrue(str(e).startswith('Something bad happened'))

        with self.assertRaises(FormatException) as cm:
            Convert.ToDateTime('this will fail')

        e = cm.exception
        # fix for international installation
        msg = text_type(e).encode("utf8")
        fnd = text_type('System.Convert.ToDateTime').encode("utf8")
        self.assertTrue(msg.find(fnd) > -1, msg)

    def test_python_compat_of_managed_exceptions(self):
        """Test managed exceptions compatible with Python's implementation"""
        from System import OverflowException
        msg = "Simple message"

        e = OverflowException(msg)
        self.assertEqual(str(e), msg)
        self.assertEqual(text_type(e), msg)

        self.assertEqual(e.args, (msg,))
        self.assertTrue(isinstance(e.args, tuple))
        if PY3:
            self.assertEqual(repr(e), "OverflowException('Simple message',)")
        elif PY2:
            self.assertEqual(repr(e), "OverflowException(u'Simple message',)")

    def test_exception_is_instance_of_system_object(self):
        """Test behavior of isinstance(, System.Object)."""
        # This is an anti-test, in that this is a caveat of the current
        # implementation. Because exceptions are not allowed to be new-style
        # classes, we wrap managed exceptions in a general-purpose old-style
        # class that delegates to the wrapped object. This makes _almost_
        # everything work as expected, except that an isinstance check against
        # CLR.System.Object will fail for a managed exception (because a new
        # style class cannot appear in the __bases__ of an old-style class
        # without causing a crash in the CPython interpreter). This test is
        # here mainly to remind me to update the caveat in the documentation
        # one day when when exceptions can be new-style classes.

        # This behavior is now over-shadowed by the implementation of
        # __instancecheck__ (i.e., overloading isinstance), so for all Python
        # version >= 2.6 we expect isinstance(, Object) to
        # be true, even though it does not really subclass Object.
        from System import OverflowException, Object

        o = OverflowException('error')

        if sys.version_info >= (2, 6):
            self.assertTrue(isinstance(o, Object))
        else:
            self.assertFalse(isinstance(o, Object))

    def test_pickling_exceptions(self):
        exc = System.Exception("test")
        dumped = pickle.dumps(exc)
        loaded = pickle.loads(dumped)

        self.assertEqual(exc.args, loaded.args)

    @unittest.skipIf(PY2, "__cause__ isn't implemented in PY2")
    def test_chained_exceptions(self):
        from Python.Test import ExceptionTest

        with self.assertRaises(Exception) as cm:
            ExceptionTest.ThrowChainedExceptions()

        exc = cm.exception

        msgs = ("Outer exception",
                "Inner exception",
                "Innermost exception",)
        for msg in msgs:
            self.assertEqual(exc.Message, msg)
            self.assertEqual(exc.__cause__, exc.InnerException)
            exc = exc.__cause__


def test_suite():
    return unittest.makeSuite(ExceptionTests)

Web Proxy Viewer  |  New URL  |  Original Page