Skip to content

TST: Clean old timezone issues PT2 #21612

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 28, 2018
6 changes: 1 addition & 5 deletions doc/source/whatsnew/v0.23.2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,7 @@ Bug Fixes

- Bug in :class:`Timestamp` and :class:`DatetimeIndex` where passing a :class:`Timestamp` localized after a DST transition would return a datetime before the DST transition (:issue:`20854`)
- Bug in comparing :class:`DataFrame`s with tz-aware :class:`DatetimeIndex` columns with a DST transition that raised a ``KeyError`` (:issue:`19970`)
- Bug in :meth:`DatetimeIndex.shift` where an ``AssertionError`` would raise when shifting across DST (:issue:`8616`)
- Bug in :class:`Timestamp` constructor where passing an invalid timezone offset designator (``Z``) would not raise a ``ValueError``(:issue:`8910`)
- Bug in :meth:`Timestamp.replace` where replacing at a DST boundary would retain an incorrect offset (:issue:`7825`)
- Bug in :meth:`DatetimeIndex.reindex` when reindexing a tz-naive and tz-aware :class:`DatetimeIndex` (:issue:`8306`)
- Bug in :meth:`DatetimeIndex.resample` when downsampling across a DST boundary (:issue:`8531`)


**Other**

Expand Down
15 changes: 12 additions & 3 deletions doc/source/whatsnew/v0.24.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,18 @@ Timedelta
Timezones
^^^^^^^^^

-
-
-
- Bug in :meth:`DatetimeIndex.shift` where an ``AssertionError`` would raise when shifting across DST (:issue:`8616`)
- Bug in :class:`Timestamp` constructor where passing an invalid timezone offset designator (``Z``) would not raise a ``ValueError``(:issue:`8910`)
- Bug in :meth:`Timestamp.replace` where replacing at a DST boundary would retain an incorrect offset (:issue:`7825`)
- Bug in :meth:`DatetimeIndex.reindex` when reindexing a tz-naive and tz-aware :class:`DatetimeIndex` (:issue:`8306`)
- Bug in :meth:`DatetimeIndex.resample` when downsampling across a DST boundary (:issue:`8531`)
- Bug when indexing :class:`DatetimeIndex` with nanosecond resolution dates and timezones (:issue:`11679`)
- Bug in :class:`DataFrame` when setting values with ``loc`` and a timezone aware :class:`DatetimeIndex` (:issue:`11365`)
- Bug in :class:`Timestamp` when passing different string date formats with a timezone offset would produce different timezone offsets (:issue:`12064`)
- Bug when comparing a tz-naive :class:`Timestamp` to a tz-aware :class:`DatetimeIndex` which would coerce the :class:`DatetimeIndex` to tz-naive (:issue:`12601`)
- Bug in :meth:`Series.truncate` with a tz-aware :class:`DatetimeIndex` which would cause a core dump (:issue:`9243`)
- Bug in :meth:`Series.replace` with ``datetime64[ns, tz]`` data when replacing ``NaT`` (:issue:`11792`)
- Bug in :class:`Series` constructor which would coerce tz-aware and tz-naive :class:`Timestamp`s to tz-aware (:issue:`13051`)

Offsets
^^^^^^^
Expand Down
22 changes: 22 additions & 0 deletions pandas/conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import operator

import pytest

import numpy as np
Expand Down Expand Up @@ -249,3 +251,23 @@ def any_int_dtype(request):
"""

return request.param


COMPARISON_OPERATORS = [operator.lt, operator.le, operator.eq, operator.ne,
operator.ge, operator.gt]


@pytest.fixture(params=COMPARISON_OPERATORS)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make this more like this

[email protected](params=['__eq__', '__ne__', '__le__',
+                        '__lt__', '__ge__', '__gt__'])
+def all_compare_operators(request):
+    """
+    Fixture for dunder names for common compare operations
     """

which is much more flexible for non-operators

def comparison_fixture(request):
"""
Parameterized fixture for comparison operators.

