diff --git a/releasenotes/notes/fix-exponential-multiplier-underflow-4fd1d6d6b9c8e2a1.yaml b/releasenotes/notes/fix-exponential-multiplier-underflow-4fd1d6d6b9c8e2a1.yaml new file mode 100644 index 00000000..dc350cff --- /dev/null +++ b/releasenotes/notes/fix-exponential-multiplier-underflow-4fd1d6d6b9c8e2a1.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Prevent ``wait_exponential`` from raising ``ValueError`` when dividing the + configured maximum wait by a large multiplier underflows to zero. diff --git a/tenacity/wait.py b/tenacity/wait.py index a662eef9..18fb6ea7 100644 --- a/tenacity/wait.py +++ b/tenacity/wait.py @@ -208,7 +208,9 @@ def __call__(self, retry_state: "RetryCallState") -> float: and self.max > 0 and self.exp_base > 1 and math.isfinite(self.max) - and exponent > math.log(self.max / self.multiplier, self.exp_base) + and exponent + > math.log(self.max, self.exp_base) + - math.log(self.multiplier, self.exp_base) ): return max(max(0, self.min), self.max) try: diff --git a/tests/test_tenacity.py b/tests/test_tenacity.py index f6c15ce0..ba44b0c8 100644 --- a/tests/test_tenacity.py +++ b/tests/test_tenacity.py @@ -367,6 +367,10 @@ def __pow__(self, exponent: float, modulo: int | None = None) -> float: r = Retrying(wait=tenacity.wait_exponential(max=40, exp_base=ExplodingPower(2))) self.assertEqual(r.wait(make_retry_state(50, 0)), 40) + def test_exponential_caps_when_max_multiplier_ratio_underflows(self) -> None: + r = Retrying(wait=tenacity.wait_exponential(multiplier=1e300, max=1e-100)) + self.assertEqual(r.wait(make_retry_state(1, 0)), 1e-100) + def test_exponential_with_min_wait(self) -> None: r = Retrying(wait=tenacity.wait_exponential(min=20)) self.assertEqual(r.wait(make_retry_state(1, 0)), 20)