Skip to content

Commit

Permalink
compat: add deprecation warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
immerrr committed Jul 25, 2018
1 parent 0a54943 commit 846d8c8
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 27 deletions.
2 changes: 1 addition & 1 deletion tenacity/after.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from tenacity import _utils


def after_nothing(func, trial_number, trial_time_taken):
def after_nothing(retry_state):
"""After call strategy that does nothing."""


Expand Down
2 changes: 1 addition & 1 deletion tenacity/before.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from tenacity import _utils


def before_nothing(func, trial_number):
def before_nothing(retry_state):
"""Before call strategy that does nothing."""


Expand Down
2 changes: 1 addition & 1 deletion tenacity/before_sleep.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from tenacity import _utils


def before_sleep_nothing(retry_state, sleep, last_result):
def before_sleep_nothing(retry_state):
"""Before call strategy that does nothing."""


Expand Down
23 changes: 22 additions & 1 deletion tenacity/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@

import inspect
from fractions import Fraction
from warnings import warn

import six

from tenacity import _utils


def warn_about_non_retry_state_deprecation(cbname, func, stacklevel):
msg = (
'"%s" function must accept single "retry_state" parameter,'
' please update %s' % (cbname, _utils.get_callback_name(func)))
warn(msg, DeprecationWarning, stacklevel=stacklevel + 1)


def func_takes_retry_state(func):
if not six.callable(func):
return False
Expand Down Expand Up @@ -99,6 +107,8 @@ def stop_func_accept_retry_state(stop_func):

