datetime tests out of range macOS & python 3.12
https://github.com/PyO3/pyo3/actions/runs/8118596439/job/22193138483?pr=3917#step:22:268a
I haven't tried to reproduce yet, if it does reproduce locally then it should be reasonably straightforward to work out how to adjust the test to stay in bounds.
Fixing this would help reduce CI flakiness!
I've marked this good first issue as it might be a nice way for someone to familiarise with the codebase. (In particular our python based part of the test suite.)
I don't think CI jobs stay around forever, so here's the error:
_________________________ test_datetime_from_timestamp _________________________
@given(dt=st.datetimes(MIN_DATETIME, MAX_DATETIME))
> @example(dt=pdt.datetime(1971, 1, 2, 0, 0))
tests/test_datetime.py:230:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
dt = datetime.datetime(9999, 12, 31, 0, 0, fold=1)
@given(dt=st.datetimes(MIN_DATETIME, MAX_DATETIME))
@example(dt=pdt.datetime(1971, 1, 2, 0, 0))
def test_datetime_from_timestamp(dt):
if PYPY and dt < pdt.datetime(1900, 1, 1):
pytest.xfail("pdt.datetime.timestamp will raise on PyPy with dates before 1900")
> ts = pdt.datetime.timestamp(dt)
E ValueError: year 10000 is out of range
E Falsifying example: test_datetime_from_timestamp(
E dt=datetime.datetime(9999, 12, 31, 0, 0, fold=1),
E )
E
E You can reproduce this example by temporarily adding @reproduce_failure('6.98.15', b'AAAfPwseAAAAAAAAAQ==') as a decorator on your test case
tests/test_datetime.py:235: ValueError
=========================== short test summary info ============================
FAILED tests/test_datetime.py::test_datetime_from_timestamp - ValueError: year 10000 is out of range
Falsifying example: test_datetime_from_timestamp(
dt=datetime.datetime(9999, 12, 31, 0, 0, fold=1),
)
You can reproduce this example by temporarily adding @reproduce_failure('6.98.15', b'AAAfPwseAAAAAAAAAQ==') as a decorator on your test case
Looks like windows 3.12 can fail too:
================================== FAILURES ===================================
________________________ test_datetime_from_timestamp _________________________
@given(dt=st.datetimes(MIN_DATETIME, MAX_DATETIME))
> @example(dt=pdt.datetime(1971, 1, 2, 0, 0))
tests\test_datetime.py:230:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
dt = datetime.datetime(3001, 1, 18, 8, 0, fold=1)
@given(dt=st.datetimes(MIN_DATETIME, MAX_DATETIME))
@example(dt=pdt.datetime(1971, 1, 2, 0, 0))
def test_datetime_from_timestamp(dt):
if PYPY and dt < pdt.datetime(1900, 1, 1):
pytest.xfail("pdt.datetime.timestamp will raise on PyPy with dates before 1900")
> ts = pdt.datetime.timestamp(dt)
E OSError: [Errno 22] Invalid argument
E Falsifying example: test_datetime_from_timestamp(
E dt=datetime.datetime(3001, 1, 18, 8, 0, fold=1),
E )
E
E You can reproduce this example by temporarily adding @reproduce_failure('6.100.1', b'AAAD6QARCAAAAAAAAQ==') as a decorator on your test case
tests\test_datetime.py:235: OSError
=========================== short test summary info ===========================
FAILED tests/test_datetime.py::test_datetime_from_timestamp - OSError: [Errno 22] Invalid argument
Falsifying example: test_datetime_from_timestamp(
dt=datetime.datetime(3001, 1, 18, 8, 0, fold=1),
)
You can reproduce this example by temporarily adding @reproduce_failure('6.100.1', b'AAAD6QARCAAAAAAAAQ==') as a decorator on your test case
======================== 1 failed, 147 passed in 3.87s ========================
From here.), on 32 bit Windows actual range for C datetime is midnight, January 1, 1970, to January 18, 19:14:07, 2038, I wonder how is the MIN and MAX range in the code:
if IS_WINDOWS:
MIN_DATETIME = pdt.datetime(1971, 1, 2, 0, 0)
if IS_32_BIT:
MAX_DATETIME = pdt.datetime(3001, 1, 19, 4, 59, 59)
else:
MAX_DATETIME = pdt.datetime(3001, 1, 19, 7, 59, 59)
else:
if IS_32_BIT:
# TS ±2147483648 (2**31)
MIN_DATETIME = pdt.datetime(1901, 12, 13, 20, 45, 52)
MAX_DATETIME = pdt.datetime(2038, 1, 18, 3, 14, 8)
else:
MIN_DATETIME = pdt.datetime(1, 1, 2, 0, 0)
MAX_DATETIME = pdt.datetime(9999, 12, 31, 18, 59, 59)
determined?
Off the top of my head I don't recall why we made those choices, the commit history or GitHub discussion on PRs might reveal more. There is also datetime.min and datetime.max, which might be useful here?
According to this datetime itself does not limit the range in C level, you will get an OverflowError or OSError (which is exactly what we have above). So I doubt datetime.min and datetime.max will be helpful here
I think I will poke around a bit more to check why the range is chosen and if should we adjust them. Or we can write some code to determine the range with seconds (which is more straightforward as we know the max in, for example, 32 bit machine).
It was added 5 years ago by @Alexander-N : https://github.com/PyO3/pyo3/commit/7aaef51ab05f02ba9d150431296435c260cfc7a7
I am wondering if this will be a better information source of what the range should be. https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/mktime-mktime32-mktime64?view=msvc-170
If there's something that I missed maybe @Alexander-N can shine some light on it.
@pganssle is the expert on this who wrote these tests, see https://github.com/PyO3/pyo3/pull/635
Thanks @Alexander-N and @pganssle I did some research this weekend and may have found the problem, have created a PR and welcome for reviews.