From 844e5fbdd857504210111a82f9a29daf42462f21 Mon Sep 17 00:00:00 2001 From: kiorky Date: Thu, 25 Jul 2024 14:59:37 +0300 Subject: [PATCH] Add an `update_current` argument to get_next/get_prev/all_next/all_prev (#84) This fixes #83 . --- CHANGELOG.rst | 3 +- src/croniter/croniter.py | 26 +++++++----- src/croniter/tests/test_croniter.py | 66 +++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3ca8a19..6d19587 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,8 +4,7 @@ Changelog 3.0.1 (unreleased) ------------------ -- Nothing changed yet. - +- Add an `update_current` argument to get_next/get_prev/all_next/all_prev to facilitate writing of some downstream code, see #83. [kiorky] 3.0.0 (2024-07-23) ------------------ diff --git a/src/croniter/croniter.py b/src/croniter/croniter.py index cb92ec6..8a01cf1 100644 --- a/src/croniter/croniter.py +++ b/src/croniter/croniter.py @@ -232,14 +232,13 @@ def _alphaconv(cls, index, key, expressions): raise CroniterNotAlphaError( "[{0}] is not acceptable".format(" ".join(expressions))) - def get_next(self, ret_type=None, start_time=None): + def get_next(self, ret_type=None, start_time=None, update_current=True): if start_time and self._expand_from_start_time: raise ValueError("start_time is not supported when using expand_from_start_time = True.") - self.set_current(start_time, force=True) - return self._get_next(ret_type or self._ret_type, is_prev=False) + return self._get_next(ret_type or self._ret_type, is_prev=False, update_current=update_current) - def get_prev(self, ret_type=None): - return self._get_next(ret_type or self._ret_type, is_prev=True) + def get_prev(self, ret_type=None, start_time=None, update_current=True): + return self._get_next(ret_type or self._ret_type, is_prev=True, update_current=update_current) def get_current(self, ret_type=None): ret_type = ret_type or self._ret_type @@ -285,7 +284,9 @@ def _timedelta_to_seconds(cls, td): """ return timedelta_to_seconds(td) - def _get_next(self, ret_type=None, start_time=None, is_prev=None): + def _get_next(self, ret_type=None, start_time=None, is_prev=None, update_current=None): + if update_current is None: + update_current = True self.set_current(start_time, force=True) if is_prev is None: is_prev = self._is_prev @@ -360,7 +361,8 @@ def _get_next(self, ret_type=None, start_time=None, is_prev=None): dtresult = dtresult_adjusted result = result_adjusted self.dst_start_time = result - self.cur = result + if update_current: + self.cur = result if issubclass(ret_type, datetime.datetime): result = dtresult return result @@ -369,7 +371,7 @@ def _get_next(self, ret_type=None, start_time=None, is_prev=None): # objects in a loop, like "for dt in croniter('5 0 * * *'): ..." # or for combining multiple croniters into single # dates feed using 'itertools' module - def all_next(self, ret_type=None): + def all_next(self, ret_type=None, start_time=None, update_current=None): '''Generator of all consecutive dates. Can be used instead of implicit call to __iter__, whenever non-default 'ret_type' has to be specified. @@ -378,19 +380,21 @@ def all_next(self, ret_type=None): try: while True: self._is_prev = False - yield self._get_next(ret_type or self._ret_type) + yield self._get_next(ret_type or self._ret_type, + start_time=start_time, update_current=update_current) except CroniterBadDateError: if self._max_years_btw_matches_explicitly_set: return else: raise - def all_prev(self, ret_type=None): + def all_prev(self, ret_type=None, start_time=None, update_current=None): '''Generator of all previous dates.''' try: while True: self._is_prev = True - yield self._get_next(ret_type or self._ret_type) + yield self._get_next(ret_type or self._ret_type, + start_time=start_time, update_current=update_current) except CroniterBadDateError: if self._max_years_btw_matches_explicitly_set: return diff --git a/src/croniter/tests/test_croniter.py b/src/croniter/tests/test_croniter.py index b699aed..eb4a2c2 100755 --- a/src/croniter/tests/test_croniter.py +++ b/src/croniter/tests/test_croniter.py @@ -1883,5 +1883,71 @@ def test_get_next_fails_with_expand_from_start_time_true(self): self.assertRaises(ValueError, expanded_croniter.get_next, datetime, start_time=datetime(2024, 7, 12)) + def test_get_next_update_current(self): + cron = croniter("* * * * * *") + + cron.set_current(datetime(2024, 7, 12), force=True) + retn = [(cron.get_next(datetime), cron.get_current(datetime)) + for a in range(3)] + self.assertEqual( + retn, + [(datetime(2024, 7, 12, 0, 0, 1), datetime(2024, 7, 12, 0, 0, 1)), + (datetime(2024, 7, 12, 0, 0, 2), datetime(2024, 7, 12, 0, 0, 2)), + (datetime(2024, 7, 12, 0, 0, 3), datetime(2024, 7, 12, 0, 0, 3))] + ) + + cron.set_current(datetime(2024, 7, 12), force=True) + retp = [(cron.get_prev(datetime), cron.get_current(datetime)) + for a in range(3)] + self.assertEqual( + retp, + [(datetime(2024, 7, 11, 23, 59, 59), datetime(2024, 7, 11, 23, 59, 59)), + (datetime(2024, 7, 11, 23, 59, 58), datetime(2024, 7, 11, 23, 59, 58)), + (datetime(2024, 7, 11, 23, 59, 57), datetime(2024, 7, 11, 23, 59, 57))] + ) + + cron.set_current(datetime(2024, 7, 12), force=True) + r = cron.all_next(datetime) + retan = [(next(r), cron.get_current(datetime)) for a in range(3)] + + cron.set_current(datetime(2024, 7, 12), force=True) + r = cron.all_prev(datetime) + retap = [(next(r), cron.get_current(datetime)) for a in range(3)] + + self.assertEqual(retp, retap) + self.assertEqual(retn, retan) + + cron.set_current(datetime(2024, 7, 12), force=True) + uretn = [(cron.get_next(datetime, update_current=False), cron.get_current(datetime)) + for a in range(3)] + self.assertEqual( + uretn, + [(datetime(2024, 7, 12, 0, 0, 1), datetime(2024, 7, 12, 0, 0)), + (datetime(2024, 7, 12, 0, 0, 1), datetime(2024, 7, 12, 0, 0)), + (datetime(2024, 7, 12, 0, 0, 1), datetime(2024, 7, 12, 0, 0))] + ) + + cron.set_current(datetime(2024, 7, 12), force=True) + uretp = [(cron.get_prev(datetime, update_current=False), cron.get_current(datetime)) + for a in range(3)] + self.assertEqual( + uretp, + [(datetime(2024, 7, 11, 23, 59, 59), datetime(2024, 7, 12, 0, 0)), + (datetime(2024, 7, 11, 23, 59, 59), datetime(2024, 7, 12, 0, 0)), + (datetime(2024, 7, 11, 23, 59, 59), datetime(2024, 7, 12, 0, 0))] + ) + + cron.set_current(datetime(2024, 7, 12), force=True) + r = cron.all_next(datetime, update_current=False) + uretan = [(next(r), cron.get_current(datetime)) for a in range(3)] + + cron.set_current(datetime(2024, 7, 12), force=True) + r = cron.all_prev(datetime, update_current=False) + uretap = [(next(r), cron.get_current(datetime)) for a in range(3)] + + self.assertEqual(uretp, uretap) + self.assertEqual(uretn, uretan) + + if __name__ == '__main__': unittest.main()