@_utils.wraps(stop_func)
def wrapped_stop_func(retry_state):
warn_about_non_retry_state_deprecation(
'stop', stop_func, stacklevel=4)
return stop_func(
retry_state.attempt_number,
retry_state.seconds_since_start,
Expand All @@ -117,6 +127,8 @@ def wait_func_accept_retry_state(wait_func):
if func_takes_last_result(wait_func):
@_utils.wraps(wait_func)
def wrapped_wait_func(retry_state):
warn_about_non_retry_state_deprecation(
'wait', wait_func, stacklevel=4)
return wait_func(
retry_state.attempt_number,
retry_state.seconds_since_start,
Expand All @@ -125,6 +137,8 @@ def wrapped_wait_func(retry_state):
else:
@_utils.wraps(wait_func)
def wrapped_wait_func(retry_state):
warn_about_non_retry_state_deprecation(
'wait', wait_func, stacklevel=4)
return wait_func(
retry_state.attempt_number,
retry_state.seconds_since_start,
Expand All @@ -142,6 +156,8 @@ def retry_func_accept_retry_state(retry_func):

@_utils.wraps(retry_func)
def wrapped_retry_func(retry_state):
warn_about_non_retry_state_deprecation(
'retry', retry_func, stacklevel=4)
return retry_func(retry_state.outcome)
return wrapped_retry_func

Expand All @@ -157,6 +173,7 @@ def before_func_accept_retry_state(fn):
@_utils.wraps(fn)
def wrapped_before_func(retry_state):
# func, trial_number, trial_time_taken
warn_about_non_retry_state_deprecation('before', fn, stacklevel=4)
return fn(
retry_state.fn,
retry_state.attempt_number,
Expand All @@ -175,6 +192,7 @@ def after_func_accept_retry_state(fn):
@_utils.wraps(fn)
def wrapped_after_sleep_func(retry_state):
# func, trial_number, trial_time_taken
warn_about_non_retry_state_deprecation('after', fn, stacklevel=4)
return fn(
retry_state.fn,
retry_state.attempt_number,
Expand All @@ -193,6 +211,8 @@ def before_sleep_func_accept_retry_state(fn):
@_utils.wraps(fn)
def wrapped_before_sleep_func(retry_state):
# retry_object, sleep, last_result
warn_about_non_retry_state_deprecation(
'before_sleep', fn, stacklevel=4)
return fn(
retry_state.retry_object,
sleep=getattr(retry_state.next_action, 'sleep'),
Expand All @@ -209,6 +229,7 @@ def retry_error_callback_accept_retry_state(fn):

@_utils.wraps(fn)
def wrapped_retry_error_callback(retry_state):
# retry_object, sleep, last_result
warn_about_non_retry_state_deprecation(
'retry_error_callback', fn, stacklevel=4)
return fn(retry_state.outcome)
return wrapped_retry_error_callback
71 changes: 49 additions & 22 deletions tenacity/tests/test_tenacity.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@
import logging
import time
import unittest
import warnings
from contextlib import contextmanager
from copy import copy

import pytest

import six.moves

import tenacity
from tenacity import RetryError
from tenacity import Retrying
from tenacity import retry
from tenacity import RetryError, Retrying, retry
from tenacity.compat import make_retry_state


Expand Down Expand Up @@ -104,11 +107,14 @@ def test_stop_after_delay(self):
def test_legacy_explicit_stop_type(self):
Retrying(stop="stop_after_attempt")

def test_stop_func_with_old_parameters(self):
def test_stop_backward_compat(self):
r = Retrying(stop=lambda attempt, delay: attempt == delay)
self.assertFalse(r.stop(make_retry_state(1, 3)))
self.assertFalse(r.stop(make_retry_state(100, 99)))
self.assertTrue(r.stop(make_retry_state(101, 101)))
with reports_deprecation_warning():
self.assertFalse(r.stop(make_retry_state(1, 3)))
with reports_deprecation_warning():
self.assertFalse(r.stop(make_retry_state(100, 99)))
with reports_deprecation_warning():
self.assertTrue(r.stop(make_retry_state(101, 101)))

def test_stop_func_with_retry_state(self):
def stop_func(retry_state):
Expand Down Expand Up @@ -199,7 +205,7 @@ def test_exponential_with_max_wait_and_multiplier(self):
def test_legacy_explicit_wait_type(self):
Retrying(wait="exponential_sleep")

def test_wait_func_result(self):
def test_wait_backward_compat_with_result(self):
captures = []

def wait_capture(attempt, delay, last_result=None):
Expand All @@ -213,12 +219,15 @@ def dying():
r = Retrying(wait=wait_capture, sleep=lambda secs: None,
stop=tenacity.stop_after_attempt(r_attempts),
reraise=True)
self.assertRaises(Exception, r.call, dying)
with reports_deprecation_warning():
self.assertRaises(Exception, r.call, dying)
self.assertEqual(r_attempts - 1, len(captures))
self.assertTrue(all([r.failed for r in captures]))

def test_wait_func(self):
r = Retrying(wait=lambda attempt, delay: attempt * delay)
def wait_func(retry_state):
return retry_state.attempt_number * retry_state.seconds_since_start
r = Retrying(wait=wait_func)
self.assertEqual(r.wait(make_retry_state(1, 5)), 5)
self.assertEqual(r.wait(make_retry_state(2, 11)), 22)
self.assertEqual(r.wait(make_retry_state(10, 100)), 1000)
Expand Down Expand Up @@ -353,7 +362,7 @@ def mean(lst):
self._assert_inclusive_range(mean(attempt[8]), 28.00, 34.00)
self._assert_inclusive_range(mean(attempt[9]), 28.00, 34.00)

def test_wait_backward_compatibility(self):
def test_wait_backward_compat(self):
"""Ensure Retrying object accepts both old and newstyle wait funcs."""
def wait1(previous_attempt_number, delay_since_first_attempt):
wait1.calls.append((
Expand All @@ -373,13 +382,15 @@ def dying():
raise Exception("Broken")

retrying1 = Retrying(wait=wait1, stop=tenacity.stop_after_attempt(4))
self.assertRaises(Exception, lambda: retrying1.call(dying))
with reports_deprecation_warning():
self.assertRaises(Exception, lambda: retrying1.call(dying))
self.assertEqual([t[0] for t in wait1.calls], [1, 2, 3])
# This assumes that 3 iterations complete within 1 second.
self.assertTrue(all(t[1] < 1 for t in wait1.calls))

retrying2 = Retrying(wait=wait2, stop=tenacity.stop_after_attempt(4))
self.assertRaises(Exception, lambda: retrying2.call(dying))
with reports_deprecation_warning():
self.assertRaises(Exception, lambda: retrying2.call(dying))
self.assertEqual([t[0] for t in wait2.calls], [1, 2, 3])
# This assumes that 3 iterations complete within 1 second.
self.assertTrue(all(t[1] < 1 for t in wait2.calls))
Expand Down Expand Up @@ -959,8 +970,9 @@ class TestBeforeAfterAttempts(unittest.TestCase):
def test_before_attempts(self):
TestBeforeAfterAttempts._attempt_number = 0

def _before(fn, attempt_number):
TestBeforeAfterAttempts._attempt_number = attempt_number
def _before(retry_state):
TestBeforeAfterAttempts._attempt_number = \
retry_state.attempt_number

@retry(wait=tenacity.wait_fixed(1),
stop=tenacity.stop_after_attempt(1),
Expand All @@ -975,8 +987,9 @@ def _test_before():
def test_after_attempts(self):
TestBeforeAfterAttempts._attempt_number = 0

def _after(fn, attempt_number, trial_time_taken_ms):
TestBeforeAfterAttempts._attempt_number = attempt_number
def _after(retry_state):
TestBeforeAfterAttempts._attempt_number = \
retry_state.attempt_number

@retry(wait=tenacity.wait_fixed(0.1),
stop=tenacity.stop_after_attempt(3),
Expand Down Expand Up @@ -1020,7 +1033,8 @@ def _test_before_sleep():
if _before_sleep.attempt_number < 2:
raise Exception("testing before_sleep_attempts handler")

_test_before_sleep()
with reports_deprecation_warning():
_test_before_sleep()
self.assertEqual(_before_sleep.attempt_number, 2)

def test_before_sleep_log_raises(self):
Expand Down Expand Up @@ -1105,7 +1119,7 @@ def test_reraise_timeout_from_retry_error(self):

@retry(wait=tenacity.wait_fixed(0.1),
stop=tenacity.stop_after_attempt(2),
retry=lambda x: True)
retry=lambda retry_state: True)
def _mock_fn():
calls.append('x')

Expand All @@ -1123,7 +1137,7 @@ def test_reraise_no_exception(self):

@retry(wait=tenacity.wait_fixed(0.1),
stop=tenacity.stop_after_attempt(2),
retry=lambda x: True,
retry=lambda retry_state: True,
reraise=True)
def _mock_fn():
calls.append('x')
Expand Down Expand Up @@ -1166,7 +1180,7 @@ def _callback(self, fut):
self._callback_called = True
return fut

def test_retry_error_callback_deprecated(self):
def test_retry_error_callback_backward_compat(self):
num_attempts = 3

def retry_error_callback(fut):
Expand All @@ -1181,7 +1195,8 @@ def _foobar():
self._attempt_number += 1
raise Exception("This exception should not be raised")

result = _foobar()
with reports_deprecation_warning():
result = _foobar()

self.assertEqual(retry_error_callback.called_times, 1)
self.assertEqual(num_attempts, self._attempt_number)
Expand Down Expand Up @@ -1209,5 +1224,17 @@ def _foobar():
self.assertIsInstance(result, tenacity.Future)


@contextmanager
def reports_deprecation_warning():
__tracebackhide__ = True
oldfilters = copy(warnings.filters)
warnings.simplefilter('always')
try:
with pytest.warns(DeprecationWarning):
yield
finally:
warnings.filters = oldfilters


if __name__ == '__main__':
unittest.main()
2 changes: 1 addition & 1 deletion tenacity/wait.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

import six

from tenacity import compat as _compat
from tenacity import _utils
from tenacity import compat as _compat


@six.add_metaclass(abc.ABCMeta)
Expand Down

0 comments on commit 846d8c8

Please sign in to comment.