Giter VIP home page Giter VIP logo

retrying's Introduction

Retrying

Retrying 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.

The simplest use case is retrying a flaky function whenever an Exception occurs until a value is returned.

import random
from retrying import retry

@retry
def do_something_unreliable():
    if random.randint(0, 10) > 1:
        raise IOError("Broken sauce, everything is hosed!!!111one")
    else:
        return "Awesome sauce!"

print do_something_unreliable()

Features

  • Generic Decorator API
  • Specify stop condition (i.e. limit by number of attempts)
  • Specify wait condition (i.e. exponential backoff sleeping between attempts)
  • Customize retrying on Exceptions
  • Customize retrying on expected returned result

Installation

To install retrying, simply:

$ pip install retrying

Or, if you absolutely must:

$ easy_install retrying

But, you might regret that later.

Examples

As you saw above, the default behavior is to retry forever without waiting.

@retry
def never_give_up_never_surrender():
    print "Retry forever ignoring Exceptions, don't wait between retries"

Let's be a little less persistent and set some boundaries, such as the number of attempts before giving up.

@retry(stop_max_attempt_number=7)
def stop_after_7_attempts():
    print "Stopping after 7 attempts"

We don't have all day, so let's set a boundary for how long we should be retrying stuff.

@retry(stop_max_delay=10000)
def stop_after_10_s():
    print "Stopping after 10 seconds"

Most things don't like to be polled as fast as possible, so let's just wait 2 seconds between retries.

@retry(wait_fixed=2000)
def wait_2_s():
    print "Wait 2 second between retries"

Some things perform best with a bit of randomness injected.

@retry(wait_random_min=1000, wait_random_max=2000)
def wait_random_1_to_2_s():
    print "Randomly wait 1 to 2 seconds between retries"

Then again, it's hard to beat exponential backoff when retrying distributed services and other remote endpoints.

@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000)
def wait_exponential_1000():
    print "Wait 2^x * 1000 milliseconds between each retry, up to 10 seconds, then 10 seconds afterwards"

We have a few options for dealing with retries that raise specific or general exceptions, as in the cases here.

def retry_if_io_error(exception):
    """Return True if we should retry (in this case when it's an IOError), False otherwise"""
    return isinstance(exception, IOError)

@retry(retry_on_exception=retry_if_io_error)
def might_io_error():
    print "Retry forever with no wait if an IOError occurs, raise any other errors"

@retry(retry_on_exception=retry_if_io_error, wrap_exception=True)
def only_raise_retry_error_when_not_io_error():
    print "Retry forever with no wait if an IOError occurs, raise any other errors wrapped in RetryError"

We can also use the result of the function to alter the behavior of retrying.

def retry_if_result_none(result):
    """Return True if we should retry (in this case when result is None), False otherwise"""
    return result is None

@retry(retry_on_result=retry_if_result_none)
def might_return_none():
    print "Retry forever ignoring Exceptions with no wait if return value is None"

Any combination of stop, wait, etc. is also supported to give you the freedom to mix and match.

Contribute

  1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
  2. Fork the repository on GitHub to start making your changes to the master branch (or branch off of it).
  3. Write a test which shows that the bug was fixed or that the feature works as expected.
  4. Send a pull request and bug the maintainer until it gets merged and published. :) Make sure to add yourself to AUTHORS.

retrying's People

Contributors

cyrusd avatar emonty avatar hguemar avatar jd avatar rholder avatar saulshanabrook avatar simondolle avatar svisser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

retrying's Issues

python 2.6 / AttributeError: 'module' object has no attribute 'wraps'

hi, does someone have a clue on this error ?
thanks

$ python -V
Python 2.6.6
$$ >>> six.version
'1.6.1'

