# KaioRetry
[![PyPI version](https://img.shields.io/pypi/v/kaioretry?logo=pypi&style=plastic)](https://pypi.python.org/pypi/kaioretry/)
[![Supported Python Version](https://img.shields.io/pypi/pyversions/kaioretry?logo=python&style=plastic)](https://pypi.python.org/pypi/kaioretry/)
[![License](https://img.shields.io/pypi/l/kaioretry?color=green&logo=GNU&style=plastic)](https://github.com/Anvil/kaioretry/blob/main/LICENSE)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/kaioretry?color=magenta&style=plastic)](https://pypistats.org/packages/kaioretry)
[![Pylint Static Quality Github Action](https://github.com/Anvil/kaioretry/actions/workflows/pylint.yml/badge.svg)](https://github.com/Anvil/kaioretry/actions/workflows/pylint.yml)
[![Mypy Static Quality Github Action](https://github.com/Anvil/kaioretry/actions/workflows/mypy.yml/badge.svg)](https://github.com/Anvil/kaioretry/actions/workflows/mypy.yml)
[![Pylint Static Quality Github Action](https://github.com/Anvil/kaioretry/actions/workflows/python-app.yml/badge.svg)](https://github.com/Anvil/kaioretry/actions/workflows/python-app.yml)
[![Documentation Status](https://readthedocs.org/projects/kaioretry/badge/?version=latest)](https://kaioretry.readthedocs.io/en/latest/?badge=latest)
KaioRetry is (yet another) retry decorator implementation, which is
clearly inspired by the original
[retry](https://pypi.org/project/retry) module and is actually
backward compatible with it.
# Basic usage
Transparently perform retries on failures:
```python
from kaioretry import retry, aioretry
@retry(exceptions=ValueError, tries=2)
def some_func(...):
...
@aioretry(exceptions=(ValueError, SomeOtherError), tries=-1, delay=1)
async def some_coroutine(...):
...
```
# Documentation
If you care to read more, a more lengthy documentation is available on
[readthedocs](https://kaioretry.readthedocs.io/en/latest/).
# Known Issues
## Pylint
[Pylint](https://pylint.readthedocs.io/en/latest/), it seems, is not [really
good a detecting decorators that change function
signatures](https://github.com/pylint-dev/pylint/issues/3108), and kaioretry
defines and uses a lot of decorators (relatively speaking).
This means that such basic code:
```python
from kaioretry import aioretry
@aioretry(exceptions=ZeroDivisionError)
async def func(x, y):
return x / y
```
Will trigger the following pylint errors:
```
E1120: No value for argument 'retry_obj' in function call (no-value-for-parameter)
```
According to pylint documentation, the only way to widely work around this
issue is to use the
[`signature-mutators`](https://pylint.pycqa.org/en/latest/user_guide/configuration/all-options.html#signature-mutators)
feature of pylint. This can be done either on the command line:
```
pylint --signature-mutators=kaioretry._make_decorator
```
Or through pylint configuration file:
```ini
# The TYPECHECK section accepts a signature-mutators directive.
[TYPECHECK]
# List of decorators that change the signature of a decorated function.
signature-mutators=kaioretry._make_decorator
```
(Of course, you can inline a `# pylint: disable=no-value-for-parameter`
comment on all `aioretry()` and `retry()` call lines, and it can be good
enough to disable a one-time warning, but repeating that line can be
tedious. The `signature-mutators` directive will globally disable the
signature-checking for `aioretry()` and `retry()` calls, so this can be easier
depending of your own usage of kaioretry.)
## Mypy and functions generated by kaioretry.aioretry
[Mypy](https://github.com/python/mypy) may incorrectly infer the type of an
aioretry-decorated function as `def (*Any, **Any) -> Any` *if* the original
function:
1. is a coroutine _and_
2. has a returned type hinted as `Any` and/or if parameters are hinted as `Any`.
If the original function is fully annotated as non-`Any`, the resulting
decorated function annotations should be correctly inferred (according to
[kaioretry test](/Anvil/kaioretry/main/test/static_analysis)).
It is unclear to me right now, if the `kaioretry.aioretry` function type hints
are incorrect or if it is an issue with either mypy or cpython. Or both. Or
all 3. Go figure.
Any information on that matter would be greatly appreciated. I've spent weeks
trying to track down this issue. And while walking down this path has allowed
me to fix some other (rather unrelated) type-hinting boo-boos from my part,
this very specific issue is still puzzling me.
# Feedback welcome.
Always.
Raw data
{
"_id": null,
"home_page": "https://github.com/Anvil/kaioretry/",
"name": "kaioretry",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.10,<4.0",
"maintainer_email": "",
"keywords": "retry,decorator,asyncio",
"author": "Damien Nad\u00e9",
"author_email": "anvil.github+kaioretry@livna.org",
"download_url": "https://files.pythonhosted.org/packages/e3/82/411c90b90dbf0030d9c7118c61526a8ce248357ec29a23fe1e56ec928593/kaioretry-1.0.0.tar.gz",
"platform": null,
"description": "# KaioRetry\n\n[![PyPI version](https://img.shields.io/pypi/v/kaioretry?logo=pypi&style=plastic)](https://pypi.python.org/pypi/kaioretry/)\n[![Supported Python Version](https://img.shields.io/pypi/pyversions/kaioretry?logo=python&style=plastic)](https://pypi.python.org/pypi/kaioretry/)\n[![License](https://img.shields.io/pypi/l/kaioretry?color=green&logo=GNU&style=plastic)](https://github.com/Anvil/kaioretry/blob/main/LICENSE)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/kaioretry?color=magenta&style=plastic)](https://pypistats.org/packages/kaioretry)\n\n[![Pylint Static Quality Github Action](https://github.com/Anvil/kaioretry/actions/workflows/pylint.yml/badge.svg)](https://github.com/Anvil/kaioretry/actions/workflows/pylint.yml)\n[![Mypy Static Quality Github Action](https://github.com/Anvil/kaioretry/actions/workflows/mypy.yml/badge.svg)](https://github.com/Anvil/kaioretry/actions/workflows/mypy.yml)\n[![Pylint Static Quality Github Action](https://github.com/Anvil/kaioretry/actions/workflows/python-app.yml/badge.svg)](https://github.com/Anvil/kaioretry/actions/workflows/python-app.yml)\n[![Documentation Status](https://readthedocs.org/projects/kaioretry/badge/?version=latest)](https://kaioretry.readthedocs.io/en/latest/?badge=latest)\n\n\nKaioRetry is (yet another) retry decorator implementation, which is\nclearly inspired by the original\n[retry](https://pypi.org/project/retry) module and is actually\nbackward compatible with it.\n\n# Basic usage\n\nTransparently perform retries on failures:\n\n```python\n\nfrom kaioretry import retry, aioretry\n\n\n@retry(exceptions=ValueError, tries=2)\ndef some_func(...):\n ...\n\n\n@aioretry(exceptions=(ValueError, SomeOtherError), tries=-1, delay=1)\nasync def some_coroutine(...):\n ...\n\n```\n\n# Documentation\n\nIf you care to read more, a more lengthy documentation is available on\n[readthedocs](https://kaioretry.readthedocs.io/en/latest/).\n\n\n# Known Issues\n\n## Pylint\n\n[Pylint](https://pylint.readthedocs.io/en/latest/), it seems, is not [really\ngood a detecting decorators that change function\nsignatures](https://github.com/pylint-dev/pylint/issues/3108), and kaioretry\ndefines and uses a lot of decorators (relatively speaking).\n\nThis means that such basic code:\n\n```python\nfrom kaioretry import aioretry\n\n@aioretry(exceptions=ZeroDivisionError)\nasync def func(x, y):\n return x / y\n```\n\nWill trigger the following pylint errors:\n\n```\nE1120: No value for argument 'retry_obj' in function call (no-value-for-parameter)\n```\n\nAccording to pylint documentation, the only way to widely work around this\nissue is to use the\n[`signature-mutators`](https://pylint.pycqa.org/en/latest/user_guide/configuration/all-options.html#signature-mutators)\nfeature of pylint. This can be done either on the command line:\n\n```\npylint --signature-mutators=kaioretry._make_decorator\n```\n\nOr through pylint configuration file:\n\n```ini\n# The TYPECHECK section accepts a signature-mutators directive.\n[TYPECHECK]\n\n# List of decorators that change the signature of a decorated function.\nsignature-mutators=kaioretry._make_decorator\n```\n\n(Of course, you can inline a `# pylint: disable=no-value-for-parameter`\ncomment on all `aioretry()` and `retry()` call lines, and it can be good\nenough to disable a one-time warning, but repeating that line can be\ntedious. The `signature-mutators` directive will globally disable the\nsignature-checking for `aioretry()` and `retry()` calls, so this can be easier\ndepending of your own usage of kaioretry.)\n\n## Mypy and functions generated by kaioretry.aioretry\n\n[Mypy](https://github.com/python/mypy) may incorrectly infer the type of an\naioretry-decorated function as `def (*Any, **Any) -> Any` *if* the original\nfunction:\n\n1. is a coroutine _and_\n2. has a returned type hinted as `Any` and/or if parameters are hinted as `Any`.\n\nIf the original function is fully annotated as non-`Any`, the resulting\ndecorated function annotations should be correctly inferred (according to\n[kaioretry test](/Anvil/kaioretry/main/test/static_analysis)).\n\nIt is unclear to me right now, if the `kaioretry.aioretry` function type hints\nare incorrect or if it is an issue with either mypy or cpython. Or both. Or\nall 3. Go figure.\n\nAny information on that matter would be greatly appreciated. I've spent weeks\ntrying to track down this issue. And while walking down this path has allowed\nme to fix some other (rather unrelated) type-hinting boo-boos from my part,\nthis very specific issue is still puzzling me.\n\n# Feedback welcome.\n\nAlways.\n",
"bugtrack_url": null,
"license": "LGPL-2.1-or-later",
"summary": "All in one retry and aioretry decorators",
"version": "1.0.0",
"project_urls": {
"Documentation": "https://kaioretry.readthedocs.io/en/latest/",
"Homepage": "https://github.com/Anvil/kaioretry/",
"Repository": "https://github.com/Anvil/kaioretry/"
},
"split_keywords": [
"retry",
"decorator",
"asyncio"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "f3da5eb64891c671e41e6a58e104bf3c7aa82d68687828d0ab5198b4c42318bd",
"md5": "460206c5acb10f20215c7ffc90f24c71",
"sha256": "79ac78a20153bc4bec0ee34241032057cf99170ea1417ab6fe450ec25279c73f"
},
"downloads": -1,
"filename": "kaioretry-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "460206c5acb10f20215c7ffc90f24c71",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10,<4.0",
"size": 22172,
"upload_time": "2023-12-16T12:25:53",
"upload_time_iso_8601": "2023-12-16T12:25:53.984140Z",
"url": "https://files.pythonhosted.org/packages/f3/da/5eb64891c671e41e6a58e104bf3c7aa82d68687828d0ab5198b4c42318bd/kaioretry-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "e382411c90b90dbf0030d9c7118c61526a8ce248357ec29a23fe1e56ec928593",
"md5": "bbdf7b304ec5d222769642a810614ca7",
"sha256": "1800487c5bc0868e4040012fbe8c4c76ab24a0decaa82bad9875262df43617ed"
},
"downloads": -1,
"filename": "kaioretry-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "bbdf7b304ec5d222769642a810614ca7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10,<4.0",
"size": 21210,
"upload_time": "2023-12-16T12:25:55",
"upload_time_iso_8601": "2023-12-16T12:25:55.968227Z",
"url": "https://files.pythonhosted.org/packages/e3/82/411c90b90dbf0030d9c7118c61526a8ce248357ec29a23fe1e56ec928593/kaioretry-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-12-16 12:25:55",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Anvil",
"github_project": "kaioretry",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "kaioretry"
}