Hello community,

here is the log from the commit of package python-backoff for openSUSE:Factory 
checked in at 2020-01-18 12:18:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-backoff (Old)
 and      /work/SRC/openSUSE:Factory/.python-backoff.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-backoff"

Sat Jan 18 12:18:12 2020 rev:4 rq:765348 version:1.10.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-backoff/python-backoff.changes    
2019-06-06 18:16:47.116695464 +0200
+++ /work/SRC/openSUSE:Factory/.python-backoff.new.26092/python-backoff.changes 
2020-01-18 12:19:00.595167185 +0100
@@ -1,0 +2,7 @@
+Fri Jan 17 16:42:58 UTC 2020 - Marketa Calabkova <[email protected]>
+
+- update to 1.10.0
+  * Support python 3.8
+  * Allow sync decorator call from async function
+
+-------------------------------------------------------------------

Old:
----
  backoff-1.8.0.tar.gz

New:
----
  backoff-1.10.0.tar.gz

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

Other differences:
------------------
++++++ python-backoff.spec ++++++
--- /var/tmp/diff_new_pack.pB9vAX/_old  2020-01-18 12:19:01.327167578 +0100
+++ /var/tmp/diff_new_pack.pB9vAX/_new  2020-01-18 12:19:01.331167580 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-backoff
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,24 +18,23 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-backoff
-Version:        1.8.0
+Version:        1.10.0
 Release:        0
 Summary:        Function decoration for backoff and retry
 License:        MIT
 Group:          Development/Languages/Python
-Url:            https://github.com/litl/backoff
+URL:            https://github.com/litl/backoff
 Source0:        
https://files.pythonhosted.org/packages/source/b/backoff/backoff-%{version}.tar.gz
 # https://github.com/litl/backoff/issues/75
 # github repo does not have setup.py
 Source1:        tests.tar.bz2
 BuildRequires:  %{python_module setuptools}
-# SECTION test requirements
-BuildRequires:  %{python_module pytest}
-# /SECTION
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 BuildArch:      noarch
-
+# SECTION test requirements
+BuildRequires:  %{python_module pytest}
+# /SECTION
 %python_subpackages
 
 %description
@@ -66,7 +65,6 @@
 %pytest
 
 %files %{python_files}
