Skip to content

Commit 2477ab9

Browse files
feat: Add a little bit of typing to google.api_core.retry (#453)
* ref(typing): add a little bit of typing to google.api_core.retry * coverage --------- Co-authored-by: Anthonios Partheniou <[email protected]>
1 parent c0ce73c commit 2477ab9

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

.coveragerc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ exclude_lines =
1111
def __repr__
1212
# Ignore abstract methods
1313
raise NotImplementedError
14+
# Ignore coverage for code specific to static type checkers
15+
TYPE_CHECKING

google/api_core/retry.py

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,28 +54,41 @@ def check_if_exists():
5454
5555
"""
5656

57-
from __future__ import unicode_literals
57+
from __future__ import annotations
5858

5959
import datetime
6060
import functools
6161
import logging
6262
import random
63+
import sys
6364
import time
65+
from typing import Any, Callable, TypeVar, TYPE_CHECKING
6466

6567
import requests.exceptions
6668

6769
from google.api_core import datetime_helpers
6870
from google.api_core import exceptions
6971
from google.auth import exceptions as auth_exceptions
7072

73+
if TYPE_CHECKING:
74+
if sys.version_info >= (3, 10):
75+
from typing import ParamSpec
76+
else:
77+
from typing_extensions import ParamSpec
78+
79+
_P = ParamSpec("_P")
80+
_R = TypeVar("_R")
81+
7182
_LOGGER = logging.getLogger(__name__)
7283
_DEFAULT_INITIAL_DELAY = 1.0 # seconds
7384
_DEFAULT_MAXIMUM_DELAY = 60.0 # seconds
7485
_DEFAULT_DELAY_MULTIPLIER = 2.0
7586
_DEFAULT_DEADLINE = 60.0 * 2.0 # seconds
7687

7788

78-
def if_exception_type(*exception_types):
89+
def if_exception_type(
90+
*exception_types: type[BaseException],
91+
) -> Callable[[BaseException], bool]:
7992
"""Creates a predicate to check if the exception is of a given type.
8093
8194
Args:
@@ -87,7 +100,7 @@ def if_exception_type(*exception_types):
87100
exception is of the given type(s).
88101
"""
89102

90-
def if_exception_type_predicate(exception):
103+
def if_exception_type_predicate(exception: BaseException) -> bool:
91104
"""Bound predicate for checking an exception type."""
92105
return isinstance(exception, exception_types)
93106

@@ -307,14 +320,14 @@ class Retry(object):
307320

308321
def __init__(
309322
self,
310-
predicate=if_transient_error,
311-
initial=_DEFAULT_INITIAL_DELAY,
312-
maximum=_DEFAULT_MAXIMUM_DELAY,
313-
multiplier=_DEFAULT_DELAY_MULTIPLIER,
314-
timeout=_DEFAULT_DEADLINE,
315-
on_error=None,
316-
**kwargs
317-
):
323+
predicate: Callable[[BaseException], bool] = if_transient_error,
324+
initial: float = _DEFAULT_INITIAL_DELAY,
325+
maximum: float = _DEFAULT_MAXIMUM_DELAY,
326+
multiplier: float = _DEFAULT_DELAY_MULTIPLIER,
327+
timeout: float = _DEFAULT_DEADLINE,
328+
on_error: Callable[[BaseException], Any] | None = None,
329+
**kwargs: Any,
330+
) -> None:
318331
self._predicate = predicate
319332
self._initial = initial
320333
self._multiplier = multiplier
@@ -323,7 +336,11 @@ def __init__(
323336
self._deadline = self._timeout
324337
self._on_error = on_error
325338

326-
def __call__(self, func, on_error=None):
339+
def __call__(
340+
self,
341+
func: Callable[_P, _R],
342+
on_error: Callable[[BaseException], Any] | None = None,
343+
) -> Callable[_P, _R]:
327344
"""Wrap a callable with retry behavior.
328345
329346
Args:
@@ -340,7 +357,7 @@ def __call__(self, func, on_error=None):
340357
on_error = self._on_error
341358

342359
@functools.wraps(func)
343-
def retry_wrapped_func(*args, **kwargs):
360+
def retry_wrapped_func(*args: _P.args, **kwargs: _P.kwargs) -> _R:
344361
"""A wrapper that calls target function with retry."""
345362
target = functools.partial(func, *args, **kwargs)
346363
sleep_generator = exponential_sleep_generator(

0 commit comments

Comments
 (0)