$ python setup.py test
running test
running egg_info
writing requirements to retrying.egg-info/requires.txt
writing retrying.egg-info/PKG-INFO
writing top-level names to retrying.egg-info/top_level.txt
writing dependency_links to retrying.egg-info/dependency_links.txt
reading manifest file 'retrying.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'retrying.egg-info/SOURCES.txt'
running build_ext
Traceback (most recent call last):
File "setup.py", line 57, in
setup(**settings)
File "/usr/lib/python2.6/distutils/core.py", line 152, in setup
dist.run_commands()
File "/usr/lib/python2.6/distutils/dist.py", line 975, in run_commands
self.run_command(cmd)
File "/usr/lib/python2.6/distutils/dist.py", line 995, in run_command
cmd_obj.run()
File "/usr/lib/python2.6/dist-packages/setuptools/command/test.py", line 137, in run
self.with_project_on_sys_path(self.run_tests)
File "/usr/lib/python2.6/dist-packages/setuptools/command/test.py", line 117, in with_project_on_sys_path
func()
File "/usr/lib/python2.6/dist-packages/setuptools/command/test.py", line 146, in run_tests
testLoader = loader_class()
File "/usr/lib/python2.6/unittest.py", line 816, in init
self.parseArgs(argv)
File "/usr/lib/python2.6/unittest.py", line 843, in parseArgs
self.createTests()
File "/usr/lib/python2.6/unittest.py", line 849, in createTests
self.module)
File "/usr/lib/python2.6/unittest.py", line 613, in loadTestsFromNames
suites = [self.loadTestsFromName(name, module) for name in names]
File "/usr/lib/python2.6/unittest.py", line 576, in loadTestsFromName
module = import('.'.join(parts_copy))
File "/root/retrying-master/test_retrying.py", line 245, in
@Retry(wait_fixed=50, retry_on_result=retry_if_result_none)
File "/root/retrying-master/retrying.py", line 47, in wrap
@six.wraps(f)
AttributeError: 'module' object has no attribute 'wraps'

Should a "retry_on_result" not include a "retry_on_exception=never_retry_on_exception"?

As mentioned in #25, I hoped to have control over a retry, based on a function, which explicits output a print-statement.

