From d66af82a70dd9af24a7953c6ae5f02d8f198d10f Mon Sep 17 00:00:00 2001 From: Daniel Fortunov Date: Thu, 22 Oct 2020 10:42:19 +0100 Subject: [PATCH] Fix a number of issues with pr253 (#258) * Temporarily Revert "Make AsyncRetrying callable (as Retrying class) (#253)" This reverts commit 78a462eb * Add test coverage for __call__() interface: Tests passing * Re-apply "Make AsyncRetrying callable (as Retrying class) (#253)": Tests fail Tests in TestInvokeViaLegacyCallMethod begin to fail. This reverts commit 8ee3d278 * Fix Retrying.call() to invoke __call__ correctly and return result * Fix Retrying.call() to raise DeprecationWarning * pep8 --- tenacity/__init__.py | 4 +- tenacity/tests/test_tenacity.py | 75 +++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/tenacity/__init__.py b/tenacity/__init__.py index ed82cf55..336f4f65 100644 --- a/tenacity/__init__.py +++ b/tenacity/__init__.py @@ -431,8 +431,8 @@ def __call__(self, fn, *args, **kwargs): def call(self, *args, **kwargs): """Use ``__call__`` instead because this method is deprecated.""" warnings.warn("'Retrying.call()' method is deprecated. " + - "Use 'Retrying.__call__()' instead") - self.__call__(self, *args, **kwargs) + "Use 'Retrying.__call__()' instead", DeprecationWarning) + return self.__call__(*args, **kwargs) class Future(futures.Future): diff --git a/tenacity/tests/test_tenacity.py b/tenacity/tests/test_tenacity.py index 568a5a8c..673541c0 100644 --- a/tenacity/tests/test_tenacity.py +++ b/tenacity/tests/test_tenacity.py @@ -1432,6 +1432,81 @@ def test(): self.assertRaises(CustomError, test) +class TestInvokeAsCallable: + """Test direct invocation of Retrying as a callable.""" + + @staticmethod + def invoke(retry, f): + """ + Invoke Retrying logic. + + Wrapper allows testing different call mechanisms in test sub-classes. + """ + return retry(f) + + def test_retry_one(self): + def f(): + f.calls.append(len(f.calls) + 1) + if len(f.calls) <= 1: + raise Exception("Retry it!") + return 42 + f.calls = [] + + retry = Retrying() + assert self.invoke(retry, f) == 42 + assert f.calls == [1, 2] + + def test_on_error(self): + class CustomError(Exception): + pass + + def f(): + f.calls.append(len(f.calls) + 1) + if len(f.calls) <= 1: + raise CustomError("Don't retry!") + return 42 + f.calls = [] + + retry = Retrying(retry=tenacity.retry_if_exception_type(IOError)) + with pytest.raises(CustomError): + self.invoke(retry, f) + assert f.calls == [1] + + def test_retry_error(self): + def f(): + f.calls.append(len(f.calls) + 1) + raise Exception("Retry it!") + f.calls = [] + + retry = Retrying(stop=tenacity.stop_after_attempt(2)) + with pytest.raises(RetryError): + self.invoke(retry, f) + assert f.calls == [1, 2] + + def test_reraise(self): + class CustomError(Exception): + pass + + def f(): + f.calls.append(len(f.calls) + 1) + raise CustomError("Retry it!") + f.calls = [] + + retry = Retrying(reraise=True, stop=tenacity.stop_after_attempt(2)) + with pytest.raises(CustomError): + self.invoke(retry, f) + assert f.calls == [1, 2] + + +class TestInvokeViaLegacyCallMethod(TestInvokeAsCallable): + """Retrying.call() method should work the same as Retrying.__call__().""" + + @staticmethod + def invoke(retry, f): + with reports_deprecation_warning(): + return retry.call(f) + + class TestRetryException(unittest.TestCase): def test_retry_error_is_pickleable(self):