# -*- coding: utf-8 -*-"""Test exception support."""import sysimport Systemimport pytestimport pickle# begin code from https://utcc.utoronto.ca/~cks/space/blog/python/GetAllObjectsimport gc# Recursively expand slist's objects# into olist, using seen to track# already processed objects.def _getr(slist, olist, seen):for e in slist:if id(e) in seen:continueseen[id(e)] = Noneolist.append(e)tl = gc.get_referents(e)if tl:_getr(tl, olist, seen)# The public function.def get_all_objects():gcl = gc.get_objects()olist = []seen = {}# Just in case:seen[id(gcl)] = Noneseen[id(olist)] = Noneseen[id(seen)] = None# _getr does the real work._getr(gcl, olist, seen)return olist# end code from https://utcc.utoronto.ca/~cks/space/blog/python/GetAllObjectsdef leak_check(func):def do_leak_check():func()gc.collect()exc = {x for x in get_all_objects() if isinstance(x, Exception) and not isinstance(x, pytest.PytestDeprecationWarning)}print(len(exc))if len(exc):for x in exc:print('-------')print(repr(x))print(gc.get_referrers(x))print(len(gc.get_referrers(x)))assert Falsegc.collect()return do_leak_checkdef test_unified_exception_semantics():"""Test unified exception semantics."""e = System.Exception('Something bad happened')assert isinstance(e, Exception)assert isinstance(e, System.Exception)def test_standard_exception_attributes():"""Test accessing standard exception attributes."""from System import OverflowExceptionfrom Python.Test import ExceptionTeste = ExceptionTest.GetExplicitException()assert isinstance(e, OverflowException)assert e.Message == 'error'e.Source = 'Test Suite'assert e.Source == 'Test Suite'v = e.ToString()assert len(v) > 0def test_extended_exception_attributes():"""Test accessing extended exception attributes."""from Python.Test import ExceptionTest, ExtendedExceptionfrom System import OverflowExceptione = ExceptionTest.GetExtendedException()assert isinstance(e, ExtendedException)assert isinstance(e, OverflowException)assert isinstance(e, System.Exception)assert e.Message == 'error'e.Source = 'Test Suite'assert e.Source == 'Test Suite'v = e.ToString()assert len(v) > 0assert e.ExtraProperty == 'extra'e.ExtraProperty = 'changed'assert e.ExtraProperty == 'changed'assert e.GetExtraInfo() == 'changed'def test_raise_class_exception():"""Test class exception propagation."""from System import NullReferenceExceptionwith pytest.raises(NullReferenceException) as cm:raise NullReferenceExceptionexc = cm.valueassert isinstance(exc, NullReferenceException)def test_exc_info():"""Test class exception propagation.Behavior of exc_info changed in Py3. Refactoring its test"""from System import NullReferenceExceptiontry:raise NullReferenceException("message")except Exception as exc:type_, value, tb = sys.exc_info()assert type_ is NullReferenceExceptionassert value.Message == "message"assert exc.Message == "message"# FIXME: Lower-case message isn't implemented# self.assertTrue(exc.message == "message")assert value is excdef test_raise_class_exception_with_value():"""Test class exception propagation with associated value."""from System import NullReferenceExceptionwith pytest.raises(NullReferenceException) as cm:raise NullReferenceException('Aiiieee!')exc = cm.valueassert isinstance(exc, NullReferenceException)assert exc.Message == 'Aiiieee!'def test_raise_instance_exception():"""Test instance exception propagation."""from System import NullReferenceExceptionwith pytest.raises(NullReferenceException) as cm:raise NullReferenceException()exc = cm.valueassert isinstance(exc, NullReferenceException)assert len(exc.Message) > 0def test_raise_instance_exception_with_args():"""Test instance exception propagation with args."""from System import NullReferenceExceptionwith pytest.raises(NullReferenceException) as cm:raise NullReferenceException("Aiiieee!")exc = cm.valueassert isinstance(exc, NullReferenceException)assert exc.Message == 'Aiiieee!'def test_managed_exception_propagation():"""Test propagation of exceptions raised in managed code."""from System import Decimal, OverflowExceptionwith pytest.raises(OverflowException):Decimal.ToInt64(Decimal.MaxValue)def test_managed_exception_conversion():"""Test conversion of managed exceptions."""from System import OverflowExceptionfrom Python.Test import ExceptionTeste = ExceptionTest.GetBaseException()assert isinstance(e, System.Exception)e = ExceptionTest.GetExplicitException()assert isinstance(e, OverflowException)assert isinstance(e, System.Exception)e = ExceptionTest.GetWidenedException()assert isinstance(e, OverflowException)assert isinstance(e, System.Exception)v = ExceptionTest.SetBaseException(System.Exception('error'))assert vv = ExceptionTest.SetExplicitException(OverflowException('error'))assert vv = ExceptionTest.SetWidenedException(OverflowException('error'))assert vdef test_catch_exception_from_managed_method():"""Test catching an exception from a managed method."""from Python.Test import ExceptionTestfrom System import OverflowExceptionwith pytest.raises(OverflowException) as cm:ExceptionTest().ThrowException()e = cm.valueassert isinstance(e, OverflowException)def test_catch_exception_from_managed_property():"""Test catching an exception from a managed property."""from Python.Test import ExceptionTestfrom System import OverflowExceptionwith pytest.raises(OverflowException) as cm:_ = ExceptionTest().ThrowPropertye = cm.valueassert isinstance(e, OverflowException)with pytest.raises(OverflowException) as cm:ExceptionTest().ThrowProperty = 1e = cm.valueassert isinstance(e, OverflowException)def test_catch_exception_managed_class():"""Test catching the managed class of an exception."""from System import OverflowExceptionwith pytest.raises(OverflowException):raise OverflowException('overflow')def test_catch_exception_python_class():"""Test catching the python class of an exception."""from System import OverflowExceptionwith pytest.raises(Exception):raise OverflowException('overflow')def test_catch_exception_base_class():"""Test catching the base of an exception."""from System import OverflowException, ArithmeticExceptionwith pytest.raises(ArithmeticException):raise OverflowException('overflow')def test_catch_exception_nested_base_class():"""Test catching the nested base of an exception."""from System import OverflowException, SystemExceptionwith pytest.raises(SystemException):raise OverflowException('overflow')def test_catch_exception_with_assignment():"""Test catching an exception with assignment."""from System import OverflowExceptionwith pytest.raises(OverflowException) as cm:raise OverflowException('overflow')e = cm.valueassert isinstance(e, OverflowException)def test_catch_exception_unqualified():"""Test catching an unqualified exception."""from System import OverflowExceptiontry:raise OverflowException('overflow')except:passelse:self.fail("failed to catch unqualified exception")def test_catch_baseexception():"""Test catching an unqualified exception with BaseException."""from System import OverflowExceptionwith pytest.raises(BaseException):raise OverflowException('overflow')def test_apparent_module_of_exception():"""Test the apparent module of an exception."""from System import OverflowExceptionassert System.Exception.__module__ == 'System'assert OverflowException.__module__ == 'System'def test_str_of_exception():"""Test the str() representation of an exception."""from System import NullReferenceException, Convert, FormatExceptione = NullReferenceException('')assert str(e) == ''e = NullReferenceException('Something bad happened')assert str(e).startswith('Something bad happened')with pytest.raises(FormatException) as cm:Convert.ToDateTime('this will fail')def test_python_compat_of_managed_exceptions():"""Test managed exceptions compatible with Python's implementation"""from System import OverflowExceptionmsg = "Simple message"e = OverflowException(msg)assert str(e) == msgassert e.args == (msg,)assert isinstance(e.args, tuple)strexp = "OverflowException('Simple message"assert repr(e)[:len(strexp)] == strexpdef test_exception_is_instance_of_system_object():"""Test behavior of isinstance(<managed exception>, 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# 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(<managed exception>, Object) to# be true, even though it does not really subclass Object.from System import OverflowException, Objecto = OverflowException('error')if sys.version_info >= (2, 6):assert isinstance(o, Object)else:assert not isinstance(o, Object)def test_pickling_exceptions():exc = System.Exception("test")dumped = pickle.dumps(exc)loaded = pickle.loads(dumped)assert exc.args == loaded.argsdef test_chained_exceptions():from Python.Test import ExceptionTestwith pytest.raises(Exception) as cm:ExceptionTest.ThrowChainedExceptions()exc = cm.valuemsgs = ("Outer exception","Inner exception","Innermost exception",)for msg in msgs:assert exc.Message == msgassert exc.__cause__ == exc.InnerExceptionexc = exc.__cause__def test_iteration_exception():from Python.Test import ExceptionTestfrom System import OverflowExceptionexception = OverflowException("error")val = ExceptionTest.ThrowExceptionInIterator(exception).__iter__()assert next(val) == 1assert next(val) == 2with pytest.raises(OverflowException) as cm:next(val)exc = cm.valueassert exc == exception# after exception is thrown iterator is no longer validwith pytest.raises(StopIteration):next(val)def test_iteration_innerexception():from Python.Test import ExceptionTestfrom System import OverflowExceptionexception = System.Exception("message", OverflowException("error"))val = ExceptionTest.ThrowExceptionInIterator(exception).__iter__()assert next(val) == 1assert next(val) == 2with pytest.raises(OverflowException) as cm:next(val)exc = cm.valueassert exc == exception.InnerException# after exception is thrown iterator is no longer validwith pytest.raises(StopIteration):next(val)def leak_test(func):def do_test_leak():# PyTest leaks things, gather the current stateorig_exc = {x for x in get_all_objects() if isinstance(x, Exception)}func()exc = {x for x in get_all_objects() if isinstance(x, Exception)}possibly_leaked = exc - orig_excassert not possibly_leakedreturn do_test_leak@leak_testdef test_dont_leak_exceptions_simple():from Python.Test import ExceptionTesttry:ExceptionTest.DoThrowSimple()except System.ArgumentException:print('type error, as expected')@leak_testdef test_dont_leak_exceptions_inner():from Python.Test import ExceptionTesttry:ExceptionTest.DoThrowWithInner()except TypeError:print('type error, as expected')except System.ArgumentException:print('type error, also expected')
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。