1+ import abc
12import socket
23from time import sleep
3- from typing import TYPE_CHECKING , Any , Callable , Iterable , Tuple , Type , TypeVar
4+ from typing import TYPE_CHECKING , Any , Callable , Generic , Iterable , Tuple , Type , TypeVar
45
56from redis .exceptions import ConnectionError , TimeoutError
67
78T = TypeVar ("T" )
9+ E = TypeVar ("E" , bound = Exception , covariant = True )
810
911if TYPE_CHECKING :
1012 from redis .backoff import AbstractBackoff
1113
1214
13- class Retry :
15+ class AbstractRetry ( Generic [ E ], abc . ABC ) :
1416 """Retry a specific number of times after a failure"""
1517
18+ _supported_errors : Tuple [Type [E ], ...]
19+
1620 def __init__ (
1721 self ,
1822 backoff : "AbstractBackoff" ,
1923 retries : int ,
20- supported_errors : Tuple [Type [Exception ], ...] = (
21- ConnectionError ,
22- TimeoutError ,
23- socket .timeout ,
24- ),
24+ supported_errors : Tuple [Type [E ], ...],
2525 ):
2626 """
2727 Initialize a `Retry` object with a `Backoff` object
@@ -34,22 +34,14 @@ def __init__(
3434 self ._retries = retries
3535 self ._supported_errors = supported_errors
3636
37+ @abc .abstractmethod
3738 def __eq__ (self , other : Any ) -> bool :
38- if not isinstance (other , Retry ):
39- return NotImplemented
40-
41- return (
42- self ._backoff == other ._backoff
43- and self ._retries == other ._retries
44- and set (self ._supported_errors ) == set (other ._supported_errors )
45- )
39+ return NotImplemented
4640
4741 def __hash__ (self ) -> int :
4842 return hash ((self ._backoff , self ._retries , frozenset (self ._supported_errors )))
4943
50- def update_supported_errors (
51- self , specified_errors : Iterable [Type [Exception ]]
52- ) -> None :
44+ def update_supported_errors (self , specified_errors : Iterable [Type [E ]]) -> None :
5345 """
5446 Updates the supported errors with the specified error types
5547 """
@@ -69,6 +61,32 @@ def update_retries(self, value: int) -> None:
6961 """
7062 self ._retries = value
7163
64+
65+ class Retry (AbstractRetry [Exception ]):
66+ __hash__ = AbstractRetry .__hash__
67+
68+ def __init__ (
69+ self ,
70+ backoff : "AbstractBackoff" ,
71+ retries : int ,
72+ supported_errors : Tuple [Type [Exception ], ...] = (
73+ ConnectionError ,
74+ TimeoutError ,
75+ socket .timeout ,
76+ ),
77+ ):
78+ super ().__init__ (backoff , retries , supported_errors )
79+
80+ def __eq__ (self , other : Any ) -> bool :
81+ if not isinstance (other , Retry ):
82+ return NotImplemented
83+
84+ return (
85+ self ._backoff == other ._backoff
86+ and self ._retries == other ._retries
87+ and set (self ._supported_errors ) == set (other ._supported_errors )
88+ )
89+
7290 def call_with_retry (
7391 self ,
7492 do : Callable [[], T ],
0 commit comments