Skip to content

TST: 26807 split pandas/tests/tseries/offsets/test_offsets.py into multiple smaller test modules #38924

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 3 commits into from
Jan 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 172 additions & 1 deletion pandas/tests/tseries/offsets/common.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
"""
Assertion helpers for offsets tests
Assertion helpers and base class for offsets tests
"""
from datetime import datetime
from typing import Optional, Type

from dateutil.tz.tz import tzlocal
import pytest

from pandas._libs.tslibs import OutOfBoundsDatetime, Timestamp
from pandas._libs.tslibs.offsets import (
FY5253,
BusinessHour,
CustomBusinessHour,
DateOffset,
FY5253Quarter,
LastWeekOfMonth,
Week,
WeekOfMonth,
)
from pandas.compat import IS64


def assert_offset_equal(offset, base, expected):
Expand All @@ -24,3 +42,156 @@ def assert_is_on_offset(offset, date, expected):
f"\nExpected: {expected}\nActual: {actual}\nFor Offset: {offset})"
f"\nAt Date: {date}"
)


class WeekDay:
MON = 0
TUE = 1
WED = 2
THU = 3
FRI = 4
SAT = 5
SUN = 6


class Base:
_offset: Optional[Type[DateOffset]] = None
d = Timestamp(datetime(2008, 1, 2))

timezones = [
None,
"UTC",
"Asia/Tokyo",
"US/Eastern",
"dateutil/Asia/Tokyo",
"dateutil/US/Pacific",
]

def _get_offset(self, klass, value=1, normalize=False):
# create instance from offset class
if klass is FY5253:
klass = klass(
n=value,
startingMonth=1,
weekday=1,
variation="last",
normalize=normalize,
)
elif klass is FY5253Quarter:
klass = klass(
n=value,
startingMonth=1,
weekday=1,
qtr_with_extra_week=1,
variation="last",
normalize=normalize,
)
elif klass is LastWeekOfMonth:
klass = klass(n=value, weekday=5, normalize=normalize)
elif klass is WeekOfMonth:
klass = klass(n=value, week=1, weekday=5, normalize=normalize)
elif klass is Week:
klass = klass(n=value, weekday=5, normalize=normalize)
elif klass is DateOffset:
klass = klass(days=value, normalize=normalize)
else:
klass = klass(value, normalize=normalize)
return klass

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
try:
if self._offset in (BusinessHour, CustomBusinessHour):
# Using 10000 in BusinessHour fails in tz check because of DST
# difference
offset = self._get_offset(self._offset, value=100000)
else:
offset = self._get_offset(self._offset, value=10000)

result = Timestamp("20080101") + offset
assert isinstance(result, datetime)
assert result.tzinfo is None

# Check tz is preserved
t = Timestamp("20080101", tz=tz)
result = t + offset
assert isinstance(result, datetime)
assert t.tzinfo == result.tzinfo

except OutOfBoundsDatetime:
pass
except (ValueError, KeyError):
# we are creating an invalid offset
# so ignore
pass

def test_offsets_compare_equal(self):
# root cause of GH#456: __ne__ was not implemented
if self._offset is None:
return
offset1 = self._offset()
offset2 = self._offset()
assert not offset1 != offset2
assert offset1 == offset2

def test_rsub(self):
if self._offset is None or not hasattr(self, "offset2"):
# i.e. skip for TestCommon and YQM subclasses that do not have
# offset2 attr
return
assert self.d - self.offset2 == (-self.offset2).apply(self.d)

def test_radd(self):
if self._offset is None or not hasattr(self, "offset2"):
# i.e. skip for TestCommon and YQM subclasses that do not have
# offset2 attr
return
assert self.d + self.offset2 == self.offset2 + self.d

def test_sub(self):
if self._offset is None or not hasattr(self, "offset2"):
# i.e. skip for TestCommon and YQM subclasses that do not have
# offset2 attr
return
off = self.offset2
msg = "Cannot subtract datetime from offset"
with pytest.raises(TypeError, match=msg):
off - self.d

assert 2 * off - off == off
assert self.d - self.offset2 == self.d + self._offset(-2)
assert self.d - self.offset2 == self.d - (2 * off - off)

def testMult1(self):
if self._offset is None or not hasattr(self, "offset1"):
# i.e. skip for TestCommon and YQM subclasses that do not have
# offset1 attr
return
assert self.d + 10 * self.offset1 == self.d + self._offset(10)
assert self.d + 5 * self.offset1 == self.d + self._offset(5)

def testMult2(self):
if self._offset is None:
return
assert self.d + (-5 * self._offset(-10)) == self.d + self._offset(50)
assert self.d + (-3 * self._offset(-2)) == self.d + self._offset(6)

def test_compare_str(self):
# GH#23524
# comparing to strings that cannot be cast to DateOffsets should
# not raise for __eq__ or __ne__
if self._offset is None:
return
off = self._get_offset(self._offset)

assert not off == "infer"
assert off != "foo"
# Note: inequalities are only implemented for Tick subclasses;
# tests for this are in test_ticks
Loading