Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ jobs:
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
- name: Install tox
run: uv tool install --with tox-uv tox
- name: Type checks
run: tox -e typing
- name: Lint code
run: tox -e lint

Expand All @@ -83,6 +81,10 @@ jobs:
with:
persist-credentials: false
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
- name: Type checks
env:
TOXENV: typing-${{ matrix.python-version }}
run: uvx --with tox-uv tox
- name: Run tests
env:
TOXENV: ${{ matrix.python-version }}
Expand Down
3 changes: 1 addition & 2 deletions backoff/_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ async def _call_handlers(
"kwargs": kwargs,
"tries": tries,
"elapsed": elapsed,
**extra,
}
# pyrefly: ignore [no-matching-overload]
details.update(extra)
for handler in handlers:
await handler(details)

Expand Down
24 changes: 8 additions & 16 deletions backoff/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from backoff._typing import (
ContextDetails,
Details,
_AnyLogger,
_AnyLoggerOrName,
_ContextHandler,
_Jitterer,
_MaybeCallable,
Expand Down Expand Up @@ -166,9 +168,7 @@ def _dispatch_handlers(handlers: Iterable[_ContextHandler], **details: Any) -> N
hdlr(details) # type: ignore[arg-type] # ty:ignore[invalid-argument-type]


def _prepare_logger(
logger: str | logging.Logger | logging.LoggerAdapter | None,
) -> logging.Logger | logging.LoggerAdapter | None:
def _prepare_logger(logger: _AnyLoggerOrName | None) -> _AnyLogger | None:
if isinstance(logger, str):
logger = logging.getLogger(logger)
return logger
Expand All @@ -180,7 +180,7 @@ def _config_handlers(
user_handlers: _HandlerT | Iterable[_HandlerT] | None,
*,
default_handler: Callable[..., None] | None = None,
logger: logging.Logger | logging.LoggerAdapter | None = None,
logger: _AnyLogger | None = None,
log_level: int | None = None,
) -> list[_HandlerT]:
handlers: list[_HandlerT] = []
Expand Down Expand Up @@ -213,11 +213,7 @@ def _config_handlers(


# Default backoff handler
def _log_backoff(
details: Details,
logger: logging.Logger | logging.LoggerAdapter,
log_level: int,
) -> None:
def _log_backoff(details: Details, logger: _AnyLogger, log_level: int) -> None:
msg = "Backing off %s(...) for %.1fs (%s)"
log_args = [details["target"].__name__, details["wait"]] # ty:ignore[unresolved-attribute]

Expand All @@ -231,11 +227,7 @@ def _log_backoff(


# Default giveup handler
def _log_giveup(
details: Details,
logger: logging.Logger | logging.LoggerAdapter,
log_level: int,
) -> None:
def _log_giveup(details: Details, logger: _AnyLogger, log_level: int) -> None:
msg = "Giving up %s(...) after %d tries (%s)"
log_args = [details["target"].__name__, details["tries"]] # ty:ignore[unresolved-attribute]

Expand All @@ -254,7 +246,7 @@ def _log_giveup(
# directly since it's no longer the active exception by this point).
def _log_backoff_context(
details: ContextDetails,
logger: logging.Logger | logging.LoggerAdapter,
logger: _AnyLogger,
log_level: int,
) -> None:
logger.log(
Expand All @@ -268,7 +260,7 @@ def _log_backoff_context(
# Default giveup handler for retry_context/aretry_context.
def _log_giveup_context(
details: ContextDetails,
logger: logging.Logger | logging.LoggerAdapter,
logger: logging.Logger | logging.LoggerAdapter[Any],
log_level: int,
) -> None:
logger.log(
Expand Down
10 changes: 5 additions & 5 deletions backoff/_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@

from backoff._common import _Attempt
from backoff._typing import (
_AnyLoggerOrName,
_CallableT,
_ContextHandler,
_Handler,
_Jitterer,
_MaybeCallable,
_MaybeLogger,
_MaybeTuple,
_Predicate,
_WaitGenerator,
Expand All @@ -45,7 +45,7 @@ def on_predicate(
on_success: _Handler | Iterable[_Handler] | None = None,
on_backoff: _Handler | Iterable[_Handler] | None = None,
on_giveup: _Handler | Iterable[_Handler] | None = None,
logger: _MaybeLogger = "backoff",
logger: _AnyLoggerOrName | None = "backoff",
backoff_log_level: int = logging.INFO,
giveup_log_level: int = logging.ERROR,
**wait_gen_kwargs: Any,
Expand Down Expand Up @@ -168,7 +168,7 @@ def on_exception(
on_backoff: _Handler | Iterable[_Handler] | None = None,
on_giveup: _Handler | Iterable[_Handler] | None = None,
raise_on_giveup: bool = True,
logger: _MaybeLogger = "backoff",
logger: _AnyLoggerOrName | None = "backoff",
backoff_log_level: int = logging.INFO,
giveup_log_level: int = logging.ERROR,
**wait_gen_kwargs: Any,
Expand Down Expand Up @@ -297,7 +297,7 @@ def retry_context(
on_backoff: _ContextHandler | Iterable[_ContextHandler] | None = None,
on_giveup: _ContextHandler | Iterable[_ContextHandler] | None = None,
raise_on_giveup: bool = True,
logger: _MaybeLogger = "backoff",
logger: _AnyLoggerOrName | None = "backoff",
backoff_log_level: int = logging.INFO,
giveup_log_level: int = logging.ERROR,
**wait_gen_kwargs: Any,
Expand Down Expand Up @@ -396,7 +396,7 @@ def aretry_context(
on_backoff: _ContextHandler | Iterable[_ContextHandler] | None = None,
on_giveup: _ContextHandler | Iterable[_ContextHandler] | None = None,
raise_on_giveup: bool = True,
logger: _MaybeLogger = "backoff",
logger: _AnyLoggerOrName | None = "backoff",
backoff_log_level: int = logging.INFO,
giveup_log_level: int = logging.ERROR,
**wait_gen_kwargs: Any,
Expand Down
3 changes: 1 addition & 2 deletions backoff/_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@ def _call_handlers(
"kwargs": kwargs,
"tries": tries,
"elapsed": elapsed,
**extra,
}
# pyrefly: ignore [no-matching-overload]
details.update(extra)
for hdlr in hdlrs:
hdlr(details)

Expand Down
22 changes: 7 additions & 15 deletions backoff/_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@
from collections.abc import Callable, Coroutine, Generator
from typing import Any, TypeAlias, TypedDict, TypeVar

__all__ = [
"_ContextHandler",
"_Handler",
"_MaybeCallable",
"_MaybeLogger",
"_MaybeTuple",
]


class _BaseDetails(TypedDict):
target: Callable[..., Any]
Expand All @@ -38,6 +30,7 @@ class _BaseContextDetails(TypedDict):

class _ContextCallDetails(TypedDict, total=False):
wait: float # present in the on_backoff handler case
value: Any # present in the on_predicate decorator case
exception: Exception # present in the on_giveup handler case


Expand All @@ -50,17 +43,16 @@ class ContextDetails(_BaseContextDetails, _ContextCallDetails, total=False):

T = TypeVar("T")

_AnyLogger = logging.Logger | logging.LoggerAdapter # type: ignore[type-arg]
_AnyLoggerOrName = str | _AnyLogger
_CallableT = TypeVar("_CallableT", bound=Callable[..., Any]) # ruff:ignore[unused-private-type-var]
_Handler: TypeAlias = (
Callable[[Details], None] | Callable[[Details], Coroutine[Any, Any, None]]
)
_ContextHandler: TypeAlias = (
_ContextHandler = (
Callable[[ContextDetails], None]
| Callable[[ContextDetails], Coroutine[Any, Any, None]]
)
_Handler = Callable[[Details], None] | Callable[[Details], Coroutine[Any, Any, None]]
_Jitterer = Callable[[float], float]
_MaybeCallable: TypeAlias = T | Callable[[], T]
_MaybeLogger: TypeAlias = str | logging.Logger | logging.LoggerAdapter | None
_MaybeTuple: TypeAlias = T | tuple[T, ...]
_MaybeCallable: TypeAlias = T | Callable[[], T] # ruff: ignore[unused-private-type-alias]
_MaybeTuple: TypeAlias = T | tuple[T, ...] # ruff: ignore[unused-private-type-alias]
_Predicate = Callable[[T], bool] | Callable[[T], Coroutine[Any, Any, bool]]
_WaitGenerator = Callable[..., Generator[float, Any, None]]
25 changes: 21 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ env_list = [
] },
"coverage",
"lint",
"typing",
{ product = [
[ "typing" ],
{ prefix = "3.", start = 10 },
] },
"docs",
]

Expand Down Expand Up @@ -132,8 +135,11 @@ commands = [
],
]

[tool.tox.env.typing]
description = "run type checking"
[tool.tox.env_base.typing]
factors = [
{ prefix = "3.", start = 9 },
]
description = "run type checking on Python {py_dot_ver}"
dependency_groups = [ "typing" ]
labels = [ "check" ]
commands = [
Expand All @@ -150,7 +156,7 @@ commands = [
"--strict",
"--disallow-any-decorated",
"--follow-imports=silent",
"tests/typing_decorators.py",
"tests/typing",
],
[
"ty",
Expand All @@ -170,6 +176,16 @@ commands = [
"tests",
], extend = true },
],
[
"pyrefly",
"coverage",
"check",
{ replace = "if", condition = "env.GITHUB_ACTIONS == 'true'", then = [ "--output-format=github" ], else = [], extend = true },
{ replace = "posargs", default = [
"backoff",
"tests",
], extend = true },
],
]

[tool.tox.env.docs]
Expand Down Expand Up @@ -232,6 +248,7 @@ ignore = [
[tool.mypy]
check_untyped_defs = true
follow_untyped_imports = true
strict = true
warn_unreachable = true
warn_unused_configs = true
warn_unused_ignores = true
Expand Down
Loading