Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-croniter for openSUSE:Factory checked in at 2023-05-29 22:48:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-croniter (Old) and /work/SRC/openSUSE:Factory/.python-croniter.new.1533 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-croniter" Mon May 29 22:48:08 2023 rev:24 rq:1089607 version:1.3.15 Changes: -------- --- /work/SRC/openSUSE:Factory/python-croniter/python-croniter.changes 2023-05-03 12:57:53.568049490 +0200 +++ /work/SRC/openSUSE:Factory/.python-croniter.new.1533/python-croniter.changes 2023-05-29 22:48:22.202500876 +0200 @@ -1,0 +2,7 @@ +Mon May 29 16:02:14 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 1.3.15: + * Fix hashed expressions omitting some entries + * Enhance .match() precision for 6 position expressions + +------------------------------------------------------------------- Old: ---- croniter-1.3.14.tar.gz New: ---- croniter-1.3.15.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-croniter.spec ++++++ --- /var/tmp/diff_new_pack.KjyCgA/_old 2023-05-29 22:48:22.778504322 +0200 +++ /var/tmp/diff_new_pack.KjyCgA/_new 2023-05-29 22:48:22.786504369 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-croniter -Version: 1.3.14 +Version: 1.3.15 Release: 0 Summary: Python iterators for datetime objects with cron-like format License: MIT ++++++ croniter-1.3.14.tar.gz -> croniter-1.3.15.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/croniter-1.3.14/CHANGELOG.rst new/croniter-1.3.15/CHANGELOG.rst --- old/croniter-1.3.14/CHANGELOG.rst 2023-04-12 18:06:44.000000000 +0200 +++ new/croniter-1.3.15/CHANGELOG.rst 2023-05-25 15:56:30.000000000 +0200 @@ -1,6 +1,14 @@ Changelog ============== +1.3.15 (2023-05-25) +------------------- + +- Fix hashed expressions omitting some entries + [@waltervos/Walter Vos <walter....@ns.nl>] +- Enhance .match() precision for 6 position expressions + [@szpol/szymon <szymon.polinkiew...@gmail.com>] + 1.3.14 (2023-04-12) ------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/croniter-1.3.14/PKG-INFO new/croniter-1.3.15/PKG-INFO --- old/croniter-1.3.14/PKG-INFO 2023-04-12 18:06:44.632668700 +0200 +++ new/croniter-1.3.15/PKG-INFO 2023-05-25 15:56:30.939684200 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: croniter -Version: 1.3.14 +Version: 1.3.15 Summary: croniter provides iteration for datetime object with cron like format Home-page: http://github.com/kiorky/croniter Author: Matsumoto Taichi, kiorky @@ -323,6 +323,14 @@ Changelog ============== +1.3.15 (2023-05-25) +------------------- + +- Fix hashed expressions omitting some entries + [@waltervos/Walter Vos <walter....@ns.nl>] +- Enhance .match() precision for 6 position expressions + [@szpol/szymon <szymon.polinkiew...@gmail.com>] + 1.3.14 (2023-04-12) ------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/croniter-1.3.14/setup.py new/croniter-1.3.15/setup.py --- old/croniter-1.3.14/setup.py 2023-04-12 18:06:44.000000000 +0200 +++ new/croniter-1.3.15/setup.py 2023-05-25 15:56:30.000000000 +0200 @@ -24,7 +24,7 @@ setup( name='croniter', - version='1.3.14', + version='1.3.15', py_modules=['croniter', ], description=( 'croniter provides iteration for datetime ' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/croniter-1.3.14/src/croniter/croniter.py new/croniter-1.3.15/src/croniter/croniter.py --- old/croniter-1.3.14/src/croniter/croniter.py 2023-04-12 18:06:44.000000000 +0200 +++ new/croniter-1.3.15/src/croniter/croniter.py 2023-05-25 15:56:30.000000000 +0200 @@ -817,7 +817,8 @@ td = td + ms1 cron.set_current(td, force=True) tdp, tdt = cron.get_current(), cron.get_prev() - return (max(tdp, tdt) - min(tdp, tdt)).total_seconds() < 60 + precision_in_seconds = 1 if len(cron.expanded) == 6 else 60 + return (max(tdp, tdt) - min(tdp, tdt)).total_seconds() < precision_in_seconds def croniter_range(start, stop, expr_format, ret_type=None, day_or=True, exclude_ends=False, @@ -886,15 +887,20 @@ def do(self, idx, hash_type="h", hash_id=None, range_end=None, range_begin=None): """Return a hashed/random integer given range/hash information""" + hours_or_minutes = idx in {0, 1} if range_end is None: range_end = self.cron.RANGES[idx][1] + if hours_or_minutes: + range_end += 1 if range_begin is None: range_begin = self.cron.RANGES[idx][0] if hash_type == 'r': crc = random.randint(0, 0xFFFFFFFF) else: crc = binascii.crc32(hash_id) & 0xFFFFFFFF - return ((crc >> idx) % (range_end - range_begin + 1)) + range_begin + if not hours_or_minutes: + return ((crc >> idx) % (range_end - range_begin + 1)) + range_begin + return ((crc >> idx) % (range_end - range_begin)) + range_begin def match(self, efl, idx, expr, hash_id=None, **kw): return hash_expression_re.match(expr) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/croniter-1.3.14/src/croniter/tests/test_croniter.py new/croniter-1.3.15/src/croniter/tests/test_croniter.py --- old/croniter-1.3.14/src/croniter/tests/test_croniter.py 2023-04-12 18:06:44.000000000 +0200 +++ new/croniter-1.3.15/src/croniter/tests/test_croniter.py 2023-05-25 15:56:30.000000000 +0200 @@ -1015,6 +1015,14 @@ datetime(2019, 1, 14, 0, 1, 0, 0) )) self.assertTrue(croniter.match( + "0 0 * * * 1", + datetime(2023, 5, 25, 0, 0, 1, 0) + )) + self.assertFalse(croniter.match( + "0 0 * * * 1", + datetime(2023, 5, 25, 0, 0, 2, 0) + )) + self.assertTrue(croniter.match( "31 * * * *", datetime(2019, 1, 14, 1, 31, 0, 0) )) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/croniter-1.3.14/src/croniter/tests/test_croniter_hash.py new/croniter-1.3.15/src/croniter/tests/test_croniter_hash.py --- old/croniter-1.3.14/src/croniter/tests/test_croniter_hash.py 2023-04-12 18:06:44.000000000 +0200 +++ new/croniter-1.3.15/src/croniter/tests/test_croniter_hash.py 2023-05-25 15:56:30.000000000 +0200 @@ -1,3 +1,5 @@ +import uuid +import random from datetime import datetime, timedelta from croniter import croniter, CroniterNotAlphaError, CroniterBadCronError @@ -91,12 +93,12 @@ def test_hash_division(self): """Test a hashed division definition""" - self._test_iter('H H/3 * * *', datetime(2020, 1, 1, 3, 10), timedelta(hours=3)) + self._test_iter('H H/3 * * *', datetime(2020, 1, 1, 2, 10), timedelta(hours=3)) def test_hash_range_division(self): """Test a hashed range + division definition""" self._test_iter( - 'H(30-59)/10 H * * *', datetime(2020, 1, 1, 11, 31), timedelta(minutes=10) + 'H(30-59)/10 H * * *', datetime(2020, 1, 1, 11, 30), timedelta(minutes=10) ) def test_hash_invalid_range(self): @@ -144,7 +146,7 @@ @midnight is actually up to 3 hours after midnight, not exactly midnight """ - self._test_iter('@midnight', datetime(2020, 1, 1, 2, 10, 32), timedelta(days=1)) + self._test_iter('@midnight', datetime(2020, 1, 1, 1, 10, 32), timedelta(days=1)) def test_hash_word_hourly(self): """Test built-in @hourly""" @@ -186,3 +188,286 @@ obj_yearly = croniter('@yearly', self.epoch, hash_id=self.hash_id) self.assertEqual(obj_annually.get_next(datetime), obj_yearly.get_next(datetime)) self.assertEqual(obj_annually.get_next(datetime), obj_yearly.get_next(datetime)) + + +class CroniterHashExpanderBase(base.TestCase): + def setUp(self) -> None: + _rd = random.Random() + _rd.seed(100) + self.HASH_IDS = [ + uuid.UUID(int=_rd.getrandbits(128)).bytes for _ in range(350) + ] + + +class CroniterHashExpanderExpandMinutesTest(CroniterHashExpanderBase): + MIN_VALUE = 0 + MAX_VALUE = 59 + TOTAL = 60 + + def test_expand_minutes(self): + minutes = set() + expression = 'H * * * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + minutes.add(expanded[0][0][0]) + assert len(minutes) == self.TOTAL + assert min(minutes) == self.MIN_VALUE + assert max(minutes) == self.MAX_VALUE + + def test_expand_minutes_range_2_minutes(self): + minutes = set() + expression = 'H/2 * * * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _minutes = expanded[0][0] + assert len(_minutes) == 30 + minutes.update(_minutes) + assert len(minutes) == self.TOTAL + assert min(minutes) == self.MIN_VALUE + assert max(minutes) == self.MAX_VALUE + + def test_expand_minutes_range_3_minutes(self): + minutes = set() + expression = 'H/3 * * * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _minutes = expanded[0][0] + assert len(_minutes) == 20 + minutes.update(_minutes) + assert len(minutes) == self.TOTAL + assert min(minutes) == self.MIN_VALUE + assert max(minutes) == self.MAX_VALUE + + def test_expand_minutes_range_15_minutes(self): + minutes = set() + expression = 'H/15 * * * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _minutes = expanded[0][0] + assert len(_minutes) == 4 + minutes.update(_minutes) + assert len(minutes) == self.TOTAL + assert min(minutes) == self.MIN_VALUE + assert max(minutes) == self.MAX_VALUE + + +class CroniterHashExpanderExpandHoursTest(CroniterHashExpanderBase): + MIN_VALUE = 0 + MAX_VALUE = 23 + TOTAL = 24 + + def test_expand_hours(self): + hours = set() + expression = 'H H * * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + hours.add(expanded[0][1][0]) + assert len(hours) == self.TOTAL + assert min(hours) == self.MIN_VALUE + assert max(hours) == self.MAX_VALUE + + def test_expand_hours_range_every_2_hours(self): + hours = set() + expression = 'H H/2 * * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _hours = expanded[0][1] + assert len(_hours) == 12 + hours.update(_hours) + assert len(hours) == self.TOTAL + assert min(hours) == self.MIN_VALUE + assert max(hours) == self.MAX_VALUE + + def test_expand_hours_range_4_hours(self): + hours = set() + expression = 'H H/4 * * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _hours = expanded[0][1] + assert len(_hours) == 6 + hours.update(_hours) + assert len(hours) == self.TOTAL + assert min(hours) == self.MIN_VALUE + assert max(hours) == self.MAX_VALUE + + def test_expand_hours_range_8_hours(self): + hours = set() + expression = 'H H/8 * * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _hours = expanded[0][1] + assert len(_hours) == 3 + hours.update(_hours) + assert len(hours) == self.TOTAL + assert min(hours) == self.MIN_VALUE + assert max(hours) == self.MAX_VALUE + + def test_expand_hours_range_10_hours(self): + hours = set() + expression = 'H H/10 * * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _hours = expanded[0][1] + assert len(_hours) in {2,3} + hours.update(_hours) + assert len(hours) == self.TOTAL + assert min(hours) == self.MIN_VALUE + assert max(hours) == self.MAX_VALUE + + def test_expand_hours_range_12_hours(self): + hours = set() + expression = 'H H/12 * * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _hours = expanded[0][1] + assert len(_hours) == 2 + hours.update(_hours) + assert len(hours) == self.TOTAL + assert min(hours) == self.MIN_VALUE + assert max(hours) == self.MAX_VALUE + + + + +class CroniterHashExpanderExpandMonthDaysTest(CroniterHashExpanderBase): + MIN_VALUE = 1 + MAX_VALUE = 31 + TOTAL = 31 + + def test_expand_month_days(self): + month_days = set() + expression = 'H H H * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + month_days.add(expanded[0][2][0]) + assert len(month_days) == self.TOTAL + assert min(month_days) == self.MIN_VALUE + assert max(month_days) == self.MAX_VALUE + + def test_expand_month_days_range_2_days(self): + month_days = set() + expression = '0 0 H/2 * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _days = expanded[0][2] + assert len(_days) in {15, 16} + month_days.update(_days) + assert len(month_days) == self.TOTAL + assert min(month_days) == self.MIN_VALUE + assert max(month_days) == self.MAX_VALUE + + def test_expand_month_days_range_5_days(self): + month_days = set() + expression = 'H H H/5 * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _days = expanded[0][2] + assert len(_days) in {6, 7} + month_days.update(_days) + assert len(month_days) == self.TOTAL + assert min(month_days) == self.MIN_VALUE + assert max(month_days) == self.MAX_VALUE + + def test_expand_month_days_range_12_days(self): + month_days = set() + expression = 'H H H/12 * *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _days = expanded[0][2] + assert len(_days) in {2, 3} + month_days.update(_days) + assert len(month_days) == self.TOTAL + assert min(month_days) == self.MIN_VALUE + assert max(month_days) == self.MAX_VALUE + + +class CroniterHashExpanderExpandMonthTest(CroniterHashExpanderBase): + MIN_VALUE = 1 + MAX_VALUE = 12 + TOTAL = 12 + + def test_expand_month_days(self): + month_days = set() + expression = 'H H * H *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + month_days.add(expanded[0][3][0]) + assert len(month_days) == self.TOTAL + assert min(month_days) == self.MIN_VALUE + assert max(month_days) == self.MAX_VALUE + + def test_expand_month_days_range_2_months(self): + months = set() + expression = 'H H * H/2 *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _months = expanded[0][3] + assert len(_months) == 6 + months.update(_months) + assert len(months) == self.TOTAL + assert min(months) == self.MIN_VALUE + assert max(months) == self.MAX_VALUE + + def test_expand_month_days_range_3_months(self): + months = set() + expression = 'H H * H/3 *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _months = expanded[0][3] + assert len(_months) == 4 + months.update(_months) + assert len(months) == self.TOTAL + assert min(months) == self.MIN_VALUE + assert max(months) == self.MAX_VALUE + + def test_expand_month_days_range_5_months(self): + months = set() + expression = 'H H * H/5 *' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _months = expanded[0][3] + assert len(_months) in {2, 3} + months.update(_months) + assert len(months) == self.TOTAL + assert min(months) == self.MIN_VALUE + assert max(months) == self.MAX_VALUE + + +class CroniterHashExpanderExpandWeekDays(CroniterHashExpanderBase): + MIN_VALUE = 0 + MAX_VALUE = 6 + TOTAL = 7 + + def test_expand_week_days(self): + week_days = set() + expression = 'H H * * H' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + week_days.add(expanded[0][4][0]) + assert len(week_days) == self.TOTAL + assert min(week_days) == self.MIN_VALUE + assert max(week_days) == self.MAX_VALUE + + def test_expand_week_days_range_2_days(self): + days = set() + expression = 'H H * * H/2' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _days = expanded[0][4] + assert len(_days) in {3, 4} + days.update(_days) + assert len(days) == self.TOTAL + assert min(days) == self.MIN_VALUE + assert max(days) == self.MAX_VALUE + + def test_expand_week_days_range_4_days(self): + days = set() + expression = 'H H * * H/4' + for hash_id in self.HASH_IDS: + expanded = croniter.expand(expression, hash_id=hash_id) + _days = expanded[0][4] + assert len(_days) in {1, 2} + days.update(_days) + assert len(days) == self.TOTAL + assert min(days) == self.MIN_VALUE + assert max(days) == self.MAX_VALUE diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/croniter-1.3.14/src/croniter.egg-info/PKG-INFO new/croniter-1.3.15/src/croniter.egg-info/PKG-INFO --- old/croniter-1.3.14/src/croniter.egg-info/PKG-INFO 2023-04-12 18:06:44.000000000 +0200 +++ new/croniter-1.3.15/src/croniter.egg-info/PKG-INFO 2023-05-25 15:56:30.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: croniter -Version: 1.3.14 +Version: 1.3.15 Summary: croniter provides iteration for datetime object with cron like format Home-page: http://github.com/kiorky/croniter Author: Matsumoto Taichi, kiorky @@ -323,6 +323,14 @@ Changelog ============== +1.3.15 (2023-05-25) +------------------- + +- Fix hashed expressions omitting some entries + [@waltervos/Walter Vos <walter....@ns.nl>] +- Enhance .match() precision for 6 position expressions + [@szpol/szymon <szymon.polinkiew...@gmail.com>] + 1.3.14 (2023-04-12) -------------------