* >=
* >
* ==
* !=
* <
* <=
"""

return request.param
24 changes: 24 additions & 0 deletions pandas/tests/frame/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1688,6 +1688,20 @@ def test_getitem_list_duplicates(self):
expected = df.iloc[:, 2:]
assert_frame_equal(result, expected)

def test_getitem_setitem_datetimeindex_tz(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are other tests like this, can you co-locate (IIRC in same file), maybe though in pandas/tests/indexing/....

# GH 11679
data = ['2016-06-28 08:30:00.123456789']
index = DatetimeIndex(data, dtype='datetime64[ns, America/Chicago]')
df = DataFrame({'a': [10]}, index=index)
result = df.loc[df.index[0]]
expected = Series(10, index=['a'], name=df.index[0])
tm.assert_series_equal(result, expected)

result = df.copy()
result.loc[df.index[0], 'a'] = -1
expected = DataFrame(-1, index=index, columns=['a'])
tm.assert_frame_equal(result, expected)

def test_get_value(self):
for idx in self.frame.index:
for col in self.frame.columns:
Expand Down Expand Up @@ -2248,6 +2262,16 @@ def test_setitem_datetimelike_with_inference(self):
index=list('ABCDEFGH'))
assert_series_equal(result, expected)

@pytest.mark.parametrize('idxer', ['var', ['var']])
@pytest.mark.parametrize('tz', [None, 'UTC'])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try to use the tz fixtures if possible

def test_setitem_datetimeindex_tz(self, idxer, tz):
# GH 11365
idx = date_range(start='2015-07-12', periods=3, freq='H', tz=tz)
expected = DataFrame(1.2, index=idx, columns=['var'])
result = DataFrame(index=idx, columns=['var'])
result.loc[:, idxer] = expected
tm.assert_frame_equal(result, expected)

def test_at_time_between_time_datetimeindex(self):
index = date_range("2012-01-01", "2012-01-05", freq='30min')
df = DataFrame(randn(len(index), 5), index=index)
Expand Down
9 changes: 9 additions & 0 deletions pandas/tests/indexes/datetimes/test_date_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,15 @@ def test_construct_over_dst(self):
freq='H', tz='US/Pacific')
tm.assert_index_equal(result, expected)

def test_construct_with_different_start_end_string_format(self):
# GH 12064
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure this is actually testing what is in the issue, as there were provided tz's there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tz aren't provided in these examples via the keyword arg. The issue was that '2013-01-01 00:00:00+09:00' vs '2013/01/01 02:00:00+09:00' (note the - vs the /) ended up produced different tzoffsets

#12064 (comment)

result = date_range('2013-01-01 00:00:00+09:00',
'2013/01/01 02:00:00+09:00', freq='H')
expected = DatetimeIndex([Timestamp('2013-01-01 00:00:00+09:00'),
Timestamp('2013-01-01 01:00:00+09:00'),
Timestamp('2013-01-01 02:00:00+09:00')])
tm.assert_index_equal(result, expected)


class TestGenRangeGeneration(object):

Expand Down
8 changes: 8 additions & 0 deletions pandas/tests/indexes/datetimes/test_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,14 @@ def test_offset_deprecated(self):
with tm.assert_produces_warning(FutureWarning):
idx.offset = BDay()

def test_ts_datetimeindex_compare_mismatched_tz(self, comparison_fixture):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have similar tests, can you co-locate

# GH 12601
comparison = comparison_fixture
idx = date_range('2016-01-01 12:00', periods=10,
freq='H', tz='Asia/Tokyo')
with pytest.raises(TypeError):
comparison(idx, pd.Timestamp('2016-01-01 08:00'))


class TestBusinessDatetimeIndex(object):

Expand Down
8 changes: 8 additions & 0 deletions pandas/tests/scalar/timestamp/test_timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,14 @@ def test_construct_timestamp_near_dst(self, offset):
result = Timestamp(expected, tz='Europe/Helsinki')
assert result == expected

@pytest.mark.parametrize('arg', [
'2013/01/01 00:00:00+09:00', '2013-01-01 00:00:00+09:00'])
def test_construct_with_different_string_format(self, arg):
# GH 12064
result = Timestamp(arg)
expected = Timestamp(datetime(2013, 1, 1), tz=pytz.FixedOffset(540))
assert result == expected


class TestTimestamp(object):

Expand Down
8 changes: 8 additions & 0 deletions pandas/tests/series/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -1185,3 +1185,11 @@ def test_constructor_range_dtype(self, dtype):
expected = Series([0, 1, 2, 3, 4], dtype=dtype or 'int64')
result = Series(range(5), dtype=dtype)
tm.assert_series_equal(result, expected)

def test_constructor_tz_aware_and_tz_naive_data(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

call this tz_mixed

# GH 13051
dt_list = [Timestamp('2016-05-01 02:03:37'),
Timestamp('2016-04-30 19:03:37-0700', tz='US/Pacific')]
result = Series(dt_list)
expected = Series(dt_list, dtype=object)
tm.assert_series_equal(result, expected)
9 changes: 9 additions & 0 deletions pandas/tests/series/test_replace.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,12 @@ def test_replace_mixed_types_with_string(self):
result = s.replace([2, '4'], np.nan)
expected = pd.Series([1, np.nan, 3, np.nan, 4, 5])
tm.assert_series_equal(expected, result)

@pytest.mark.parametrize('to_replace', [pd.NaT, [np.nan, pd.NaT]])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have a fixture for nulls

def test_replace_with_tz_aware_data(self, to_replace):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you tests with tz-naive as well, maybe just have a combined test (as we likely have one for naive)

# GH 11792
ts = pd.Timestamp('2015/01/01', tz='UTC')
s = pd.Series([pd.NaT, pd.Timestamp('2015/01/01', tz='UTC')])
result = s.replace(to_replace, pd.Timestamp.min)
expected = pd.Series([pd.Timestamp.min, ts], dtype=object)
tm.assert_series_equal(expected, result)
8 changes: 8 additions & 0 deletions pandas/tests/series/test_timezones.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,11 @@ def test_getitem_pydatetime_tz(self, tzstr):
dt = datetime(2012, 12, 24, 17, 0)
time_datetime = tslib._localize_pydatetime(dt, tz)
assert ts[time_pandas] == ts[time_datetime]

def test_series_truncate_datetimeindex_tz(self):
# GH 9243
idx = date_range('4/1/2005', '4/30/2005', freq='D', tz='US/Pacific')
s = Series(range(len(idx)), index=idx)
result = s.truncate(datetime(2005, 4, 2), datetime(2005, 4, 4))
expected = Series([1, 2, 3], index=idx[1:4])
tm.assert_series_equal(result, expected)