A suspicious long run (in a detached process, which I couldn't debug/interupt easily), had sent me into the internal retrying logic.

With a print statement, after the "sleep" calculation, I was able to observe that it run out of my control into endless retries (with wait_exponential_multiplier).

                sleep = self.wait(attempt_number, delay_since_first_attempt_ms)

                # xxx pa 141117 debug wait
                print "RETRY: ", sleep, attempt_number, delay_since_first_attempt_ms

Reason was that my code had hit an exception, and the default logic is "always_reject" due to that part:

        if retry_on_exception is None:
            self._retry_on_exception = self.always_reject

which ended in endless retries:

RETRY:  2000 1 0
RETRY:  4000 2 2003
RETRY:  8000 3 6004
RETRY:  10000 4 14006
RETRY:  10000 5 24008
RETRY:  10000 6 34010
...

To stop endless loop, I had to override the "retry_on_exception"

    def never_retry_on_exception(response):
        """Return always False to raise on Exception (will not happen by default!)"""
        return False

    # and has to add it to my decorator
    retry429_decorator = retry(
        retry_on_result=retry_if_result_429, 
        wait_exponential_multiplier=1000, 
        wait_exponential_max=10000,
        retry_on_exception=never_retry_on_exception
        )

Summary:

  • for me it was a trap, because I thought to have control
  • is this intended by design?
  • was my approach the correct one?
  • If yes, worth to mention more explicit in the doc, that your solution trys by default to retry on tracebacks?

Any way to know which condition has caused to stop retrying..?

Hi there,

Having a function decorated with @retry and some combination of available options (e.g., retry_on_result, retry_on_exception and stop_max_delay), is there any way to tell the caller which one of them triggered the decision to stop retrying..? (i.e., did we stop retrying because we were getting some exception (e.g. ConnectionError) or because the result was not as expected?)

Raising a `RetryError` on failure.

Hi,
I just found your library and it looks to do exactly what I was looking for.
However when launching the code below, I am getting a RetryError.
Is is the intended behavior?

from retrying import retry, RetryError

@retry(wait_fixed=100,
       stop_max_attempt_number=10,
       wrap_exception=False)
def foo():
    raise ValueError()

try:
    foo()
except ValueError:
    print "ValueError"
except RetryError as e:
    print "RetryError"

Intuitively, I was expecting a ValueError. That would let me use the retry decorator without modifying the rest of the code.

Add support for coroutines

@retry(stop_max_attempt_number=7)
async def stop_after_7_attempts():
    print "Stopping after 7 attempts"

It would great to have this feature where it works for coroutines too.

specify time in decimal seconds

because python time.time() and time.sleep() have sub millisecond resolution (at least on linux which has ~microsecond-ish resoluiton), providing time in fractional seconds should be preferred to ms ... i would rather specify 1.000001s than 1000.001ms ...

but if backward compatibility is important, then at least support fractional milliseconds (up to 0.001ms resolution).

also this saves some multiplicaiton, division and rounding which is precious time if you need to retry in a high performance environment.

Do something / nothing when max retries run out.

I'm doing a broad except to catch everything and then not raising it. To make retrying work, I had to catch and raise the IOError specifically. But if the max retries run out, I don't wan't it to raise and fail. Is there a way to do this?

Skips the test entirely in pytest

Can this be used in pytest. When I use the decorator, it seems to skip the test entirely when I run the test suite. I am doing like
@retry(AssertionError, tries=10, delay=3, backoff=2) def test_something(data):

I am trying to make use of exponential back off

The blank except clause is unintuitive

Using a blank except: is unintuitive as it catches KeyBoardInterrupt exceptions too, this means if you try to ctrl+c the code it wont work (unless you do it enough times to hit a limit etc.)

This should be changed to except Exception: which will then catch the vast majority of exceptions that inherit from this. Otherwise you get all exceptions that inherit from BaseException which includes KeyboardInterrupt.

Alternatively it would be useful to add a parameter to retry on specific exceptions (and their subclasses).

@retry(on_exception=requests.exceptions.HTTPError)
@retry(on_exception=socket.timeout)
@retry(on_exception=BaseException)
etc. etc.

The added beifit here is that you state what you want to catch and don't accidentally supress other exceptions.

This change would however be slightly backwards incompatible. The alternative would be to remaind a default to BaseException but allow the user to change this.

1.2.0 decorator - AttributeError: 'Retrying' object has no attribute 'getattr'

Hi there,

I'm getting a AttributeError: 'Retrying' object has no attribute 'getattr' when the @retry decorator is being used in 1.2.0. I actually ran into this while building out the dependencies for another library I'm using (dynamic-dynamodb), so apologies in advance if I'm missing something obvious about the usage.

Here's a REPL session that roughly duplicates what that library was doing:

Python 2.7.5 (default, Sep 12 2013, 21:33:34)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from retrying import retry
>>> @retry(
...     wait='exponential_sleep',
...     wait_exponential_multiplier=1000,
...     wait_exponential_max=5000)
... def foo():
...     return 1
...
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Python/2.7/site-packages/retrying.py", line 89, in wrapped_f
    return Retrying(*dargs, **dkw).call(f, *args, **kw)
  File "/Library/Python/2.7/site-packages/retrying.py", line 154, in __init__
    self.wait = self.getattr(wait)
AttributeError: 'Retrying' object has no attribute 'getattr'

It seemed to work on 1.1.x before I rebuilt this morning and the lib pulled in 1.2.0, so I'm guessing it's something fairly recent.

Would love a 1.3.4 release

I'd like to download from PyPI and be able to use the after_attempts decorator kwarg.

Let me know if there's anything I can do to help!

Thanks for creating this project. It's exactly what I need.

Add support for wrap_func

If we run out of attempts, it'd be nice to have a final chance to inspect the result of the call before the final reraise or return are done. I think this could be done by having a wrap_func called passing in the attempt

Transfer ownership to tenacity

Thanks for this useful package and work over the years.

Given that your priorities now lie elsewhere, would you be open to transferring ownership of the PyPI package name to tenacity?

jd/tenacity#356

No work on your part and a compatibility shim will be added.

Wheel support for linux aarch64/x86

Summary
Installing retrying on aarch64/x86 via pip using command "pip3 install retrying" tries to build wheel from source code

Problem description
retrying doesn't have wheel for aarch64/x86 on PyPI repository. So, while installing retrying via pip on aarch64/x86 machine, pip builds the source code resulting in it takes more time to install retrying. Making wheel available for aarch64/x86 will benefit aarch64/x86 users by minimizing retrying installation time. We can release the wheel using CI/CD tools such as travis-ci, circle-ci, azure-pipelne etc..

Expected Output
Pip should be able to download retrying wheel from PyPI repository rather than building it from source code.

@retrying-taem, please let me know if I can help you building wheel/uploading to PyPI repository. I am curious to make retrying wheel available for aarch64. It will be a great opportunity for me to work with you.

Support retrying as context manager

Would be very helpful to support retrying as a context manager:

Something along the lines of:

def do_something_unreliable():
    if random.randint(0, 10) > 1:
        raise IOError("Broken sauce, everything is hosed!!!111one")
    else:
        return "Awesome sauce!"

with retry(wait_fixed=2000):
    do_something_unreliable()

@retry decorator changes method/function signatures

Using the retry decorator changes the signature of a method / signature.
As far as I know, this is a bad thing (see http://www.phyast.pitt.edu/~micheles/python/documentation.html#statement-of-the-problem ).

script:

#!/usr/bin/python
from retrying import retry
from inspect import getargspec

@retry
def test(a, b):
    pass

def test2(a, b):
    pass


print getargspec(test)
print getargspec(test2)

Output:

root@dd4797b24f12:~/ta# python test2.py 
ArgSpec(args=[], varargs='args', keywords='kw', defaults=None)
ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)

Better documentation

Hello, lovely package.

It seems that it has a lot of features that are not documented.

Would be nice to see a docstring of Retrying.__init__ or actual retry decorator.

In addition, examples are very good, but also do not cover complete functionality.

Thanks for considering.

Logging support

It would be nice to add logging info/debug statements to show exactly what is being retried, when, etc.

Method retry

I want to decorate methods of a class with @Retry and use a specific method as the "retry_on_exception" function. Issue is of course, that you can not do

@retry(retry_on_exception=self.retry_handler)

since self is not defined in that case. This code snippet is an attempt to work around this:

def method_retry(*dargs, **dkw):
    def decorator_retry(func):
        @functools.wraps(func)
        def retry_func(self, *args, **kwargs):
            fixed_dkw = dkw.copy()
            if retry_on_ex := fixed_dkw.get("retry_on_exception"):
                fixed_dkw["retry_on_exception"] = lambda ex: retry_on_ex(self, ex)
            
            if retry_on_res := fixed_dkw.get("wait_on_result"):
                fixed_dkw["retry_on_result"] = lambda res: retry_on_res(self, res)

            return Retrying(*dargs, **fixed_dkw).call(func, self, *args, **kwargs)
        return retry_func
    return decorator_retry

*dargs would have to be modified similarly to kwargs. There might be an even more elegant solution though. But this is the best I could come up with so far.

This seems to work, although you can not do

class MyClass:
    def my_exception_handler(self):
        pass

    @method_retry(retry_on_exception=MyClass.my_exception_handler)
    def my_method(self):
        pass

since MyClass is not defined at that point yet.

so you have to do

def my_exception_handler(self):
     pass

class MyClass:
    @method_retry(retry_on_exception=my_exception_handler)
    def my_method(self):
        pass

which is quite annoying.

Would be cool if anyone had a better idea.

Just depend on six

Instead of copying six functions into retrying codebase why not just require the six module itself? This was if six updates then you automatically get this update as well...

retrying

using the retrying package. How do I use it for retrying, and if the retries ends without a successful match, the code block leaves?

import random
from retrying import retry

@retry(wait_fixed=500, stop_max_delay=5000 )
def do_something_unreliable():
    result = random.randint(0, 10)
    print result
    if result != 11:
        raise IOError("Broken")
    else:
        return True

print do_something_unreliable()

I want the the raise IOError to be replaced with an option of returning, say, False

In other words, I want to use this decorator, in case of actual values is different than expected, while the actual is created frequently from other function

Access to retry_number from decorated method?

I'd like to log the retry attempt_number in the wrapped/decorated method.
Is there any provision to access this from the method being retried?

eg:

@retry(retry_on_exception=retryable_write_exceptions, wrap_exception=True,
       wait_exponential_multiplier=10000, wait_exponential_max=600000)
def retry_read(flakey_method):
    try:
        retval = flakey_method()
    except Exception as e:
        logger.error('Retry number: {}'.format(**retry_wrappers_attempt_number**))
    return retval

retry_on_no_exception

I am using retrying for integration testing of networking code.

Quite frequently I have to retry on a condition n times within m seconds, where the condition may not fail a single time within that time frame.

Thus, it would helpful to have a "retry_on_no_exception" option similar to the "retry_on_exception" option.

The expected behavior of the "retry_on_no_exception" option is to ...

  • ... retry if no exception occurs.
  • ... stop retrying and raising whichever exception has occurred, if an exception occurred.

Add type hints

I use mypy and want to have type hints for retrying to fix this error:

error: Skipping analyzing "retrying": module is installed, but missing library stubs or py.typed marker  [import]
note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports

Current non-optimal solution is to ignore by adding the following lines to the mypy.ini config.

[mypy-retrying.*]
ignore_missing_imports = True

Creating a new release from master

Hey guys, could you please create a new release (1.3.4?) from master? I really need the latests commits that are found in master.

Thanks in advance :)

