dirty-equals icon indicating copy to clipboard operation
dirty-equals copied to clipboard

unix datetime tests fail if TZ != UTC

Open mgorny opened this issue 2 years ago • 3 comments

The following tests fail if the system timezone is not UTC:

FAILED tests/test_datetime.py::test_is_datetime[unix-int] - assert 946684800 == IsDatetime(approx=datetime.datetime(2000, 1, 1, 0, 0...
FAILED tests/test_datetime.py::test_is_datetime[unix-float] - assert 946684800.123 == IsDatetime(approx=datetime.datetime(2000, 1, 1...
FAILED tests/test_docs.py::test_docs_examples[dirty_equals/_datetime.py:45-58] - assert 946684800.123 == IsDatetime(approx=datetime....

Full output:

============================================================== FAILURES ===============================================================
_____________________________________________________ test_is_datetime[unix-int] ______________________________________________________

value = 946684800, dirty = IsDatetime(approx=datetime.datetime(2000, 1, 1, 0, 0), unix_number=True), expect_match = True

    @pytest.mark.parametrize(
        'value,dirty,expect_match',
        [
            pytest.param(datetime(2000, 1, 1), IsDatetime(approx=datetime(2000, 1, 1)), True, id='same'),
            # Note: this requires the system timezone to be UTC
            pytest.param(946684800, IsDatetime(approx=datetime(2000, 1, 1), unix_number=True), True, id='unix-int'),
            # Note: this requires the system timezone to be UTC
            pytest.param(946684800.123, IsDatetime(approx=datetime(2000, 1, 1), unix_number=True), True, id='unix-float'),
            pytest.param(946684800, IsDatetime(approx=datetime(2000, 1, 1)), False, id='unix-different'),
            pytest.param(
                '2000-01-01T00:00', IsDatetime(approx=datetime(2000, 1, 1), iso_string=True), True, id='iso-string-true'
            ),
            pytest.param('2000-01-01T00:00', IsDatetime(approx=datetime(2000, 1, 1)), False, id='iso-string-different'),
            pytest.param('broken', IsDatetime(approx=datetime(2000, 1, 1)), False, id='iso-string-wrong'),
            pytest.param(
                '28/01/87', IsDatetime(approx=datetime(1987, 1, 28), format_string='%d/%m/%y'), True, id='string-format'
            ),
            pytest.param('28/01/87', IsDatetime(approx=datetime(2000, 1, 1)), False, id='string-format-different'),
            pytest.param('foobar', IsDatetime(approx=datetime(2000, 1, 1)), False, id='string-format-wrong'),
            pytest.param(datetime.now().isoformat(), IsNow(iso_string=True), True, id='isnow-str-true'),
            pytest.param(datetime(2000, 1, 1).isoformat(), IsNow(iso_string=True), False, id='isnow-str-different'),
            pytest.param([1, 2, 3], IsDatetime(approx=datetime(2000, 1, 1)), False, id='wrong-type'),
            pytest.param(
                datetime(2020, 1, 1, 12, 13, 14), IsDatetime(approx=datetime(2020, 1, 1, 12, 13, 14)), True, id='tz-same'
            ),
            pytest.param(
                datetime(2020, 1, 1, 12, 13, 14, tzinfo=timezone.utc),
                IsDatetime(approx=datetime(2020, 1, 1, 12, 13, 14), enforce_tz=False),
                True,
                id='tz-utc',
            ),
            pytest.param(
                datetime(2020, 1, 1, 12, 13, 14, tzinfo=timezone.utc),
                IsDatetime(approx=datetime(2020, 1, 1, 12, 13, 14)),
                False,
                id='tz-utc-different',
            ),
            pytest.param(
                datetime(2020, 1, 1, 12, 13, 14),
                IsDatetime(approx=datetime(2020, 1, 1, 12, 13, 14, tzinfo=timezone.utc), enforce_tz=False),
                False,
                id='tz-approx-tz',
            ),
            pytest.param(
                datetime(2020, 1, 1, 12, 13, 14, tzinfo=timezone(offset=timedelta(hours=1))),
                IsDatetime(approx=datetime(2020, 1, 1, 12, 13, 14), enforce_tz=False),
                True,
                id='tz-1-hour',
            ),
            pytest.param(
                pytz.timezone('Europe/London').localize(datetime(2022, 2, 15, 15, 15)),
                IsDatetime(
                    approx=pytz.timezone('America/New_York').localize(datetime(2022, 2, 15, 10, 15)), enforce_tz=False
                ),
                True,
                id='tz-both-tz',
            ),
            pytest.param(
                pytz.timezone('Europe/London').localize(datetime(2022, 2, 15, 15, 15)),
                IsDatetime(approx=pytz.timezone('America/New_York').localize(datetime(2022, 2, 15, 10, 15))),
                False,
                id='tz-both-tz-different',
            ),
            pytest.param(datetime(2000, 1, 1), IsDatetime(ge=datetime(2000, 1, 1)), True, id='ge'),
            pytest.param(datetime(1999, 1, 1), IsDatetime(ge=datetime(2000, 1, 1)), False, id='ge-not'),
            pytest.param(datetime(2000, 1, 2), IsDatetime(gt=datetime(2000, 1, 1)), True, id='gt'),
            pytest.param(datetime(2000, 1, 1), IsDatetime(gt=datetime(2000, 1, 1)), False, id='gt-not'),
        ],
    )
    def test_is_datetime(value, dirty, expect_match):
        if expect_match:
>           assert value == dirty
E           assert 946684800 == IsDatetime(approx=datetime.datetime(2000, 1, 1, 0, 0), unix_number=True)

tests/test_datetime.py:80: AssertionError
____________________________________________________ test_is_datetime[unix-float] _____________________________________________________

value = 946684800.123, dirty = IsDatetime(approx=datetime.datetime(2000, 1, 1, 0, 0), unix_number=True), expect_match = True

    @pytest.mark.parametrize(
        'value,dirty,expect_match',
        [
            pytest.param(datetime(2000, 1, 1), IsDatetime(approx=datetime(2000, 1, 1)), True, id='same'),
            # Note: this requires the system timezone to be UTC
            pytest.param(946684800, IsDatetime(approx=datetime(2000, 1, 1), unix_number=True), True, id='unix-int'),
            # Note: this requires the system timezone to be UTC
            pytest.param(946684800.123, IsDatetime(approx=datetime(2000, 1, 1), unix_number=True), True, id='unix-float'),
            pytest.param(946684800, IsDatetime(approx=datetime(2000, 1, 1)), False, id='unix-different'),
            pytest.param(
                '2000-01-01T00:00', IsDatetime(approx=datetime(2000, 1, 1), iso_string=True), True, id='iso-string-true'
            ),
            pytest.param('2000-01-01T00:00', IsDatetime(approx=datetime(2000, 1, 1)), False, id='iso-string-different'),
            pytest.param('broken', IsDatetime(approx=datetime(2000, 1, 1)), False, id='iso-string-wrong'),
            pytest.param(
                '28/01/87', IsDatetime(approx=datetime(1987, 1, 28), format_string='%d/%m/%y'), True, id='string-format'
            ),
            pytest.param('28/01/87', IsDatetime(approx=datetime(2000, 1, 1)), False, id='string-format-different'),
            pytest.param('foobar', IsDatetime(approx=datetime(2000, 1, 1)), False, id='string-format-wrong'),
            pytest.param(datetime.now().isoformat(), IsNow(iso_string=True), True, id='isnow-str-true'),
            pytest.param(datetime(2000, 1, 1).isoformat(), IsNow(iso_string=True), False, id='isnow-str-different'),
            pytest.param([1, 2, 3], IsDatetime(approx=datetime(2000, 1, 1)), False, id='wrong-type'),
            pytest.param(
                datetime(2020, 1, 1, 12, 13, 14), IsDatetime(approx=datetime(2020, 1, 1, 12, 13, 14)), True, id='tz-same'
            ),
            pytest.param(
                datetime(2020, 1, 1, 12, 13, 14, tzinfo=timezone.utc),
                IsDatetime(approx=datetime(2020, 1, 1, 12, 13, 14), enforce_tz=False),
                True,
                id='tz-utc',
            ),
            pytest.param(
                datetime(2020, 1, 1, 12, 13, 14, tzinfo=timezone.utc),
                IsDatetime(approx=datetime(2020, 1, 1, 12, 13, 14)),
                False,
                id='tz-utc-different',
            ),
            pytest.param(
                datetime(2020, 1, 1, 12, 13, 14),
                IsDatetime(approx=datetime(2020, 1, 1, 12, 13, 14, tzinfo=timezone.utc), enforce_tz=False),
                False,
                id='tz-approx-tz',
            ),
            pytest.param(
                datetime(2020, 1, 1, 12, 13, 14, tzinfo=timezone(offset=timedelta(hours=1))),
                IsDatetime(approx=datetime(2020, 1, 1, 12, 13, 14), enforce_tz=False),
                True,
                id='tz-1-hour',
            ),
            pytest.param(
                pytz.timezone('Europe/London').localize(datetime(2022, 2, 15, 15, 15)),
                IsDatetime(
                    approx=pytz.timezone('America/New_York').localize(datetime(2022, 2, 15, 10, 15)), enforce_tz=False
                ),
                True,
                id='tz-both-tz',
            ),
            pytest.param(
                pytz.timezone('Europe/London').localize(datetime(2022, 2, 15, 15, 15)),
                IsDatetime(approx=pytz.timezone('America/New_York').localize(datetime(2022, 2, 15, 10, 15))),
                False,
                id='tz-both-tz-different',
            ),
            pytest.param(datetime(2000, 1, 1), IsDatetime(ge=datetime(2000, 1, 1)), True, id='ge'),
            pytest.param(datetime(1999, 1, 1), IsDatetime(ge=datetime(2000, 1, 1)), False, id='ge-not'),
            pytest.param(datetime(2000, 1, 2), IsDatetime(gt=datetime(2000, 1, 1)), True, id='gt'),
            pytest.param(datetime(2000, 1, 1), IsDatetime(gt=datetime(2000, 1, 1)), False, id='gt-not'),
        ],
    )
    def test_is_datetime(value, dirty, expect_match):
        if expect_match:
>           assert value == dirty
E           assert 946684800.123 == IsDatetime(approx=datetime.datetime(2000, 1, 1, 0, 0), unix_number=True)

tests/test_datetime.py:80: AssertionError
_________________________________________ test_docs_examples[dirty_equals/_datetime.py:45-58] _________________________________________

module_name = '_datetime_45_58'
source_code = '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nfrom dirty_equals import Is...string=True)\n\nassert datetime(2000, 1, 2) == IsDatetime(gt=y2k)\nassert datetime(1999, 1, 2) != IsDatetime(gt=y2k)\n'
import_execute = <function import_execute.<locals>._import_execute at 0x7f3d4b0a4dc0>

    def test_docs_examples(module_name, source_code, import_execute):
>       import_execute(module_name, source_code, True)

tests/test_docs.py:69: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/test_docs.py:25: in _import_execute
    spec.loader.exec_module(module)
/usr/lib/python3.10/site-packages/_pytest/assertion/rewrite.py:168: in exec_module
    exec(co, module.__dict__)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    from dirty_equals import IsDatetime
    from datetime import datetime
    
    y2k = datetime(2000, 1, 1)
    assert datetime(2000, 1, 1) == IsDatetime(approx=y2k)
    # Note: this requires the system timezone to be UTC
    assert 946684800.123 == IsDatetime(approx=y2k, unix_number=True)
E   assert 946684800.123 == IsDatetime(approx=datetime.datetime(2000, 1, 1, 0, 0), unix_number=True)
E    +  where IsDatetime(approx=datetime.datetime(2000, 1, 1, 0, 0), unix_number=True) = IsDatetime(approx=datetime.datetime(2000, 1, 1, 0, 0), unix_number=True)

../pytest-of-mgorny/pytest-9/test_docs_examples_dirty_equal32/_datetime_45_58.py:52: AssertionError
======================================================= short test summary info =======================================================
FAILED tests/test_datetime.py::test_is_datetime[unix-int] - assert 946684800 == IsDatetime(approx=datetime.datetime(2000, 1, 1, 0, 0...
FAILED tests/test_datetime.py::test_is_datetime[unix-float] - assert 946684800.123 == IsDatetime(approx=datetime.datetime(2000, 1, 1...
FAILED tests/test_docs.py::test_docs_examples[dirty_equals/_datetime.py:45-58] - assert 946684800.123 == IsDatetime(approx=datetime....
==================================================== 3 failed, 481 passed in 1.09s ====================================================

mgorny avatar Apr 24 '22 08:04 mgorny

Fix welcome, but the simplest fix might be to run tests with TZ=utc ....

If that's not an option, it shouldn't be hard to fix in python.

samuelcolvin avatar Apr 24 '22 08:04 samuelcolvin

To be honest, I don't know if that's a problem with the tests or with the underlying logic, i.e. if it doesn't break real code.

mgorny avatar Apr 24 '22 09:04 mgorny

I think (hope) it's just that tests assume UTC.

samuelcolvin avatar Apr 24 '22 09:04 samuelcolvin