Skip to content

Commit 8c9f507

Browse files
moinkluckyvs1
authored andcommitted
TST: 26807 split pandas/tests/tseries/offsets/test_offsets.py into multiple smaller test modules (pandas-dev#38924)
1 parent 610fad4 commit 8c9f507

11 files changed

+3597
-3664
lines changed

pandas/tests/tseries/offsets/common.py

+172-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
"""
2-
Assertion helpers for offsets tests
2+
Assertion helpers and base class for offsets tests
33
"""
4+
from datetime import datetime
5+
from typing import Optional, Type
6+
7+
from dateutil.tz.tz import tzlocal
8+
import pytest
9+
10+
from pandas._libs.tslibs import OutOfBoundsDatetime, Timestamp
11+
from pandas._libs.tslibs.offsets import (
12+
FY5253,
13+
BusinessHour,
14+
CustomBusinessHour,
15+
DateOffset,
16+
FY5253Quarter,
17+
LastWeekOfMonth,
18+
Week,
19+
WeekOfMonth,
20+
)
21+
from pandas.compat import IS64
422

523

624
def assert_offset_equal(offset, base, expected):
@@ -24,3 +42,156 @@ def assert_is_on_offset(offset, date, expected):
2442
f"\nExpected: {expected}\nActual: {actual}\nFor Offset: {offset})"
2543
f"\nAt Date: {date}"
2644
)
45+
46+
47+
class WeekDay:
48+
MON = 0
49+
TUE = 1
50+
WED = 2
51+
THU = 3
52+
FRI = 4
53+
SAT = 5
54+
SUN = 6
55+
56+
57+
class Base:
58+
_offset: Optional[Type[DateOffset]] = None
59+
d = Timestamp(datetime(2008, 1, 2))
60+
61+
timezones = [
62+
None,
63+
"UTC",
64+
"Asia/Tokyo",
65+
"US/Eastern",
66+
"dateutil/Asia/Tokyo",
67+
"dateutil/US/Pacific",
68+
]
69+
70+
def _get_offset(self, klass, value=1, normalize=False):
71+
# create instance from offset class
72+
if klass is FY5253:
73+
klass = klass(
74+
n=value,
75+
startingMonth=1,
76+
weekday=1,
77+
variation="last",
78+
normalize=normalize,
79+
)
80+
elif klass is FY5253Quarter:
81+
klass = klass(
82+
n=value,
83+
startingMonth=1,
84+
weekday=1,
85+
qtr_with_extra_week=1,
86+
variation="last",
87+
normalize=normalize,
88+
)
89+
elif klass is LastWeekOfMonth:
90+
klass = klass(n=value, weekday=5, normalize=normalize)
91+
elif klass is WeekOfMonth:
92+
klass = klass(n=value, week=1, weekday=5, normalize=normalize)
93+
elif klass is Week:
94+
klass = klass(n=value, weekday=5, normalize=normalize)
95+
elif klass is DateOffset:
96+
klass = klass(days=value, normalize=normalize)
97+
else:
98+
klass = klass(value, normalize=normalize)
99+
return klass
100+
101+
def test_apply_out_of_range(self, tz_naive_fixture):
102+
tz = tz_naive_fixture
103+
if self._offset is None:
104+
return
105+
if isinstance(tz, tzlocal) and not IS64:
106+
pytest.xfail(reason="OverflowError inside tzlocal past 2038")
107+
108+
# try to create an out-of-bounds result timestamp; if we can't create
109+
# the offset skip
110+
try:
111+
if self._offset in (BusinessHour, CustomBusinessHour):
112+
# Using 10000 in BusinessHour fails in tz check because of DST
113+
# difference
114+
offset = self._get_offset(self._offset, value=100000)
115+
else:
116+
offset = self._get_offset(self._offset, value=10000)
117+
118+
result = Timestamp("20080101") + offset
119+
assert isinstance(result, datetime)
120+
assert result.tzinfo is None
121+
122+
# Check tz is preserved
123+
t = Timestamp("20080101", tz=tz)
124+
result = t + offset
125+
assert isinstance(result, datetime)
126+
assert t.tzinfo == result.tzinfo
127+
128+
except OutOfBoundsDatetime:
129+
pass
130+
except (ValueError, KeyError):
131+
# we are creating an invalid offset
132+
# so ignore
133+
pass
134+
135+
def test_offsets_compare_equal(self):
136+
# root cause of GH#456: __ne__ was not implemented
137+
if self._offset is None:
138+
return
139+
offset1 = self._offset()
140+
offset2 = self._offset()
141+
assert not offset1 != offset2
142+
assert offset1 == offset2
143+
144+
def test_rsub(self):
145+
if self._offset is None or not hasattr(self, "offset2"):
146+
# i.e. skip for TestCommon and YQM subclasses that do not have
147+
# offset2 attr
148+
return
149+
assert self.d - self.offset2 == (-self.offset2).apply(self.d)
150+
151+
def test_radd(self):
152+
if self._offset is None or not hasattr(self, "offset2"):
153+
# i.e. skip for TestCommon and YQM subclasses that do not have
154+
# offset2 attr
155+
return
156+
assert self.d + self.offset2 == self.offset2 + self.d
157+
158+
def test_sub(self):
159+
if self._offset is None or not hasattr(self, "offset2"):
160+
# i.e. skip for TestCommon and YQM subclasses that do not have
161+
# offset2 attr
162+
return
163+
off = self.offset2
164+
msg = "Cannot subtract datetime from offset"
165+
with pytest.raises(TypeError, match=msg):
166+
off - self.d
167+
168+
assert 2 * off - off == off
169+
assert self.d - self.offset2 == self.d + self._offset(-2)
170+
assert self.d - self.offset2 == self.d - (2 * off - off)
171+
172+
def testMult1(self):
173+
if self._offset is None or not hasattr(self, "offset1"):
174+
# i.e. skip for TestCommon and YQM subclasses that do not have
175+
# offset1 attr
176+
return
177+
assert self.d + 10 * self.offset1 == self.d + self._offset(10)
178+
assert self.d + 5 * self.offset1 == self.d + self._offset(5)
179+
180+
def testMult2(self):
181+
if self._offset is None:
182+
return
183+
assert self.d + (-5 * self._offset(-10)) == self.d + self._offset(50)
184+
assert self.d + (-3 * self._offset(-2)) == self.d + self._offset(6)
185+
186+
def test_compare_str(self):
187+
# GH#23524
188+
# comparing to strings that cannot be cast to DateOffsets should
189+
# not raise for __eq__ or __ne__
190+
if self._offset is None:
191+
return
192+
off = self._get_offset(self._offset)
193+
194+
assert not off == "infer"
195+
assert off != "foo"
196+
# Note: inequalities are only implemented for Tick subclasses;
197+
# tests for this are in test_ticks

0 commit comments

Comments
 (0)