How to reset an exponential_sleep configuration, after a successfull_threshold again?

Great lib, which saved me definitive from an ugly hack to make "requests" calls retrying on the status_code :)

    def retry_if_result_429(response):
        """Return True if we should retry (in this case when the status_code is 429), False otherwise"""
        # DEBUG to see this in action
        if response.status_code == 429:
            print 'RETRY 429: %s' % response.url
            return True
        else:
            return False

    #
    # functools partial to the help
    # to inject auth parameter in the get/delete/post/put requests
    #
    retry429_decorator = retry(
        retry_on_result=retry_if_result_429, 
        wait_exponential_multiplier=1000, 
        wait_exponential_max=10000
        )

    #1. curry the authentication
    #2. decorate it with the retry logic
    s.get    = retry429_decorator(partial(s.get,    auth=credentials))
    s.put    = retry429_decorator(partial(s.put,    auth=credentials))
    s.post   = retry429_decorator(partial(s.post,   auth=credentials))
    s.delete = retry429_decorator(partial(s.delete, auth=credentials))

But running a huge test, I have the doubt now, that one of my batches had run into the "wait_exponential_max" and that this will not be reset.

Will the wait_function applied to every subsequent call?
Or will the delay happen only when it run into a retry again?

Any idea how to achieve a reset?
Resetting the "attempt_number" for example?

