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)
 -------------------
 

Reply via email to