kiorky / croniter

MIT License
410 stars 40 forks source link

several tests fail on 32bit systems #87

Closed stanislavlevin closed 1 month ago

stanislavlevin commented 4 months ago

As of croniter 3.0.0 (tested 3.0.3 as well) several project's tests started to fail on 32bit system:


=================================== FAILURES ===================================
____________________________ CroniterTest.test_year ____________________________

self = <croniter.tests.test_croniter.CroniterTest testMethod=test_year>

    def test_year(self):
        itr1 = croniter("0 0 11 * * 0 2060", datetime(2050, 1, 1))
>       n1 = itr1.get_next(datetime)

src/croniter/tests/test_croniter.py:1505: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
src/croniter/croniter.py:237: in get_next
    return self._get_next(ret_type or self._ret_type,
src/croniter/croniter.py:336: in _get_next
    result = self._calc(self.cur, expanded,
src/croniter/croniter.py:430: in _calc
    dst = now = self._timestamp_to_datetime(now + sign * offset)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <croniter.croniter.croniter object at 0xf7004d38>, timestamp = 2524608001

    def _timestamp_to_datetime(self, timestamp):
        """
        Converts a UNIX timestamp `timestamp` into a `datetime` object.
        """
>       result = datetime.datetime.fromtimestamp(timestamp, tz=tzutc()).replace(tzinfo=None)
E       OverflowError: timestamp out of range for platform time_t

src/croniter/croniter.py:276: OverflowError
_______________ CroniterTest.test_year_with_second_at_beginning ________________

self = <croniter.tests.test_croniter.CroniterTest testMethod=test_year_with_second_at_beginning>

    def test_year_with_second_at_beginning(self):
        base = datetime(2050, 1, 1)
        itr = croniter("59 58 23 31 12 * 2070", base, second_at_beginning=True)
>       n = itr.get_next(datetime)

src/croniter/tests/test_croniter.py:1604: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
src/croniter/croniter.py:237: in get_next
    return self._get_next(ret_type or self._ret_type,
src/croniter/croniter.py:336: in _get_next
    result = self._calc(self.cur, expanded,
src/croniter/croniter.py:430: in _calc
    dst = now = self._timestamp_to_datetime(now + sign * offset)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <croniter.croniter.croniter object at 0xf6fe7720>, timestamp = 2524608001

    def _timestamp_to_datetime(self, timestamp):
        """
        Converts a UNIX timestamp `timestamp` into a `datetime` object.
        """
>       result = datetime.datetime.fromtimestamp(timestamp, tz=tzutc()).replace(tzinfo=None)
E       OverflowError: timestamp out of range for platform time_t

src/croniter/croniter.py:276: OverflowError
_______________________ CroniterHashTest.test_hash_year ________________________

self = <croniter.tests.test_croniter_hash.CroniterHashTest testMethod=test_hash_year>

    def test_hash_year(self):
        """Test years

        provide a seventh field as year
        """
>       self._test_iter(
            'H H * * * H H', datetime(2066, 1, 1, 11, 10, 32), timedelta(days=1)
        )

src/croniter/tests/test_croniter_hash.py:73: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
src/croniter/tests/test_croniter_hash.py:25: in _test_iter
    testval = obj.get_next(next_type)
src/croniter/croniter.py:237: in get_next
    return self._get_next(ret_type or self._ret_type,
src/croniter/croniter.py:343: in _get_next
    dtresult = self._timestamp_to_datetime(result)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <croniter.croniter.croniter object at 0xf6d0b8e8>
timestamp = 3029569832.0

    def _timestamp_to_datetime(self, timestamp):
        """
        Converts a UNIX timestamp `timestamp` into a `datetime` object.
        """
>       result = datetime.datetime.fromtimestamp(timestamp, tz=tzutc()).replace(tzinfo=None)
E       OverflowError: timestamp out of range for platform time_t

src/croniter/croniter.py:276: OverflowError
=========================== short test summary info ============================
FAILED src/croniter/tests/test_croniter.py::CroniterTest::test_year - Overflo...
FAILED src/croniter/tests/test_croniter.py::CroniterTest::test_year_with_second_at_beginning
FAILED src/croniter/tests/test_croniter_hash.py::CroniterHashTest::test_hash_year

Are 32bit systems supported?

kiorky commented 4 months ago

I'm not sure that those are the changes from 3.0.0 and onward that can trigger the problem, but something else.

If you want the support, submit a PR, and i ll be glad to review & merge it :-)

Do you have a way to reproduce it easily ?

kiorky commented 4 months ago

Ok, we are tied to https://github.com/python/cpython/issues/101069, im thinking on how to fix/workaround a bit on 32bits.

Seems 7th fields crons on 32 bit will be limited up to 2038 ....

I try to search a better way.

kiorky commented 4 months ago

the fix is mostly there.

I also added a new CICD test to test under 32bit container, you can see this here : https://github.com/kiorky/croniter/actions/runs/10116093675/job/27978277513

I ll finish this and make a release normally tomorrow.

kiorky commented 1 month ago

fixed, will be released along with #93 if any.

stanislavlevin commented 1 month ago

Thanks!