pyo3 icon indicating copy to clipboard operation
pyo3 copied to clipboard

datetime tests out of range macOS & python 3.12

Open davidhewitt opened this issue 1 year ago • 2 comments

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

davidhewitt avatar Mar 02 '24 07:03 davidhewitt

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

LilyFirefly avatar Mar 02 '24 14:03 LilyFirefly

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

davidhewitt avatar Apr 11 '24 21:04 davidhewitt

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?

Cheukting avatar May 24 '24 14:05 Cheukting

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?

davidhewitt avatar May 24 '24 14:05 davidhewitt

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

Cheukting avatar May 24 '24 15:05 Cheukting

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

Cheukting avatar May 24 '24 15:05 Cheukting

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.

Cheukting avatar May 24 '24 16:05 Cheukting

@pganssle is the expert on this who wrote these tests, see https://github.com/PyO3/pyo3/pull/635

Alexander-N avatar May 26 '24 20:05 Alexander-N

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.

Cheukting avatar May 26 '24 21:05 Cheukting