Hello community,

here is the log from the commit of package python-tenacity for openSUSE:Factory 
checked in at 2018-01-13 21:47:36
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-tenacity (Old)
 and      /work/SRC/openSUSE:Factory/.python-tenacity.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-tenacity"

Sat Jan 13 21:47:36 2018 rev:4 rq:563549 version:4.8.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-tenacity/python-tenacity.changes  
2017-11-11 14:20:46.828617522 +0100
+++ /work/SRC/openSUSE:Factory/.python-tenacity.new/python-tenacity.changes     
2018-01-13 21:47:40.198011952 +0100
@@ -1,0 +2,23 @@
+Wed Jan 10 22:24:53 UTC 2018 - [email protected]
+
+- Remove repetition of license terms in description.
+
+-------------------------------------------------------------------
+Wed Jan 10 20:48:41 UTC 2018 - [email protected]
+
+- update to 4.8.0
+  * Allow waiters to introspect last result
+- update to 4.7.1
+  * Missed top level import of stop\_when\_event\_set
+  * Mention Tornado minimum version in README
+  * Fix unless\_exception test names and add no input test
+- update to 4.7.0
+  * Add Tornado support
+  * Fix pep8
+- update to 4.6.1
+  * Simplify wrapping code
+- update to 4.6.0
+  * Implement \`retry\_with' on decorated functions
+- Implement single-spec version
+
+-------------------------------------------------------------------

Old:
----
  tenacity-4.5.0.tar.gz

New:
----
  tenacity-4.8.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-tenacity.spec ++++++
--- /var/tmp/diff_new_pack.nfgl2p/_old  2018-01-13 21:47:40.785984540 +0100
+++ /var/tmp/diff_new_pack.nfgl2p/_new  2018-01-13 21:47:40.789984354 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-tenacity
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,29 +16,41 @@
 #
 
 
+%{?!python_module:%define python_module() python-%{**} python3-%{**}}
+%bcond_without  test
 Name:           python-tenacity
-Version:        4.5.0
+Version:        4.8.0
 Release:        0
 Summary:        Retry code until it succeeeds
 License:        Apache-2.0
 Group:          Development/Languages/Python
 Url:            https://github.com/jd/tenacity
-Source:         
https://pypi.io/packages/source/t/tenacity/tenacity-%{version}.tar.gz
-BuildRequires:  python-devel
+Source:         
https://files.pythonhosted.org/packages/source/t/tenacity/tenacity-%{version}.tar.gz
+BuildRequires:  %{python_module devel}
+BuildRequires:  %{python_module monotonic >= 0.6}
+BuildRequires:  %{python_module pbr}
+BuildRequires:  %{python_module setuptools}
+BuildRequires:  %{python_module six >= 1.7.0}
+BuildRequires:  fdupes
 BuildRequires:  python-futures >= 3.0
-BuildRequires:  python-monotonic >= 0.6
-BuildRequires:  python-pbr
-BuildRequires:  python-setuptools
-BuildRequires:  python-six >= 1.7.0
-Requires:       python-futures >= 3.0
+BuildRequires:  python-rpm-macros
+%if %{with test}
+BuildRequires:  %{python_module nose}
+BuildRequires:  %{python_module tornado}
+%endif
 Requires:       python-monotonic >= 0.6
 Requires:       python-six >= 1.9.0
-BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+Recommends:     python-tornado
+%ifpython2
+Requires:       python-futures >= 3.0
+%endif
 BuildArch:      noarch
 
+%python_subpackages
+
 %description
-Tenacity is an Apache 2.0 licensed general-purpose retrying library, written in
-Python, to simplify the task of adding retry behavior to just about anything.
+Tenacity is a general-purpose retrying library, written in Python, to simplify
+the task of adding retry behavior to just about anything.
 It originates from a fork of `Retrying`_
 Features
 --------
@@ -52,15 +64,18 @@
 %setup -q -n tenacity-%{version}
 
 %build
-python setup.py build
+%python_build
 
 %install
-python setup.py install --prefix=%{_prefix} --root=%{buildroot}
+%python_install
+%python_expand %fdupes -s %{buildroot}%{$python_sitelib}
 
+%if %{with test}
 %check
-python setup.py test
+%python_exec setup.py nosetests --ignore-files '.*async.py'
+%endif
 
-%files
+%files %{python_files}
 %defattr(-,root,root,-)
 %doc AUTHORS ChangeLog LICENSE README.rst
 %{python_sitelib}/*

++++++ tenacity-4.5.0.tar.gz -> tenacity-4.8.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/AUTHORS new/tenacity-4.8.0/AUTHORS
--- old/tenacity-4.5.0/AUTHORS  2017-10-24 10:41:17.000000000 +0200
+++ new/tenacity-4.8.0/AUTHORS  2017-12-14 09:53:45.000000000 +0100
@@ -1,8 +1,8 @@
 Brian Williams <[email protected]>
 Brian-Williams <[email protected]>
+Elisey Zanko <[email protected]>
 Joshua Harlow <[email protected]>
 Julien Danjou <[email protected]>
-Mehdi Abaakouk <[email protected]>
 Michael Evans <[email protected]>
 Victor Yap <[email protected]>
 William Silversmith <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/ChangeLog new/tenacity-4.8.0/ChangeLog
--- old/tenacity-4.5.0/ChangeLog        2017-10-24 10:41:17.000000000 +0200
+++ new/tenacity-4.8.0/ChangeLog        2017-12-14 09:53:45.000000000 +0100
@@ -1,6 +1,34 @@
 CHANGES
 =======
 
+4.8.0
+-----
+
+* Allow waiters to introspect last result
+
+4.7.1
+-----
+
+* Missed top level import of stop\_when\_event\_set
+* Mention Tornado minimum version in README
+* Fix unless\_exception test names and add no input test
+
+4.7.0
+-----
+
+* Add Tornado support
+* Fix pep8
+
+4.6.1
+-----
+
+* Simplify wrapping code
+
+4.6.0
+-----
+
+* Implement \`retry\_with' on decorated functions
+
 4.5.0
 -----
 
@@ -92,10 +120,3 @@
 -----
 
 * Deprecate wait\_jitter for wait\_random
-* Align tox and travis settings
-* Fix README typo
-* Bump hacking to 0.12
-* Fix README.rst wrong description
-* This is using floating point seconds (not milliseconds)
-* Some small docstring updates
-* Use py3.x compat print in README.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/PKG-INFO new/tenacity-4.8.0/PKG-INFO
--- old/tenacity-4.5.0/PKG-INFO 2017-10-24 10:41:17.000000000 +0200
+++ new/tenacity-4.8.0/PKG-INFO 2017-12-14 09:53:45.000000000 +0100
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: tenacity
-Version: 4.5.0
+Version: 4.8.0
 Summary: Retry code until it succeeeds
 Home-page: https://github.com/jd/tenacity
 Author: Julien Danjou
 Author-email: [email protected]
 License: UNKNOWN
+Description-Content-Type: UNKNOWN
 Description: Tenacity
         ========
         .. image:: https://img.shields.io/pypi/v/tenacity.svg
@@ -283,8 +284,29 @@
         
            ...
         
-        Finally, ``retry`` works also on asyncio coroutines. Sleeps are done
-        asynchronously too.
+        You can change the arguments of a retry decorator as needed when 
calling it by
+        using the `retry_with` function attached to the wrapped function:
+        
+        .. testcode::
+        
+            @retry(stop=stop_after_attempt(3))
+            def raise_my_exception():
+                raise MyException("Fail")
+        
+            try:
+                raise_my_exception.retry_with(stop=stop_after_attempt(4))()
+            except Exception:
+                pass
+        
+            print(raise_my_exception.retry.statistics)
+        
+        .. testoutput::
+           :hide:
+        
+           ...
+        
+        Finally, ``retry`` works also on asyncio and Tornado (>= 4.5) 
coroutines.
+        Sleeps are done asynchronously too.
         
         .. code-block:: python
         
@@ -292,6 +314,13 @@
             async def my_async_function(loop):
                 await loop.getaddrinfo('8.8.8.8', 53)
         
+        .. code-block:: python
+        
+            @retry
+            @tornado.gen.coroutine
+            def my_async_function(http_client, url):
+                yield http_client.fetch(url)
+        
         Contribute
         ----------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/README.rst 
new/tenacity-4.8.0/README.rst
--- old/tenacity-4.5.0/README.rst       2017-10-24 10:40:34.000000000 +0200
+++ new/tenacity-4.8.0/README.rst       2017-12-14 09:53:01.000000000 +0100
@@ -275,8 +275,29 @@
 
    ...
 
-Finally, ``retry`` works also on asyncio coroutines. Sleeps are done
-asynchronously too.
+You can change the arguments of a retry decorator as needed when calling it by
+using the `retry_with` function attached to the wrapped function:
+
+.. testcode::
+
+    @retry(stop=stop_after_attempt(3))
+    def raise_my_exception():
+        raise MyException("Fail")
+
+    try:
+        raise_my_exception.retry_with(stop=stop_after_attempt(4))()
+    except Exception:
+        pass
+
+    print(raise_my_exception.retry.statistics)
+
+.. testoutput::
+   :hide:
+
+   ...
+
+Finally, ``retry`` works also on asyncio and Tornado (>= 4.5) coroutines.
+Sleeps are done asynchronously too.
 
 .. code-block:: python
 
@@ -284,6 +305,13 @@
     async def my_async_function(loop):
         await loop.getaddrinfo('8.8.8.8', 53)
 
+.. code-block:: python
+
+    @retry
+    @tornado.gen.coroutine
+    def my_async_function(http_client, url):
+        yield http_client.fetch(url)
+
 Contribute
 ----------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/doc/source/index.rst 
new/tenacity-4.8.0/doc/source/index.rst
--- old/tenacity-4.5.0/doc/source/index.rst     2017-10-24 10:40:34.000000000 
+0200
+++ new/tenacity-4.8.0/doc/source/index.rst     2017-12-14 09:53:01.000000000 
+0100
@@ -275,8 +275,29 @@
 
    ...
 
-Finally, ``retry`` works also on asyncio coroutines. Sleeps are done
-asynchronously too.
+You can change the arguments of a retry decorator as needed when calling it by
+using the `retry_with` function attached to the wrapped function:
+
+.. testcode::
+
+    @retry(stop=stop_after_attempt(3))
+    def raise_my_exception():
+        raise MyException("Fail")
+
+    try:
+        raise_my_exception.retry_with(stop=stop_after_attempt(4))()
+    except Exception:
+        pass
+
+    print(raise_my_exception.retry.statistics)
+
+.. testoutput::
+   :hide:
+
+   ...
+
+Finally, ``retry`` works also on asyncio and Tornado (>= 4.5) coroutines.
+Sleeps are done asynchronously too.
 
 .. code-block:: python
 
@@ -284,6 +305,13 @@
     async def my_async_function(loop):
         await loop.getaddrinfo('8.8.8.8', 53)
 
+.. code-block:: python
+
+    @retry
+    @tornado.gen.coroutine
+    def my_async_function(http_client, url):
+        yield http_client.fetch(url)
+
 Contribute
 ----------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/tenacity/__init__.py 
new/tenacity-4.8.0/tenacity/__init__.py
--- old/tenacity-4.5.0/tenacity/__init__.py     2017-10-24 10:40:34.000000000 
+0200
+++ new/tenacity-4.8.0/tenacity/__init__.py     2017-12-14 09:53:01.000000000 
+0100
@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
+# Copyright 2017 Elisey Zanko
 # Copyright 2016 Étienne Bersac
 # Copyright 2016 Julien Danjou
 # Copyright 2016 Joshua Harlow
@@ -21,13 +22,23 @@
 except ImportError:
     asyncio = None
 
+try:
+    import tornado
+except ImportError:
+    tornado = None
+
+import inspect
 import sys
 import threading
-
 from concurrent import futures
+
 from monotonic import monotonic as now
+
 import six
 
+from tenacity import _utils
+from tenacity import wait as _wait
+
 # Import all built-in retry strategies for easier usage.
 from .retry import retry_all  # noqa
 from .retry import retry_always  # noqa
@@ -49,6 +60,7 @@
 from .stop import stop_all  # noqa
 from .stop import stop_any  # noqa
 from .stop import stop_never  # noqa
+from .stop import stop_when_event_set  # noqa
 
 # Import all built-in wait strategies for easier usage.
 from .wait import wait_chain  # noqa
@@ -69,8 +81,6 @@
 from .after import after_log  # noqa
 from .after import after_nothing  # noqa
 
-from tenacity import _utils
-
 
 def retry(*dargs, **dkw):
     """Wrap a function with a new `Retrying` object.
@@ -85,6 +95,8 @@
         def wrap(f):
             if asyncio and asyncio.iscoroutinefunction(f):
                 r = AsyncRetrying(*dargs, **dkw)
+            elif tornado and tornado.gen.is_coroutine_function(f):
+                r = TornadoRetrying(*dargs, **dkw)
             else:
                 r = Retrying(*dargs, **dkw)
 
@@ -108,6 +120,9 @@
     pass
 
 
+_unset = object()
+
+
 class BaseRetrying(object):
 
     def __init__(self,
@@ -125,6 +140,32 @@
         self.after = after
         self.reraise = reraise
         self._local = threading.local()
+        # This will allow for passing in the result and handling
+        # the older versions of these functions that do not take
+        # the prior result.
+        self._wait_takes_result = self._waiter_takes_last_result(wait)
+
+    def copy(self, sleep=_unset, stop=_unset, wait=_unset,
+             retry=_unset, before=_unset, after=_unset, reraise=_unset):
+        """Copy this object with some parameters changed if needed."""
+        return self.__class__(
+            sleep=self.sleep if sleep is _unset else sleep,
+            stop=self.stop if stop is _unset else stop,
+            wait=self.wait if wait is _unset else wait,
+            retry=self.retry if retry is _unset else retry,
+            before=self.before if before is _unset else before,
+            after=self.after if after is _unset else after,
+            reraise=self.reraise if after is _unset else reraise,
+        )
+
+    @staticmethod
+    def _waiter_takes_last_result(waiter):
+        if not six.callable(waiter):
+            return False
+        if isinstance(waiter, _wait.wait_base):
+            waiter = waiter.__call__
+        waiter_spec = inspect.getargspec(waiter)
+        return 'last_result' in waiter_spec.args
 
     def __repr__(self):
         attrs = dict(
@@ -171,7 +212,13 @@
         @six.wraps(f)
         def wrapped_f(*args, **kw):
             return self.call(f, *args, **kw)
+
+        def retry_with(*args, **kwargs):
+            return self.copy(*args, **kwargs).wraps(f)
+
         wrapped_f.retry = self
+        wrapped_f.retry_with = retry_with
+
         return wrapped_f
 
     def begin(self, fn):
@@ -219,8 +266,12 @@
             six.raise_from(RetryError(fut), fut.exception())
 
         if self.wait:
-            sleep = self.wait(self.statistics['attempt_number'],
-                              delay_since_first_attempt)
+            if self._wait_takes_result:
+                sleep = self.wait(self.statistics['attempt_number'],
+                                  delay_since_first_attempt, last_result=fut)
+            else:
+                sleep = self.wait(self.statistics['attempt_number'],
+                                  delay_since_first_attempt)
         else:
             sleep = 0
         self.statistics['idle_for'] += sleep
@@ -299,3 +350,6 @@
 
 if asyncio:
     from tenacity.async import AsyncRetrying
+
+if tornado:
+    from tenacity.tornadoweb import TornadoRetrying
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/tenacity/tests/test_tenacity.py 
new/tenacity-4.8.0/tenacity/tests/test_tenacity.py
--- old/tenacity-4.5.0/tenacity/tests/test_tenacity.py  2017-10-24 
10:40:34.000000000 +0200
+++ new/tenacity-4.8.0/tenacity/tests/test_tenacity.py  2017-12-14 
09:53:01.000000000 +0100
@@ -175,6 +175,24 @@
     def test_legacy_explicit_wait_type(self):
         Retrying(wait="exponential_sleep")
 
+    def test_wait_func_result(self):
+        captures = []
+
+        def wait_capture(attempt, delay, last_result=None):
+            captures.append(last_result)
+            return 1
+
+        def dying():
+            raise Exception("Broken")
+
+        r_attempts = 10
+        r = Retrying(wait=wait_capture, sleep=lambda secs: None,
+                     stop=tenacity.stop_after_attempt(r_attempts),
+                     reraise=True)
+        self.assertRaises(Exception, r.call, dying)
+        self.assertEqual(r_attempts - 1, len(captures))
+        self.assertTrue(all([r.failed for r in captures]))
+
     def test_wait_func(self):
         r = Retrying(wait=lambda attempt, delay: attempt * delay)
         self.assertEqual(r.wait(1, 5), 5)
@@ -525,14 +543,19 @@
 
 
 @retry(retry=tenacity.retry_unless_exception_type(NameError))
-def _retryable_test_with_not_exception_type_name(thing):
+def _retryable_test_with_unless_exception_type_name(thing):
     return thing.go()
 
 
 @retry(
     stop=tenacity.stop_after_attempt(3),
     retry=tenacity.retry_unless_exception_type(NameError))
-def _retryable_test_with_not_exception_type_name_attempt_limit(thing):
+def _retryable_test_with_unless_exception_type_name_attempt_limit(thing):
+    return thing.go()
+
+
+@retry(retry=tenacity.retry_unless_exception_type())
+def _retryable_test_with_unless_exception_type_no_input(thing):
     return thing.go()
 
 
@@ -567,6 +590,14 @@
         self.assertGreaterEqual(t, 250)
         self.assertTrue(result)
 
+    def test_retry_with(self):
+        start = current_time_ms()
+        result = _retryable_test_with_wait.retry_with(
+            wait=tenacity.wait_fixed(0.1))(NoneReturnUntilAfterCount(5))
+        t = current_time_ms() - start
+        self.assertGreaterEqual(t, 500)
+        self.assertTrue(result)
+
     def test_with_stop_on_return_value(self):
         try:
             _retryable_test_with_stop(NoneReturnUntilAfterCount(5))
@@ -609,10 +640,26 @@
 
     def test_retry_until_exception_of_type_attempt_number(self):
         try:
-            self.assertTrue(_retryable_test_with_not_exception_type_name(
+            self.assertTrue(_retryable_test_with_unless_exception_type_name(
                 NameErrorUntilCount(5)))
         except NameError as e:
-            s = _retryable_test_with_not_exception_type_name.retry.statistics
+            s = _retryable_test_with_unless_exception_type_name.\
+                retry.statistics
+            self.assertTrue(s['attempt_number'] == 6)
+            print(e)
+        else:
+            self.fail("Expected NameError")
+
+    def test_retry_until_exception_of_type_no_type(self):
+        try:
+            # no input should catch all subclasses of Exception
+            self.assertTrue(
+                _retryable_test_with_unless_exception_type_no_input(
+                    NameErrorUntilCount(5))
+            )
+        except NameError as e:
+            s = _retryable_test_with_unless_exception_type_no_input.\
+                retry.statistics
             self.assertTrue(s['attempt_number'] == 6)
             print(e)
         else:
@@ -621,7 +668,7 @@
     def test_retry_until_exception_of_type_wrong_exception(self):
         try:
             # two iterations with IOError, one that returns True
-            _retryable_test_with_not_exception_type_name_attempt_limit(
+            _retryable_test_with_unless_exception_type_name_attempt_limit(
                 IOErrorUntilCount(2))
             self.fail("Expected RetryError")
         except RetryError as e:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/tenacity/tests/test_tornado.py 
new/tenacity-4.8.0/tenacity/tests/test_tornado.py
--- old/tenacity-4.5.0/tenacity/tests/test_tornado.py   1970-01-01 
01:00:00.000000000 +0100
+++ new/tenacity-4.8.0/tenacity/tests/test_tornado.py   2017-12-14 
09:53:01.000000000 +0100
@@ -0,0 +1,46 @@
+# coding: utf-8
+# Copyright 2017 Elisey Zanko
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+
+from tenacity import retry
+from tenacity import tornadoweb
+from tenacity.tests.test_tenacity import NoIOErrorAfterCount
+
+from tornado import gen
+from tornado import testing
+
+
+@retry
[email protected]
+def _retryable_coroutine(thing):
+    yield gen.sleep(0.00001)
+    thing.go()
+
+
+class TestTornado(testing.AsyncTestCase):
+    @testing.gen_test
+    def test_retry(self):
+        assert gen.is_coroutine_function(_retryable_coroutine)
+        thing = NoIOErrorAfterCount(5)
+        yield _retryable_coroutine(thing)
+        assert thing.counter == thing.count
+
+    def test_repr(self):
+        repr(tornadoweb.TornadoRetrying())
+
+
+if __name__ == '__main__':
+    unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/tenacity/tornadoweb.py 
new/tenacity-4.8.0/tenacity/tornadoweb.py
--- old/tenacity-4.5.0/tenacity/tornadoweb.py   1970-01-01 01:00:00.000000000 
+0100
+++ new/tenacity-4.8.0/tenacity/tornadoweb.py   2017-12-14 09:53:01.000000000 
+0100
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+# Copyright 2017 Elisey Zanko
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+
+from monotonic import monotonic as now
+
+from tenacity import BaseRetrying
+from tenacity import DoAttempt
+from tenacity import DoSleep
+from tenacity import NO_RESULT
+
+from tornado import gen
+
+
+class TornadoRetrying(BaseRetrying):
+
+    def __init__(self,
+                 sleep=gen.sleep,
+                 **kwargs):
+        super(TornadoRetrying, self).__init__(**kwargs)
+        self.sleep = sleep
+
+    @gen.coroutine
+    def call(self, fn, *args, **kwargs):
+        self.begin(fn)
+
+        result = NO_RESULT
+        exc_info = None
+        start_time = now()
+
+        while True:
+            do = self.iter(result=result, exc_info=exc_info,
+                           start_time=start_time)
+            if isinstance(do, DoAttempt):
+                try:
+                    result = yield fn(*args, **kwargs)
+                    exc_info = None
+                    continue
+                except Exception:
+                    result = NO_RESULT
+                    exc_info = sys.exc_info()
+                    continue
+            elif isinstance(do, DoSleep):
+                result = NO_RESULT
+                exc_info = None
+                yield self.sleep(do)
+            else:
+                raise gen.Return(do)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/tenacity/wait.py 
new/tenacity-4.8.0/tenacity/wait.py
--- old/tenacity-4.5.0/tenacity/wait.py 2017-10-24 10:40:34.000000000 +0200
+++ new/tenacity-4.8.0/tenacity/wait.py 2017-12-14 09:53:01.000000000 +0100
@@ -27,7 +27,8 @@
     """Abstract base class for wait strategies."""
 
     @abc.abstractmethod
-    def __call__(self, previous_attempt_number, delay_since_first_attempt):
+    def __call__(self, previous_attempt_number, delay_since_first_attempt,
+                 last_result=None):
         pass
 
     def __add__(self, other):
@@ -46,7 +47,8 @@
     def __init__(self, wait):
         self.wait_fixed = wait
 
-    def __call__(self, previous_attempt_number, delay_since_first_attempt):
+    def __call__(self, previous_attempt_number, delay_since_first_attempt,
+                 last_result=None):
         return self.wait_fixed
 
 
@@ -64,7 +66,8 @@
         self.wait_random_min = min
         self.wait_random_max = max
 
-    def __call__(self, previous_attempt_number, delay_since_first_attempt):
+    def __call__(self, previous_attempt_number, delay_since_first_attempt,
+                 last_result=None):
         return (self.wait_random_min +
                 (random.random() *
                  (self.wait_random_max - self.wait_random_min)))
@@ -76,7 +79,8 @@
     def __init__(self, *strategies):
         self.wait_funcs = strategies
 
-    def __call__(self, previous_attempt_number, delay_since_first_attempt):
+    def __call__(self, previous_attempt_number, delay_since_first_attempt,
+                 last_result=None):
         return sum(map(
             lambda x: x(previous_attempt_number, delay_since_first_attempt),
             self.wait_funcs))
@@ -101,7 +105,8 @@
     def __init__(self, *strategies):
         self.strategies = list(strategies)
 
-    def __call__(self, previous_attempt_number, delay_since_first_attempt):
+    def __call__(self, previous_attempt_number, delay_since_first_attempt,
+                 last_result=None):
         wait_func = self.strategies[0]
         if len(self.strategies) > 1:
             self.strategies.pop(0)
@@ -120,7 +125,8 @@
         self.increment = increment
         self.max = max
 
-    def __call__(self, previous_attempt_number, delay_since_first_attempt):
+    def __call__(self, previous_attempt_number, delay_since_first_attempt,
+                 last_result=None):
         result = self.start + (
             self.increment * (previous_attempt_number - 1)
         )
@@ -145,7 +151,8 @@
         self.max = max
         self.exp_base = exp_base
 
-    def __call__(self, previous_attempt_number, delay_since_first_attempt):
+    def __call__(self, previous_attempt_number, delay_since_first_attempt,
+                 last_result=None):
         try:
             exp = self.exp_base ** previous_attempt_number
             result = self.multiplier * exp
@@ -179,7 +186,8 @@
     wait_exponential strategy (which uses a fixed interval) may be preferable.
     """
 
-    def __call__(self, previous_attempt_number, delay_since_first_attempt):
+    def __call__(self, previous_attempt_number, delay_since_first_attempt,
+                 last_result=None):
         high = super(wait_random_exponential, self).__call__(
             previous_attempt_number, delay_since_first_attempt)
         return random.uniform(0, high)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/tenacity.egg-info/PKG-INFO 
new/tenacity-4.8.0/tenacity.egg-info/PKG-INFO
--- old/tenacity-4.5.0/tenacity.egg-info/PKG-INFO       2017-10-24 
10:41:17.000000000 +0200
+++ new/tenacity-4.8.0/tenacity.egg-info/PKG-INFO       2017-12-14 
09:53:45.000000000 +0100
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: tenacity
-Version: 4.5.0
+Version: 4.8.0
 Summary: Retry code until it succeeeds
 Home-page: https://github.com/jd/tenacity
 Author: Julien Danjou
 Author-email: [email protected]
 License: UNKNOWN
+Description-Content-Type: UNKNOWN
 Description: Tenacity
         ========
         .. image:: https://img.shields.io/pypi/v/tenacity.svg
@@ -283,8 +284,29 @@
         
            ...
         
-        Finally, ``retry`` works also on asyncio coroutines. Sleeps are done
-        asynchronously too.
+        You can change the arguments of a retry decorator as needed when 
calling it by
+        using the `retry_with` function attached to the wrapped function:
+        
+        .. testcode::
+        
+            @retry(stop=stop_after_attempt(3))
+            def raise_my_exception():
+                raise MyException("Fail")
+        
+            try:
+                raise_my_exception.retry_with(stop=stop_after_attempt(4))()
+            except Exception:
+                pass
+        
+            print(raise_my_exception.retry.statistics)
+        
+        .. testoutput::
+           :hide:
+        
+           ...
+        
+        Finally, ``retry`` works also on asyncio and Tornado (>= 4.5) 
coroutines.
+        Sleeps are done asynchronously too.
         
         .. code-block:: python
         
@@ -292,6 +314,13 @@
             async def my_async_function(loop):
                 await loop.getaddrinfo('8.8.8.8', 53)
         
+        .. code-block:: python
+        
+            @retry
+            @tornado.gen.coroutine
+            def my_async_function(http_client, url):
+                yield http_client.fetch(url)
+        
         Contribute
         ----------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/tenacity.egg-info/SOURCES.txt 
new/tenacity-4.8.0/tenacity.egg-info/SOURCES.txt
--- old/tenacity-4.5.0/tenacity.egg-info/SOURCES.txt    2017-10-24 
10:41:17.000000000 +0200
+++ new/tenacity-4.8.0/tenacity.egg-info/SOURCES.txt    2017-12-14 
09:53:45.000000000 +0100
@@ -17,6 +17,7 @@
 tenacity/nap.py
 tenacity/retry.py
 tenacity/stop.py
+tenacity/tornadoweb.py
 tenacity/wait.py
 tenacity.egg-info/PKG-INFO
 tenacity.egg-info/SOURCES.txt
@@ -27,4 +28,5 @@
 tenacity.egg-info/top_level.txt
 tenacity/tests/__init__.py
 tenacity/tests/test_async.py
-tenacity/tests/test_tenacity.py
\ No newline at end of file
+tenacity/tests/test_tenacity.py
+tenacity/tests/test_tornado.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/tenacity.egg-info/pbr.json 
new/tenacity-4.8.0/tenacity.egg-info/pbr.json
--- old/tenacity-4.5.0/tenacity.egg-info/pbr.json       2017-10-24 
10:41:17.000000000 +0200
+++ new/tenacity-4.8.0/tenacity.egg-info/pbr.json       2017-12-14 
09:53:45.000000000 +0100
@@ -1 +1 @@
-{"git_version": "a86237f", "is_release": true}
\ No newline at end of file
+{"git_version": "69cf4a7", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-4.5.0/tox.ini new/tenacity-4.8.0/tox.ini
--- old/tenacity-4.5.0/tox.ini  2017-10-24 10:40:34.000000000 +0200
+++ new/tenacity-4.8.0/tox.ini  2017-12-14 09:53:01.000000000 +0100
@@ -13,6 +13,7 @@
 deps =
     nose
     sphinx
+    tornado
 commands =
     py{27,py}: python setup.py nosetests --ignore-files '.*async.py'
     py3{5,6}: python setup.py nosetests


Reply via email to