thx for any hint or clarification, when the delay happens

Modify input between retries?

Hello,

I have a list of items that should be pushed to a stream.
Every push command, which is a batch push command, may accept a strict subset of the items and reject the rest.

In the response, it will let me know which items were rejected, so I would like to apply the retry mechanism on this function as long as there are items that failed to be pushed.
But!, I do not want accepted items to be pushed again, so I need to modify the input of the function between calls.

How can this be done?
Thanks

stop_max_delay doesn't work as expected

I am not sure how stop_max_delay is intended to work, but I would expect it would stop retry after have been retrying more than the given time with that parameter. However, actually it works very differently: it just disable retry if the script has been run for more than the given time. This can be easily reproduced with this script:

import time                                                                                                                                                                     
import sys 
from retrying import retry

def retry_on_exception(exception):
    print 'Retrying....'
    return True


@retry(retry_on_exception=retry_on_exception, stop_max_delay=10000, wait_fixed=1000)
def test(sleep):
    time.sleep(sleep)
    assert False


if __name__ == '__main__':
    test(int(sys.argv[1]))

if I run

python test.py 0

you will get 10 retries, one per second, as expected. In this case, the exception is raised as soon as the script starts, that is why the problem is not seen. However, if you run

python test.py 12

(so exception will be raised 12 seconds after the script started), you won't get any retry.

Use with existing exception handling?

I've read through the retrying README, and I'm still a bit confused about how to use this with my existing exception handling code.

For example, here is the current code:

@retry(stop_max_attempt_number=5, wait_exponential_multiplier=1000, wait_exponential_max=10000)
def write_points(logger, client, json_points, line_number):
    # TODO - I originally wrote this to reduce code duplication - however, we need a better way to handle all the parameters
    try:
        client.write_points(json_points)
        logger.info("Wrote in {} points to InfluxDB. Processed up to line {}.".format(len(json_points), line_number))
    except RequestException as e:
        logger.error("Unable to connect to InfluxDB at {} - {}".format(client._host, e))
    except InfluxDBClientError as e:
        logger.error('Unable to write to InfluxDB - {}'.format(e))
    except SSLError as e:
        logger.error('SSL error - {}'.format(e))

However, the @retry() decorator here seems to have no effect.

It's only if I remove all the try/except blocks that it does anything:

@retry(stop_max_attempt_number=5, wait_exponential_multiplier=1000, wait_exponential_max=10000)
def write_points(logger, client, json_points, line_number):
    # TODO - I originally wrote this to reduce code duplication - however, we need a better way to handle all the parameters
    client.write_points(json_points)
    logger.info("Wrote in {} points to InfluxDB. Processed up to line {}.".format(len(json_points), line_number))

Should I be re-throwing the exception again in my own code? Or is there a better way to use retrying, and still get say, nice error messages for different exception types?

Override retry limits with decorated function's parameter

I would like to allow for overriding the decorator's kwargs while calling the decorated function. A simplified example use case is:

