From d8d88e9b1e45b8366bcd42e4d483fd4102e374da Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 5 Nov 2020 18:48:25 -0800 Subject: [PATCH 1/6] CI: catch windows py38 OSError --- pandas/_libs/tslibs/tzconversion.pyx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pandas/_libs/tslibs/tzconversion.pyx b/pandas/_libs/tslibs/tzconversion.pyx index 4a3fac1954ab7..d23e04e867bde 100644 --- a/pandas/_libs/tslibs/tzconversion.pyx +++ b/pandas/_libs/tslibs/tzconversion.pyx @@ -549,8 +549,10 @@ cdef inline int64_t _tzlocal_get_offset_components(int64_t val, tzinfo tz, return int(td.total_seconds() * 1_000_000_000) +# OSError may be thrown by tzlocal on windows at or close to 1970-01-01 +# see https://github.com/pandas-dev/pandas/pull/37591#issuecomment-720628241 cdef int64_t _tz_convert_tzlocal_utc(int64_t val, tzinfo tz, bint to_utc=True, - bint* fold=NULL): + bint* fold=NULL) except? -1: """ Convert the i8 representation of a datetime from a tzlocal timezone to UTC, or vice-versa. From 0a167112a090fb68c5fce74a3cc9a897bf0c1044 Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 6 Nov 2020 08:17:52 -0800 Subject: [PATCH 2/6] catch higher --- pandas/_libs/tslibs/tzconversion.pxd | 4 +++- pandas/_libs/tslibs/tzconversion.pyx | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pandas/_libs/tslibs/tzconversion.pxd b/pandas/_libs/tslibs/tzconversion.pxd index 1990afd77a8fb..3666d00707ac8 100644 --- a/pandas/_libs/tslibs/tzconversion.pxd +++ b/pandas/_libs/tslibs/tzconversion.pxd @@ -2,7 +2,9 @@ from cpython.datetime cimport tzinfo from numpy cimport int64_t -cdef int64_t tz_convert_utc_to_tzlocal(int64_t utc_val, tzinfo tz, bint* fold=*) +cdef int64_t tz_convert_utc_to_tzlocal( + int64_t utc_val, tzinfo tz, bint* fold=* +) except? -1 cpdef int64_t tz_convert_from_utc_single(int64_t val, tzinfo tz) cdef int64_t tz_localize_to_utc_single( int64_t val, tzinfo tz, object ambiguous=*, object nonexistent=* diff --git a/pandas/_libs/tslibs/tzconversion.pyx b/pandas/_libs/tslibs/tzconversion.pyx index d23e04e867bde..f08a86b1262e6 100644 --- a/pandas/_libs/tslibs/tzconversion.pyx +++ b/pandas/_libs/tslibs/tzconversion.pyx @@ -355,7 +355,9 @@ cdef inline str _render_tstamp(int64_t val): # ---------------------------------------------------------------------- # Timezone Conversion -cdef int64_t tz_convert_utc_to_tzlocal(int64_t utc_val, tzinfo tz, bint* fold=NULL): +cdef int64_t tz_convert_utc_to_tzlocal( + int64_t utc_val, tzinfo tz, bint* fold=NULL +) except? -1: """ Parameters ---------- From 0b362a7bfcd504e179b4aa9b04209c34695c7ad7 Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 6 Nov 2020 10:18:42 -0800 Subject: [PATCH 3/6] catch higher --- pandas/_libs/tslibs/conversion.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index 3b52b4d499694..5a7885686c194 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -681,7 +681,8 @@ cdef inline check_overflows(_TSObject obj): # ---------------------------------------------------------------------- # Localization -cdef inline void _localize_tso(_TSObject obj, tzinfo tz): +# Catch OSError issued via tzlocal +cdef inline void _localize_tso(_TSObject obj, tzinfo tz) except? -1: """ Given the UTC nanosecond timestamp in obj.value, find the wall-clock representation of that timestamp in the given timezone. From 58fff69a6a81d0cd123927eef8f910bf22061818 Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 6 Nov 2020 10:37:33 -0800 Subject: [PATCH 4/6] revert --- pandas/_libs/tslibs/conversion.pyx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index 5a7885686c194..3b52b4d499694 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -681,8 +681,7 @@ cdef inline check_overflows(_TSObject obj): # ---------------------------------------------------------------------- # Localization -# Catch OSError issued via tzlocal -cdef inline void _localize_tso(_TSObject obj, tzinfo tz) except? -1: +cdef inline void _localize_tso(_TSObject obj, tzinfo tz): """ Given the UTC nanosecond timestamp in obj.value, find the wall-clock representation of that timestamp in the given timezone. From 102401a3d827bb5e5adaae3733dac8ca4ea69111 Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 6 Nov 2020 13:39:33 -0800 Subject: [PATCH 5/6] xfail 32bit tests --- pandas/tests/indexes/datetimes/test_ops.py | 40 +++++++++++--------- pandas/tests/tseries/offsets/test_offsets.py | 4 ++ 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/pandas/tests/indexes/datetimes/test_ops.py b/pandas/tests/indexes/datetimes/test_ops.py index 1d64fde103e9e..0359ee17f87c5 100644 --- a/pandas/tests/indexes/datetimes/test_ops.py +++ b/pandas/tests/indexes/datetimes/test_ops.py @@ -1,8 +1,11 @@ from datetime import datetime +from dateutil.tz import tzlocal import numpy as np import pytest +from pandas.compat import IS64 + import pandas as pd from pandas import ( DateOffset, @@ -106,24 +109,27 @@ def test_repeat(self, tz_naive_fixture): with pytest.raises(ValueError, match=msg): np.repeat(rng, reps, axis=1) - def test_resolution(self, tz_naive_fixture): + @pytest.mark.parametrize( + "freq,expected", + [ + ("A", "day"), + ("Q", "day"), + ("M", "day"), + ("D", "day"), + ("H", "hour"), + ("T", "minute"), + ("S", "second"), + ("L", "millisecond"), + ("U", "microsecond"), + ], + ) + def test_resolution(self, tz_naive_fixture, freq, expected): tz = tz_naive_fixture - for freq, expected in zip( - ["A", "Q", "M", "D", "H", "T", "S", "L", "U"], - [ - "day", - "day", - "day", - "day", - "hour", - "minute", - "second", - "millisecond", - "microsecond", - ], - ): - idx = pd.date_range(start="2013-04-01", periods=30, freq=freq, tz=tz) - assert idx.resolution == expected + if freq == "A" and not IS64 and isinstance(tz, tzlocal): + pytest.xfail(reason="OverflowError inside tzlocal past 2038") + + idx = pd.date_range(start="2013-04-01", periods=30, freq=freq, tz=tz) + assert idx.resolution == expected def test_value_counts_unique(self, tz_naive_fixture): tz = tz_naive_fixture diff --git a/pandas/tests/tseries/offsets/test_offsets.py b/pandas/tests/tseries/offsets/test_offsets.py index fba123e47feb2..fca1316493e85 100644 --- a/pandas/tests/tseries/offsets/test_offsets.py +++ b/pandas/tests/tseries/offsets/test_offsets.py @@ -1,6 +1,7 @@ from datetime import date, datetime, time as dt_time, timedelta from typing import Dict, List, Optional, Tuple, Type +from dateutil.tz import tzlocal import numpy as np import pytest @@ -14,6 +15,7 @@ import pandas._libs.tslibs.offsets as liboffsets from pandas._libs.tslibs.offsets import ApplyTypeError, _get_offset, _offset_map from pandas._libs.tslibs.period import INVALID_FREQ_ERR_MSG +from pandas.compat import IS64 from pandas.compat.numpy import np_datetime64_compat from pandas.errors import PerformanceWarning @@ -129,6 +131,8 @@ def test_apply_out_of_range(self, tz_naive_fixture): tz = tz_naive_fixture if self._offset is None: return + if isinstance(tz, tzlocal) and not IS64: + pytest.xfail(reason="OverflowError inside tzlocal past 2038") # try to create an out-of-bounds result timestamp; if we can't create # the offset skip From ceb7078e963dd972f5b362fa77b94c219992a53b Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 6 Nov 2020 14:30:27 -0800 Subject: [PATCH 6/6] xfail on windows --- pandas/tests/frame/test_reductions.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pandas/tests/frame/test_reductions.py b/pandas/tests/frame/test_reductions.py index fbb51b70d34fd..374d185f45844 100644 --- a/pandas/tests/frame/test_reductions.py +++ b/pandas/tests/frame/test_reductions.py @@ -1,9 +1,11 @@ from datetime import timedelta from decimal import Decimal +from dateutil.tz import tzlocal import numpy as np import pytest +from pandas.compat import is_platform_windows import pandas.util._test_decorators as td import pandas as pd @@ -1172,6 +1174,12 @@ def test_min_max_dt64_with_NaT(self): def test_min_max_dt64_with_NaT_skipna_false(self, tz_naive_fixture): # GH#36907 tz = tz_naive_fixture + if isinstance(tz, tzlocal) and is_platform_windows(): + pytest.xfail( + reason="GH#37659 OSError raised within tzlocal bc Windows " + "chokes in times before 1970-01-01" + ) + df = DataFrame( { "a": [