{"id":695,"library":"retry","title":"Easy to use retry decorator","description":"The `retry` library (version 0.9.2) provides a simple decorator for adding retry logic to Python functions. It allows configuration of exceptions to catch, number of attempts, delay between retries, backoff strategy, and optional jitter. This library is largely unmaintained, with its last release in 2016, and is superseded by more actively developed alternatives like `tenacity`.","status":"abandoned","version":"0.9.2","language":"python","source_language":"en","source_url":"https://github.com/invl/retry","tags":["retry","decorator","error handling","resilience","backoff"],"install":[{"cmd":"pip install retry","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Used to optionally preserve function signatures when decorating, not strictly required for core functionality.","package":"decorator","optional":true}],"imports":[{"note":"The 'retrying' library is a different, also unmaintained, project that `tenacity` forked from. This `retry` library has a distinct import path.","wrong":"from retrying import retry","symbol":"retry","correct":"from retry import retry"}],"quickstart":{"code":"import random\nfrom retry import retry\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\n\n@retry(exceptions=(IOError, ValueError), tries=3, delay=2, backoff=2, max_delay=10)\ndef unreliable_function():\n    if random.randint(0, 5) > 2:\n        raise IOError(\"Simulated network error\")\n    elif random.randint(0, 5) < 1:\n        raise ValueError(\"Simulated data error\")\n    else:\n        print(\"Function succeeded!\")\n        return \"Success\"\n\ntry:\n    result = unreliable_function()\n    print(f\"Final result: {result}\")\nexcept (IOError, ValueError) as e:\n    print(f\"Function failed after all retries: {e}\")","lang":"python","description":"This quickstart demonstrates how to apply the `@retry` decorator to a function, configuring it to retry on specific exceptions, with a maximum number of attempts, an initial delay, exponential backoff, and a maximum delay between retries. It will print logging messages for each retry attempt."},"warnings":[{"fix":"Consider migrating to `tenacity` (pip install tenacity) for active development, better features, and bug fixes. Tenacity offers a more robust and flexible API for retry strategies.","message":"This 'retry' library (invl/retry) is largely unmaintained, with its last release in 2016. Its API is not compatible with 'tenacity', which is the actively maintained successor to the 'retrying' library (another distinct, unmaintained project).","severity":"breaking","affected_versions":"<=0.9.2"},{"fix":"Always set a finite `tries` value (e.g., `tries=5`) or a `max_delay` to prevent infinite loops in production environments.","message":"By default, the `@retry` decorator will retry indefinitely if the `tries` parameter is not explicitly set or set to -1.","severity":"gotcha","affected_versions":"<=0.9.2"},{"fix":"For asynchronous code, you will need to use a different retry library that explicitly supports `async/await`, such as `tenacity` with `AsyncRetrying` or `stamina`.","message":"The `retry` decorator does not inherently support asynchronous functions (async/await syntax).","severity":"gotcha","affected_versions":"<=0.9.2"},{"fix":"Be aware of the type of `jitter` parameter passed. For true random jitter to prevent 'thundering herd' problems, provide a tuple (e.g., `jitter=(0, 1)`).","message":"When using `jitter`, if a tuple `(min, max)` is provided, the extra delay is chosen randomly. If a single number is provided, the jitter is fixed.","severity":"gotcha","affected_versions":"<=0.9.2"}],"env_vars":null,"last_verified":"2026-05-12T17:54:58.533Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Run 'pip install retry' in your terminal.","cause":"The 'retry' library has not been installed in your Python environment.","error":"ModuleNotFoundError: No module named 'retry'"},{"fix":"Always use parentheses when providing arguments to the decorator, even if empty: `@retry(tries=3)` instead of `@retry(tries=3)`.","cause":"The `@retry` decorator was called with arguments but without the necessary parentheses for the decorator factory, causing it to be interpreted as if it's decorating a function directly.","error":"TypeError: retry() missing 1 required positional argument: 'f'"},{"fix":"If you `import retry`, use `@retry(...)` or `retry(func, ...)`. If you `from retry import retry`, then use `@retry(...)` or `retry(func, ...)`.","cause":"After `import retry`, the user attempted to access `retry.retry`. The `retry` module itself is the decorator function, so you should use `retry` directly.","error":"AttributeError: module 'retry' has no attribute 'retry'"},{"fix":"Replace unsupported arguments like 'wait' with the correct argument 'delay' (e.g., `@retry(delay=2)` instead of `@retry(wait=2)`).","cause":"The 'retry' library does not recognize the keyword argument 'wait' (commonly used in other retry libraries like 'tenacity'). It expects 'delay' for the wait time.","error":"TypeError: retry() got an unexpected keyword argument 'wait'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":"0.9.2","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.6,"disk_size":"18.8M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.6,"disk_size":"18.8M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.6,"import_time_s":0.02,"mem_mb":1.6,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.6,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":1.9,"disk_size":"20.8M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":1.9,"disk_size":"20.8M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.8,"import_time_s":0.05,"mem_mb":1.9,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.05,"mem_mb":1.9,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":1.7,"disk_size":"12.6M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":1.7,"disk_size":"12.6M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.7,"import_time_s":0.06,"mem_mb":1.7,"disk_size":"13M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":1.7,"disk_size":"13M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":2.5,"disk_size":"12.4M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":2.1,"disk_size":"12.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.6,"import_time_s":0.06,"mem_mb":2.4,"disk_size":"13M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":1.9,"disk_size":"13M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.6,"disk_size":"18.3M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.6,"disk_size":"18.3M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.9,"import_time_s":0.02,"mem_mb":1.6,"disk_size":"19M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.6,"disk_size":"19M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}