-%defattr(-,root,root,-)
 %doc README.rst
 %license LICENSE
 %{python_sitelib}/*

++++++ backoff-1.8.0.tar.gz -> backoff-1.10.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backoff-1.8.0/PKG-INFO new/backoff-1.10.0/PKG-INFO
--- old/backoff-1.8.0/PKG-INFO  1970-01-01 01:00:00.000000000 +0100
+++ new/backoff-1.10.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
@@ -1,12 +1,12 @@
 Metadata-Version: 2.1
 Name: backoff
-Version: 1.8.0
+Version: 1.10.0
 Summary: Function decoration for backoff and retry
 Home-page: https://github.com/litl/backoff
 Author: Bob Green
 Author-email: [email protected]
 Keywords: retry,backoff,decorators
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: MIT License
@@ -16,10 +16,10 @@
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
 Classifier: Topic :: Internet :: WWW/HTTP
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Classifier: Topic :: Utilities
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backoff-1.8.0/README.rst 
new/backoff-1.10.0/README.rst
--- old/backoff-1.8.0/README.rst        2018-12-15 18:22:25.000000000 +0100
+++ new/backoff-1.10.0/README.rst       2019-09-28 12:09:16.601051300 +0200
@@ -176,7 +176,7 @@
                           requests.exceptions.HTTPError,
                           max_time=60)
     @backoff.on_exception(backoff.expo,
-                          requests.exceptions.TimeoutError,
+                          requests.exceptions.Timeout,
                           max_time=300)
     def poll_for_message(queue):
         return queue.get()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backoff-1.8.0/backoff/__init__.py 
new/backoff-1.10.0/backoff/__init__.py
--- old/backoff-1.8.0/backoff/__init__.py       2018-12-21 06:19:40.000000000 
+0100
+++ new/backoff-1.10.0/backoff/__init__.py      2019-12-07 22:01:32.459555400 
+0100
@@ -26,4 +26,4 @@
     'random_jitter'
 ]
 
-__version__ = '1.8.0'
+__version__ = '1.10.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backoff-1.8.0/backoff/_async.py 
new/backoff-1.10.0/backoff/_async.py
--- old/backoff-1.8.0/backoff/_async.py 2018-12-15 18:22:25.000000000 +0100
+++ new/backoff-1.10.0/backoff/_async.py        2019-11-24 19:01:03.877472400 
+0100
@@ -1,8 +1,7 @@
 # coding:utf-8
 import datetime
 import functools
-# Python 3.4 code and syntax is allowed in this module!
-import asyncio
+import asyncio  # Python 3.5 code and syntax is allowed in this file
 from datetime import timedelta
 
 from backoff._common import (_init_wait_gen, _maybe_call, _next_wait)
@@ -12,7 +11,10 @@
     if asyncio.iscoroutinefunction(coro_or_func):
         return coro_or_func
     else:
-        return asyncio.coroutine(coro_or_func)
+        @functools.wraps(coro_or_func)
+        async def f(*args, **kwargs):
+            return coro_or_func(*args, **kwargs)
+        return f
 
 
 def _ensure_coroutines(coros_or_funcs):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backoff-1.8.0/backoff/_common.py 
new/backoff-1.10.0/backoff/_common.py
--- old/backoff-1.8.0/backoff/_common.py        2018-12-15 18:22:25.000000000 
+0100
+++ new/backoff-1.10.0/backoff/_common.py       2019-11-24 19:01:03.877809300 
+0100
@@ -19,7 +19,6 @@
 
 
 def _init_wait_gen(wait_gen, wait_gen_kwargs):
-    # there are no dictionary comprehensions in python 2.6
     kwargs = {k: _maybe_call(v) for k, v in wait_gen_kwargs.items()}
     return wait_gen(**kwargs)
 
@@ -75,28 +74,28 @@
 
 # Default backoff handler
 def _log_backoff(details, logger):
-    fmt = "Backing off {0}(...) for {1:.1f}s"
-    msg = fmt.format(details['target'].__name__, details['wait'])
+    msg = "Backing off %s(...) for %.1fs (%s)"
+    log_args = [details['target'].__name__, details['wait']]
 
     exc_typ, exc, _ = sys.exc_info()
     if exc is not None:
         exc_fmt = traceback.format_exception_only(exc_typ, exc)[-1]
-        msg = "{} ({})".format(msg, exc_fmt.rstrip("\n"))
+        log_args.append(exc_fmt.rstrip("\n"))
     else:
-        msg = "{} ({})".format(msg, details['value'])
-    logger.info(msg)
+        log_args.append(details['value'])
+    logger.info(msg, *log_args)
 
 
 # Default giveup handler
 def _log_giveup(details, logger):
-    fmt = "Giving up {0}(...) after {1} tries"
-    msg = fmt.format(details['target'].__name__, details['tries'])
+    msg = "Giving up %s(...) after %d tries (%s)"
+    log_args = [details['target'].__name__, details['tries']]
 
     exc_typ, exc, _ = sys.exc_info()
     if exc is not None:
         exc_fmt = traceback.format_exception_only(exc_typ, exc)[-1]
-        msg = "{} ({})".format(msg, exc_fmt.rstrip("\n"))
+        log_args.append(exc_fmt.rstrip("\n"))
     else:
-        msg = "{} ({})".format(msg, details['value'])
+        log_args.append(details['value'])
 
-    logger.error(msg)
+    logger.error(msg, *log_args)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backoff-1.8.0/backoff/_decorator.py 
new/backoff-1.10.0/backoff/_decorator.py
--- old/backoff-1.8.0/backoff/_decorator.py     2018-12-21 06:08:23.000000000 
+0100
+++ new/backoff-1.10.0/backoff/_decorator.py    2019-12-07 22:00:50.005837200 
+0100
@@ -85,15 +85,6 @@
                 import backoff._async
                 retry = backoff._async.retry_predicate
 
-            elif _is_event_loop() and _is_current_task():
-                # Verify that sync version is not being run from coroutine
-                # (that would lead to event loop hiccups).
-                raise TypeError(
-                    "backoff.on_predicate applied to a regular function "
-                    "inside coroutine, this will lead to event loop "
-                    "hiccups. Use backoff.on_predicate on coroutines in "
-                    "asynchronous code.")
-
         if retry is None:
             retry = _sync.retry_predicate
 
@@ -174,14 +165,6 @@
             if asyncio.iscoroutinefunction(target):
                 import backoff._async
                 retry = backoff._async.retry_exception
-            elif _is_event_loop() and _is_current_task():
-                # Verify that sync version is not being run from coroutine
-                # (that would lead to event loop hiccups).
-                raise TypeError(
-                    "backoff.on_exception applied to a regular function "
-                    "inside coroutine, this will lead to event loop "
-                    "hiccups. Use backoff.on_exception on coroutines in "
-                    "asynchronous code.")
 
         if retry is None:
             retry = _sync.retry_exception
@@ -193,25 +176,3 @@
 
     # Return a function which decorates a target with a retry loop.
     return decorate
-
-
-def _is_event_loop():  # pragma: no cover
-    import asyncio
-
-    try:
-        if sys.version_info >= (3, 7):
-            asyncio.get_running_loop()
-
-        asyncio.get_event_loop()
-    except RuntimeError:
-        return False
-    else:
-        return True
-
-
-def _is_current_task():  # pragma: no cover
-    import asyncio
-    if sys.version_info >= (3, 7):
-        return asyncio.current_task() is not None
-
-    return asyncio.Task.current_task() is not None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backoff-1.8.0/pyproject.toml 
new/backoff-1.10.0/pyproject.toml
--- old/backoff-1.8.0/pyproject.toml    2018-12-21 06:19:07.000000000 +0100
+++ new/backoff-1.10.0/pyproject.toml   2019-12-07 22:01:41.996678800 +0100
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "backoff"
-version = "1.8.0"
+version = "1.10.0"
 description = "Function decoration for backoff and retry"
 authors = ["Bob Green <[email protected]>"]
 readme = "README.rst"
@@ -17,27 +17,25 @@
                'Programming Language :: Python :: 2',
                'Programming Language :: Python :: 2.7',
                'Programming Language :: Python :: 3',
-               'Programming Language :: Python :: 3.4',
                'Programming Language :: Python :: 3.5',
                'Programming Language :: Python :: 3.6',
                'Programming Language :: Python :: 3.7',
+               'Programming Language :: Python :: 3.8',
                'Topic :: Internet :: WWW/HTTP',
                'Topic :: Software Development :: Libraries :: Python Modules',
                'Topic :: Utilities']
 packages = [
     { include = "backoff" },
-    { include = "README.rst" },
-    { include = "LICENSE" },
 ]
 
 [tool.poetry.dependencies]
-python = "^2.7 || ^3.4"
+python = "^2.7 || ^3.5"
 
 [tool.poetry.dev-dependencies]
 flake8 = "^3.6"
 pytest = "^4.0"
 pytest-cov = "^2.6"
-pytest-asyncio = {version = "^0.9.0",python = "^3.5"}
+pytest-asyncio = {version = "^0.10.0",python = "^3.5"}
 
 [build-system]
 requires = ["poetry>=0.12"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backoff-1.8.0/setup.py new/backoff-1.10.0/setup.py
--- old/backoff-1.8.0/setup.py  1970-01-01 01:00:00.000000000 +0100
+++ new/backoff-1.10.0/setup.py 1970-01-01 01:00:00.000000000 +0100
@@ -7,20 +7,17 @@
 package_data = \
 {'': ['*']}
 
-modules = \
-['README', 'LICENSE']
 setup_kwargs = {
     'name': 'backoff',
-    'version': '1.8.0',
+    'version': '1.10.0',
     'description': 'Function decoration for backoff and retry',
-    'long_description': 'backoff\n=======\n\n.. image:: 
https://travis-ci.org/litl/backoff.svg?branch=master\n    :target: 
https://travis-ci.org/litl/backoff?branch=master\n.. image:: 
https://coveralls.io/repos/litl/backoff/badge.svg?branch=master\n    :target: 
https://coveralls.io/r/litl/backoff?branch=master\n.. image:: 
https://img.shields.io/pypi/v/backoff.svg\n    :target: 
https://pypi.python.org/pypi/backoff\n\n**Function decoration for backoff and 
retry**\n\nThis module provides function decorators which can be used to wrap 
a\nfunction such that it will be retried until some condition is met. It\nis 
meant to be of use when accessing unreliable resources with the\npotential for 
intermittent failures i.e. network resources and external\nAPIs. Somewhat more 
generally, it may also be of use for dynamically\npolling resources for 
externally generated content.\n\nDecorators support both regular functions for 
synchronous code and\n`asyncio 
<https://docs.python.org/3/library/asyncio.html>`_\'s coroutines\nfor 
asynchronous code.\n\nExamples\n========\n\nSince Kenneth Reitz\'s `requests 
<http://python-requests.org>`_ module\nhas become a defacto standard for 
synchronous HTTP clients in Python,\nnetworking examples below are written 
using it, but it is in no way required\nby the backoff 
module.\n\[email protected]_exception\n---------------------\n\nThe ``on_exception`` 
decorator is used to retry when a specified exception\nis raised. Here\'s an 
example using exponential backoff when any\n``requests`` exception is 
raised:\n\n.. code-block:: python\n\n    @backoff.on_exception(backoff.expo,\n  
                        requests.exceptions.RequestException)\n    def 
get_url(url):\n        return requests.get(url)\n\nThe decorator will also 
accept a tuple of exceptions for cases where\nthe same backoff behavior is 
desired for more than one exception type:\n\n.. code-block:: python\n\n    
@backoff.on_exception(backoff.expo,\n                          
(requests.exceptions.Timeout,\n                           
requests.exceptions.ConnectionError))\n    def get_url(url):\n        return 
requests.get(url)\n\n**Give Up Conditions**\n\nOptional keyword arguments can 
specify conditions under which to give\nup.\n\nThe keyword argument 
``max_time`` specifies the maximum amount\nof total time in seconds that can 
elapse before giving up.\n\n.. code-block:: python\n\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.RequestException,\n                          max_time=60)\n 
   def get_url(url):\n        return requests.get(url)\n\n\nKeyword argument 
``max_tries`` specifies the maximum number of calls\nto make to the target 
function before giving up.\n\n.. code-block:: python\n\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.RequestException,\n                          max_tries=8,\n 
                         jitter=None)\n    def get_url(url):\n        return 
requests.get(url)\n\n\nIn some cases the raised exception instance itself may 
need to be\ninspected in order to determine if it is a retryable condition. 
The\n``giveup`` keyword arg can be used to specify a function which 
accepts\nthe exception and returns a truthy value if the exception should 
not\nbe retried:\n\n.. code-block:: python\n\n    def fatal_code(e):\n        
return 400 <= e.response.status_code < 500\n\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.RequestException,\n                          
max_time=300,\n                          giveup=fatal_code)\n    def 
get_url(url):\n        return requests.get(url)\n\nWhen a give up event occurs, 
the exception in question is reraised\nand so code calling an 
`on_exception`-decorated function may still\nneed to do exception 
handling.\n\[email protected]_predicate\n---------------------\n\nThe 
``on_predicate`` decorator is used to retry when a particular\ncondition is 
true of the return value of the target function.  This may\nbe useful when 
polling a resource for externally generated content.\n\nHere\'s an example 
which uses a fibonacci sequence backoff when the\nreturn value of the target 
function is the empty list:\n\n.. code-block:: python\n\n    
@backoff.on_predicate(backoff.fibo, lambda x: x == [], max_value=13)\n    def 
poll_for_messages(queue):\n        return queue.get()\n\nExtra keyword 
arguments are passed when initializing the\nwait generator, so the 
``max_value`` param above is passed as a keyword\narg when initializing the 
fibo generator.\n\nWhen not specified, the predicate param defaults to the 
falsey test,\nso the above can more concisely be written:\n\n.. code-block:: 
python\n\n    @backoff.on_predicate(backoff.fibo, max_value=13)\n    def 
poll_for_message(queue)\n        return queue.get()\n\nMore simply, a function 
which continues polling every second until it\ngets a non-falsey result could 
be defined like like this:\n\n.. code-block:: python\n\n    
@backoff.on_predicate(backoff.constant, interval=1)\n    def 
poll_for_message(queue)\n        return queue.get()\n\nJitter\n------\n\nA 
jitter algorithm can be supplied with the ``jitter`` keyword arg to\neither of 
the backoff decorators. This argument should be a function\naccepting the 
original unadulterated backoff value and returning it\'s\njittered 
counterpart.\n\nAs of version 1.2, the default jitter function 
``backoff.full_jitter``\nimplements the \'Full Jitter\' algorithm as defined in 
the AWS\nArchitecture Blog\'s `Exponential Backoff And 
Jitter\n<https://www.awsarchitectureblog.com/2015/03/backoff.html>`_ 
post.\nNote that with this algorithm, the time yielded by the wait 
generator\nis actually the *maximum* amount of time to wait.\n\nPrevious 
versions of backoff defaulted to adding some random number of\nmilliseconds (up 
to 1s) to the raw sleep value. If desired, this\nbehavior is now available as 
``backoff.random_jitter``.\n\nUsing multiple 
decorators\n-------------------------\n\nThe backoff decorators may also be 
combined to specify different\nbackoff behavior for different cases:\n\n.. 
code-block:: python\n\n    @backoff.on_predicate(backoff.fibo, max_value=13)\n  
  @backoff.on_exception(backoff.expo,\n                          
requests.exceptions.HTTPError,\n                          max_time=60)\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.TimeoutError,\n                          max_time=300)\n    
def poll_for_message(queue):\n        return queue.get()\n\nRuntime 
Configuration\n---------------------\n\nThe decorator functions 
``on_exception`` and ``on_predicate`` are\ngenerally evaluated at import time. 
This is fine when the keyword args\nare passed as constant values, but suppose 
we want to consult a\ndictionary with configuration options that only become 
available at\nruntime. The relevant values are not available at import time. 
Instead,\ndecorator functions can be passed callables which are evaluated 
at\nruntime to obtain the value:\n\n.. code-block:: python\n\n    def 
lookup_max_time():\n        # pretend we have a global reference to \'app\' 
here\n        # and that it has a dictionary-like \'config\' property\n        
return app.config["BACKOFF_MAX_TIME"]\n\n    
@backoff.on_exception(backoff.expo,\n                          ValueError,\n    
                      max_time=lookup_max_time)\n\nEvent 
handlers\n--------------\n\nBoth backoff decorators optionally accept event 
handler functions\nusing the keyword arguments ``on_success``, ``on_backoff``, 
and ``on_giveup``.\nThis may be useful in reporting statistics or performing 
other custom\nlogging.\n\nHandlers must be callables with a unary signature 
accepting a dict\nargument. This dict contains the details of the invocation. 
Valid keys\ninclude:\n\n* *target*: reference to the function or method being 
invoked\n* *args*: positional arguments to func\n* *kwargs*: keyword arguments 
to func\n* *tries*: number of invocation tries so far\n* *elapsed*: elapsed 
time in seconds so far\n* *wait*: seconds to wait (``on_backoff`` handler 
only)\n* *value*: value triggering backoff (``on_predicate`` decorator 
only)\n\nA handler which prints the details of the backoff event could 
be\nimplemented like so:\n\n.. code-block:: python\n\n    def 
backoff_hdlr(details):\n        print ("Backing off {wait:0.1f} seconds afters 
{tries} tries "\n               "calling function {target} with args {args} and 
kwargs "\n               "{kwargs}".format(**details))\n\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.RequestException,\n                          
on_backoff=backoff_hdlr)\n    def get_url(url):\n        return 
requests.get(url)\n\n**Multiple handlers per event type**\n\nIn all cases, 
iterables of handler functions are also accepted, which\nare called in turn. 
For example, you might provide a simple list of\nhandler functions as the value 
of the ``on_backoff`` keyword arg:\n\n.. code-block:: python\n\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.RequestException,\n                          
on_backoff=[backoff_hdlr1, backoff_hdlr2])\n    def get_url(url):\n        
return requests.get(url)\n\n**Getting exception info**\n\nIn the case of the 
``on_exception`` decorator, all ``on_backoff`` and\n``on_giveup`` handlers are 
called from within the except block for the\nexception being handled. Therefore 
exception info is available to the\nhandler functions via the python standard 
library, specifically\n``sys.exc_info()`` or the ``traceback`` 
module.\n\nAsynchronous code\n-----------------\n\nBackoff supports 
asynchronous execution in Python 3.5 and above.\n\nTo use backoff in 
asynchronous code based on\n`asyncio 
<https://docs.python.org/3/library/asyncio.html>`_\nyou simply need to apply 
``backoff.on_exception`` or ``backoff.on_predicate``\nto coroutines.\nYou can 
also use coroutines for the ``on_success``, ``on_backoff``, and\n``on_giveup`` 
event handlers, with the interface otherwise being identical.\n\nThe following 
examples use `aiohttp <https://aiohttp.readthedocs.io/>`_\nasynchronous HTTP 
client/server library.\n\n.. code-block:: python\n\n    
@backoff.on_exception(backoff.expo, aiohttp.ClientError, max_time=60)\n    
async def get_url(url):\n        async with aiohttp.ClientSession() as 
session:\n            async with session.get(url) as response:\n                
return await response.text()\n\nLogging 
configuration\n---------------------\n\nBy default, backoff and retry attempts 
are logged to the \'backoff\'\nlogger. By default, this logger is configured 
with a NullHandler, so\nthere will be nothing output unless you configure a 
handler.\nProgrammatically, this might be accomplished with something as 
simple\nas:\n\n.. code-block:: python\n\n    
logging.getLogger(\'backoff\').addHandler(logging.StreamHandler())\n\nThe 
default logging level is INFO, which corresponds to logging\nanytime a retry 
event occurs. If you would instead like to log\nonly when a giveup event 
occurs, set the logger level to ERROR.\n\n.. code-block:: python\n\n    
logging.getLogger(\'backoff\').setLevel(logging.ERROR)\n\nIt is also possible 
to specify an alternate logger with the ``logger``\nkeyword argument.  If a 
string value is specified the logger will be\nlooked up by name.\n\n.. 
code-block:: python\n\n   @backoff.on_exception(backoff.expo,\n                 
        requests.exception.RequestException,\n\t\t\t logger=\'my_logger\')\n   
# ...\n\nIt is also supported to specify a Logger (or LoggerAdapter) 
object\ndirectly.\n\n.. code-block:: python\n\n    my_logger = 
logging.getLogger(\'my_logger\')\n    my_handler = logging.StreamHandler()\n    
my_logger.add_handler(my_handler)\n    my_logger.setLevel(logging.ERROR)\n\n    
@backoff.on_exception(backoff.expo,\n                         
requests.exception.RequestException,\n\t\t\t logger=my_logger)\n    # 
...\n\nDefault logging can be disabled all together by 
specifying\n``logger=None``. In this case, if desired alternative logging 
behavior\ncould be defined by using custom event handlers.\n',
+    'long_description': 'backoff\n=======\n\n.. image:: 
https://travis-ci.org/litl/backoff.svg?branch=master\n    :target: 
https://travis-ci.org/litl/backoff?branch=master\n.. image:: 
https://coveralls.io/repos/litl/backoff/badge.svg?branch=master\n    :target: 
https://coveralls.io/r/litl/backoff?branch=master\n.. image:: 
https://img.shields.io/pypi/v/backoff.svg\n    :target: 
https://pypi.python.org/pypi/backoff\n\n**Function decoration for backoff and 
retry**\n\nThis module provides function decorators which can be used to wrap 
a\nfunction such that it will be retried until some condition is met. It\nis 
meant to be of use when accessing unreliable resources with the\npotential for 
intermittent failures i.e. network resources and external\nAPIs. Somewhat more 
generally, it may also be of use for dynamically\npolling resources for 
externally generated content.\n\nDecorators support both regular functions for 
synchronous code and\n`asyncio 
<https://docs.python.org/3/library/asyncio.html>`_\'s coroutines\nfor 
asynchronous code.\n\nExamples\n========\n\nSince Kenneth Reitz\'s `requests 
<http://python-requests.org>`_ module\nhas become a defacto standard for 
synchronous HTTP clients in Python,\nnetworking examples below are written 
using it, but it is in no way required\nby the backoff 
module.\n\[email protected]_exception\n---------------------\n\nThe ``on_exception`` 
decorator is used to retry when a specified exception\nis raised. Here\'s an 
example using exponential backoff when any\n``requests`` exception is 
raised:\n\n.. code-block:: python\n\n    @backoff.on_exception(backoff.expo,\n  
                        requests.exceptions.RequestException)\n    def 
get_url(url):\n        return requests.get(url)\n\nThe decorator will also 
accept a tuple of exceptions for cases where\nthe same backoff behavior is 
desired for more than one exception type:\n\n.. code-block:: python\n\n    
@backoff.on_exception(backoff.expo,\n                          
(requests.exceptions.Timeout,\n                           
requests.exceptions.ConnectionError))\n    def get_url(url):\n        return 
requests.get(url)\n\n**Give Up Conditions**\n\nOptional keyword arguments can 
specify conditions under which to give\nup.\n\nThe keyword argument 
``max_time`` specifies the maximum amount\nof total time in seconds that can 
elapse before giving up.\n\n.. code-block:: python\n\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.RequestException,\n                          max_time=60)\n 
   def get_url(url):\n        return requests.get(url)\n\n\nKeyword argument 
``max_tries`` specifies the maximum number of calls\nto make to the target 
function before giving up.\n\n.. code-block:: python\n\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.RequestException,\n                          max_tries=8,\n 
                         jitter=None)\n    def get_url(url):\n        return 
requests.get(url)\n\n\nIn some cases the raised exception instance itself may 
need to be\ninspected in order to determine if it is a retryable condition. 
The\n``giveup`` keyword arg can be used to specify a function which 
accepts\nthe exception and returns a truthy value if the exception should 
not\nbe retried:\n\n.. code-block:: python\n\n    def fatal_code(e):\n        
return 400 <= e.response.status_code < 500\n\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.RequestException,\n                          
max_time=300,\n                          giveup=fatal_code)\n    def 
get_url(url):\n        return requests.get(url)\n\nWhen a give up event occurs, 
the exception in question is reraised\nand so code calling an 
`on_exception`-decorated function may still\nneed to do exception 
handling.\n\[email protected]_predicate\n---------------------\n\nThe 
``on_predicate`` decorator is used to retry when a particular\ncondition is 
true of the return value of the target function.  This may\nbe useful when 
polling a resource for externally generated content.\n\nHere\'s an example 
which uses a fibonacci sequence backoff when the\nreturn value of the target 
function is the empty list:\n\n.. code-block:: python\n\n    
@backoff.on_predicate(backoff.fibo, lambda x: x == [], max_value=13)\n    def 
poll_for_messages(queue):\n        return queue.get()\n\nExtra keyword 
arguments are passed when initializing the\nwait generator, so the 
``max_value`` param above is passed as a keyword\narg when initializing the 
fibo generator.\n\nWhen not specified, the predicate param defaults to the 
falsey test,\nso the above can more concisely be written:\n\n.. code-block:: 
python\n\n    @backoff.on_predicate(backoff.fibo, max_value=13)\n    def 
poll_for_message(queue)\n        return queue.get()\n\nMore simply, a function 
which continues polling every second until it\ngets a non-falsey result could 
be defined like like this:\n\n.. code-block:: python\n\n    
@backoff.on_predicate(backoff.constant, interval=1)\n    def 
poll_for_message(queue)\n        return queue.get()\n\nJitter\n------\n\nA 
jitter algorithm can be supplied with the ``jitter`` keyword arg to\neither of 
the backoff decorators. This argument should be a function\naccepting the 
original unadulterated backoff value and returning it\'s\njittered 
counterpart.\n\nAs of version 1.2, the default jitter function 
``backoff.full_jitter``\nimplements the \'Full Jitter\' algorithm as defined in 
the AWS\nArchitecture Blog\'s `Exponential Backoff And 
Jitter\n<https://www.awsarchitectureblog.com/2015/03/backoff.html>`_ 
post.\nNote that with this algorithm, the time yielded by the wait 
generator\nis actually the *maximum* amount of time to wait.\n\nPrevious 
versions of backoff defaulted to adding some random number of\nmilliseconds (up 
to 1s) to the raw sleep value. If desired, this\nbehavior is now available as 
``backoff.random_jitter``.\n\nUsing multiple 
decorators\n-------------------------\n\nThe backoff decorators may also be 
combined to specify different\nbackoff behavior for different cases:\n\n.. 
code-block:: python\n\n    @backoff.on_predicate(backoff.fibo, max_value=13)\n  
  @backoff.on_exception(backoff.expo,\n                          
requests.exceptions.HTTPError,\n                          max_time=60)\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.Timeout,\n                          max_time=300)\n    def 
poll_for_message(queue):\n        return queue.get()\n\nRuntime 
Configuration\n---------------------\n\nThe decorator functions 
``on_exception`` and ``on_predicate`` are\ngenerally evaluated at import time. 
This is fine when the keyword args\nare passed as constant values, but suppose 
we want to consult a\ndictionary with configuration options that only become 
available at\nruntime. The relevant values are not available at import time. 
Instead,\ndecorator functions can be passed callables which are evaluated 
at\nruntime to obtain the value:\n\n.. code-block:: python\n\n    def 
lookup_max_time():\n        # pretend we have a global reference to \'app\' 
here\n        # and that it has a dictionary-like \'config\' property\n        
return app.config["BACKOFF_MAX_TIME"]\n\n    
@backoff.on_exception(backoff.expo,\n                          ValueError,\n    
                      max_time=lookup_max_time)\n\nEvent 
handlers\n--------------\n\nBoth backoff decorators optionally accept event 
handler functions\nusing the keyword arguments ``on_success``, ``on_backoff``, 
and ``on_giveup``.\nThis may be useful in reporting statistics or performing 
other custom\nlogging.\n\nHandlers must be callables with a unary signature 
accepting a dict\nargument. This dict contains the details of the invocation. 
Valid keys\ninclude:\n\n* *target*: reference to the function or method being 
invoked\n* *args*: positional arguments to func\n* *kwargs*: keyword arguments 
to func\n* *tries*: number of invocation tries so far\n* *elapsed*: elapsed 
time in seconds so far\n* *wait*: seconds to wait (``on_backoff`` handler 
only)\n* *value*: value triggering backoff (``on_predicate`` decorator 
only)\n\nA handler which prints the details of the backoff event could 
be\nimplemented like so:\n\n.. code-block:: python\n\n    def 
backoff_hdlr(details):\n        print ("Backing off {wait:0.1f} seconds afters 
{tries} tries "\n               "calling function {target} with args {args} and 
kwargs "\n               "{kwargs}".format(**details))\n\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.RequestException,\n                          
on_backoff=backoff_hdlr)\n    def get_url(url):\n        return 
requests.get(url)\n\n**Multiple handlers per event type**\n\nIn all cases, 
iterables of handler functions are also accepted, which\nare called in turn. 
For example, you might provide a simple list of\nhandler functions as the value 
of the ``on_backoff`` keyword arg:\n\n.. code-block:: python\n\n    
@backoff.on_exception(backoff.expo,\n                          
requests.exceptions.RequestException,\n                          
on_backoff=[backoff_hdlr1, backoff_hdlr2])\n    def get_url(url):\n        
return requests.get(url)\n\n**Getting exception info**\n\nIn the case of the 
``on_exception`` decorator, all ``on_backoff`` and\n``on_giveup`` handlers are 
called from within the except block for the\nexception being handled. Therefore 
exception info is available to the\nhandler functions via the python standard 
library, specifically\n``sys.exc_info()`` or the ``traceback`` 
module.\n\nAsynchronous code\n-----------------\n\nBackoff supports 
asynchronous execution in Python 3.5 and above.\n\nTo use backoff in 
asynchronous code based on\n`asyncio 
<https://docs.python.org/3/library/asyncio.html>`_\nyou simply need to apply 
``backoff.on_exception`` or ``backoff.on_predicate``\nto coroutines.\nYou can 
also use coroutines for the ``on_success``, ``on_backoff``, and\n``on_giveup`` 
event handlers, with the interface otherwise being identical.\n\nThe following 
examples use `aiohttp <https://aiohttp.readthedocs.io/>`_\nasynchronous HTTP 
client/server library.\n\n.. code-block:: python\n\n    
@backoff.on_exception(backoff.expo, aiohttp.ClientError, max_time=60)\n    
async def get_url(url):\n        async with aiohttp.ClientSession() as 
session:\n            async with session.get(url) as response:\n                
return await response.text()\n\nLogging 
configuration\n---------------------\n\nBy default, backoff and retry attempts 
are logged to the \'backoff\'\nlogger. By default, this logger is configured 
with a NullHandler, so\nthere will be nothing output unless you configure a 
handler.\nProgrammatically, this might be accomplished with something as 
simple\nas:\n\n.. code-block:: python\n\n    
logging.getLogger(\'backoff\').addHandler(logging.StreamHandler())\n\nThe 
default logging level is INFO, which corresponds to logging\nanytime a retry 
event occurs. If you would instead like to log\nonly when a giveup event 
occurs, set the logger level to ERROR.\n\n.. code-block:: python\n\n    
logging.getLogger(\'backoff\').setLevel(logging.ERROR)\n\nIt is also possible 
to specify an alternate logger with the ``logger``\nkeyword argument.  If a 
string value is specified the logger will be\nlooked up by name.\n\n.. 
code-block:: python\n\n   @backoff.on_exception(backoff.expo,\n                 
        requests.exception.RequestException,\n\t\t\t logger=\'my_logger\')\n   
# ...\n\nIt is also supported to specify a Logger (or LoggerAdapter) 
object\ndirectly.\n\n.. code-block:: python\n\n    my_logger = 
logging.getLogger(\'my_logger\')\n    my_handler = logging.StreamHandler()\n    
my_logger.add_handler(my_handler)\n    my_logger.setLevel(logging.ERROR)\n\n    
@backoff.on_exception(backoff.expo,\n                         
requests.exception.RequestException,\n\t\t\t logger=my_logger)\n    # 
...\n\nDefault logging can be disabled all together by 
specifying\n``logger=None``. In this case, if desired alternative logging 
behavior\ncould be defined by using custom event handlers.\n',
     'author': 'Bob Green',
     'author_email': '[email protected]',
     'url': 'https://github.com/litl/backoff',
     'packages': packages,
     'package_data': package_data,
-    'py_modules': modules,
-    'python_requires': '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
+    'python_requires': '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
 }
 
 


Reply via email to