@retry
def request(url):
      return "TADA"

request("someurl", retry_options=dict(stop_max_attempt_number=3))

I can send a pull request if the idea is acceptable. Thanks!

python 2.7 & OS X / AttributeError: 'module' object has no attribute 'wraps'

I have a weird question. It don't work at Mac OS X, but it can work at linux.
My Macbook envs:

$ python -V
Python 2.7.6

retrying (1.3.3)
six (1.9.0)

Error:

AttributeError at /
'module' object has no attribute 'wraps'
Request Method: GET
Request URL:    http://127.0.0.1:8080/
Django Version: 1.5.5
Exception Type: AttributeError
Exception Value:    
'module' object has no attribute 'wraps'
Exception Location: /Library/Python/2.7/site-packages/retrying.py in wrap, line 47
Python Executable:  /usr/bin/python
Python Version: 2.7.6
Python Path:    
['/Users/yangxufeng.zhao/workspace/work/xnetweb',
 '/Library/Python/2.7/site-packages/requests-2.2.0-py2.7.egg',
 '/Library/Python/2.7/site-packages/paramiko-1.14.0-py2.7.egg',
 '/Library/Python/2.7/site-packages/ecdsa-0.11-py2.7.egg',
 '/Library/Python/2.7/site-packages/pycrypto-2.6.1-py2.7-macosx-10.9-intel.egg',
 '/Library/Python/2.7/site-packages/setuptools-5.4.1-py2.7.egg',
 '/Library/Python/2.7/site-packages/json2xml-0.6-py2.7.egg',
 '/Library/Python/2.7/site-packages/Routes-2.0-py2.7.egg',
 '/Library/Python/2.7/site-packages/repoze.lru-0.6-py2.7.egg',
 '/Library/Python/2.7/site-packages/pip-1.5.6-py2.7.egg',
 '/Library/Python/2.7/site-packages/oss-0.1.3-py2.7.egg',
 '/Users/yangxufeng.zhao/workspace/work/arch_define',
 '/Users/yangxufeng.zhao/workspace/work/xnetweb',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC',
 '/Library/Python/2.7/site-packages']

Unable to use llibrary on MAC OS X

I installed your library with

pip install retrying

I am able to see the following message

You are using pip version 6.0.8, however version 7.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Requirement already satisfied (use --upgrade to upgrade): retrying in /usr/local/lib/python2.7/site-packages
Requirement already satisfied (use --upgrade to upgrade): six>=1.7.0 in /usr/local/lib/python2.7/site-packages (from retrying)

But while importing a library, it gives import error

ImportError: No module named retrying

None decorator-like usage of retrying

The documentation focuses on using the retry call as a decorator. Does it mean that the internal Retrying interface is bound to change? If not, please state that in the docs and maybe give an example usage.

In some cases I would like to use retrying like below, but am afraid the interface may change.

retry_call = Retrying(stop_max_attempt_number=self.retry_count, wait_fixed=self.retry_sleep)
retry_call.call(self._remote_call)

retrying with generators

Will this work with a generator, and would it be possible to resume retrying from the failed state in a generator, not from the beginning?

@retry decorator seems to have no effect

Hullo,

On CentOS 7 (python 2.7.5) I'm trying to validate a trivial script, and the @Retry decorator seems to be completely ignored:

import sys
import os
from retrying import retry

@retry
def do_something_unreliable():
    print sys.argv[1]
    if os.system(sys.argv[1]):
        return "fail"
    else:
        return "Awesome sauce!"

print do_something_unreliable()

Transcript showing that there is no competition for the name retry

[root@jenkins ~]# python /usr/local/bin/retry.py false
Traceback (most recent call last):
  File "/usr/local/bin/retry.py", line 3, in <module>
    from retrying import retry
ImportError: No module named retrying
[root@jenkins ~]# pip install retrying
Collecting retrying
  Using cached retrying-1.3.3.tar.gz
Requirement already satisfied (use --upgrade to upgrade): six>=1.7.0 in /usr/lib/python2.7/site-packages (from retrying)
Installing collected packages: retrying
  Running setup.py install for retrying
Successfully installed retrying-1.3.3
[root@jenkins ~]# python /usr/local/bin/retry.py false
false
fail

I was expecting to see false\nfail\n shooting up the screen, but the @retry appears to simply not happen :/ Any advice would be warmly welcomed!

Cheers,
Gavin.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.