diff --git a/tests/test_issue65.py b/tests/test_issue65.py new file mode 100644 index 0000000..9da4a9f --- /dev/null +++ b/tests/test_issue65.py @@ -0,0 +1,27 @@ +import pickle + +from tblib import pickling_support + + +class HTTPrettyError(Exception): + pass + + +class UnmockedError(HTTPrettyError): + def __init__(self): + super().__init__('No mocking was registered, and real connections are not allowed (httpretty.allow_net_connect = False).') + + +def test_65(): + pickling_support.install() + + try: + raise UnmockedError + except Exception as e: + exc = e + + exc = pickle.loads(pickle.dumps(exc)) + + assert isinstance(exc, UnmockedError) + assert exc.args == ('No mocking was registered, and real connections are not allowed (httpretty.allow_net_connect = False).',) + assert exc.__traceback__ is not None diff --git a/tests/test_pickle_exception.py b/tests/test_pickle_exception.py index 53a9dce..db45254 100644 --- a/tests/test_pickle_exception.py +++ b/tests/test_pickle_exception.py @@ -164,3 +164,95 @@ def func(my_arg='2'): exc = pickle.loads(pickle.dumps(exc, protocol=protocol)) assert exc.__traceback__.tb_next.tb_frame.f_locals == {'my_variable': 1} + + +class CustomWithAttributesException(Exception): + def __init__(self, message, arg1, arg2, arg3): + super().__init__(message) + self.values12 = (arg1, arg2) + self.value3 = arg3 + + +def test_custom_with_attributes(): + try: + raise CustomWithAttributesException('bar', 1, 2, 3) + except Exception as e: + exc = e + + tblib.pickling_support.install(exc) + exc = pickle.loads(pickle.dumps(exc)) + + assert isinstance(exc, CustomWithAttributesException) + assert exc.args == ('bar',) + assert exc.values12 == (1, 2) + assert exc.value3 == 3 + assert exc.__traceback__ is not None + + +class CustomReduceException(Exception): + def __init__(self, message, arg1, arg2, arg3): + super().__init__(message) + self.values12 = (arg1, arg2) + self.value3 = arg3 + + def __reduce__(self): + return self.__class__, self.args + self.values12 + (self.value3,) + + +def test_custom_reduce(): + try: + raise CustomReduceException('foo', 1, 2, 3) + except Exception as e: + exc = e + + tblib.pickling_support.install(exc) + exc = pickle.loads(pickle.dumps(exc)) + + assert isinstance(exc, CustomReduceException) + assert exc.args == ('foo',) + assert exc.values12 == (1, 2) + assert exc.value3 == 3 + assert exc.__traceback__ is not None + + +class CustomReduceExException(Exception): + def __init__(self, message, arg1, arg2, protocol): + super().__init__(message) + self.values12 = (arg1, arg2) + self.value3 = protocol + + def __reduce_ex__(self, protocol): + return self.__class__, self.args + self.values12 + (self.value3,) + + +@pytest.mark.parametrize('protocol', [None, *list(range(1, pickle.HIGHEST_PROTOCOL + 1))]) +def test_custom_reduce_ex(protocol): + try: + raise CustomReduceExException('foo', 1, 2, 3) + except Exception as e: + exc = e + + tblib.pickling_support.install(exc) + exc = pickle.loads(pickle.dumps(exc, protocol=protocol)) + + assert isinstance(exc, CustomReduceExException) + assert exc.args == ('foo',) + assert exc.values12 == (1, 2) + assert exc.value3 == 3 + assert exc.__traceback__ is not None + + +def test_oserror(): + try: + raise OSError(13, 'Permission denied') + except Exception as e: + exc = e + + tblib.pickling_support.install(exc) + exc = pickle.loads(pickle.dumps(exc)) + + assert isinstance(exc, OSError) + assert exc.args == (13, 'Permission denied') + assert exc.errno == 13 + assert exc.strerror == 'Permission denied' + assert exc.__traceback__ is not None