1
1
""" Test Matrix for arithmetic operations on DatetimeIndex, TimedeltaIndex,
2
2
and PeriodIndex
3
3
"""
4
+ from datetime import datetime , timedelta
4
5
5
6
import pytest
7
+ import numpy as np
6
8
7
9
import pandas as pd
8
10
from pandas import Timestamp , Timedelta , NaT
9
11
12
+ tdinat = pd .to_timedelta (['24658 days 11:15:00' , 'NaT' ])
13
+ tdimax = pd .to_timedelta (['24658 days 11:15:00' , Timedelta .max ])
14
+ tdimin = pd .to_timedelta (['24658 days 11:15:00' , Timedelta .min ])
15
+
16
+ dtinat = pd .to_datetime (['now' , 'NaT' ])
17
+ dtimax = pd .to_datetime (['now' , Timestamp .max ])
18
+ dtimin = pd .to_datetime (['now' , Timestamp .min ])
19
+
20
+
21
+ tspos = Timestamp ('1980-01-01' )
22
+ ts_pos_variants = [tspos ,
23
+ datetime (1980 , 1 , 1 ),
24
+ np .datetime64 ('1980-01-01' ).astype ('M8[ns]' ),
25
+ np .datetime64 ('1980-01-01' ).astype ('M8[D]' )]
26
+
27
+ tsneg = Timestamp ('1950-01-01' )
28
+ ts_neg_variants = [tsneg ,
29
+ datetime (1950 , 1 , 1 ),
30
+ np .datetime64 ('1950-01-01' ).astype ('M8[ns]' ),
31
+ np .datetime64 ('1950-01-01' ).astype ('M8[D]' )]
32
+
33
+ tdpos = Timedelta ('1h' )
34
+ td_pos_variants = [tdpos ,
35
+ tdpos .to_pytimedelta (),
36
+ tdpos .to_timedelta64 ()]
37
+
38
+ tdneg = Timedelta ('-1h' )
39
+ td_neg_variants = [tdneg ,
40
+ tdneg .to_pytimedelta (),
41
+ tdneg .to_timedelta64 ()]
42
+
10
43
11
44
class TestDatetimeLikeIndexArithmetic (object ):
12
45
# GH17991 checking for overflows and NaT masking on arithmetic ops
@@ -25,159 +58,147 @@ class TestDatetimeLikeIndexArithmetic(object):
25
58
# - object-dtype, categorical dtype
26
59
# - PeriodIndex
27
60
# - consistency with .map(...) ?
61
+ # - versions with near-min/max values
28
62
29
63
def test_timedeltaindex_add_timestamp_nat_masking (self ):
30
- tdinat = pd .to_timedelta (['24658 days 11:15:00' , 'NaT' ])
31
-
32
- # tsneg.value < 0, tspos.value > 0
33
- tsneg = Timestamp ('1950-01-01' )
34
- tspos = Timestamp ('1980-01-01' )
64
+ for variant in ts_neg_variants :
65
+ res = tdinat + variant
66
+ assert res [1 ] is NaT
35
67
36
- res1 = tdinat + tsneg
37
- assert res1 [1 ] is NaT
38
- res2 = tdinat + tspos
39
- assert res2 [1 ] is NaT
68
+ for variant in ts_pos_variants :
69
+ res = tdinat + variant
70
+ assert res [1 ] is NaT
40
71
41
72
def test_timedeltaindex_add_timestamp_overflow (self ):
42
- tdimax = pd .to_timedelta (['24658 days 11:15:00' , Timedelta .max ])
43
- tdimin = pd .to_timedelta (['24658 days 11:15:00' , Timedelta .min ])
44
-
45
- # tsneg.value < 0, tspos.value > 0
46
- tsneg = Timestamp ('1950-01-01' )
47
- tspos = Timestamp ('1980-01-01' )
73
+ expected = Timedelta .max .value + tsneg .value
74
+ for variant in ts_neg_variants :
75
+ res = tdimax + variant
76
+ assert res [1 ].value == expected
48
77
49
- res1 = tdimax + tsneg
50
- assert res1 [ 1 ]. value == Timedelta . max . value + tsneg . value
51
- res2 = tdimin + tspos
52
- assert res2 [1 ].value == Timedelta . min . value + tspos . value
78
+ expected = Timedelta . min . value + tspos . value
79
+ for variant in ts_pos_variants :
80
+ res = tdimin + variant
81
+ assert res [1 ].value == expected
53
82
54
- with pytest .raises (OverflowError ):
55
- tdimax + tspos
83
+ for variant in ts_pos_variants :
84
+ with pytest .raises (OverflowError ):
85
+ tdimax + variant
56
86
57
- with pytest .raises (OverflowError ):
58
- tdimin + tsneg
87
+ for variant in ts_neg_variants :
88
+ with pytest .raises (OverflowError ):
89
+ tdimin + variant
59
90
60
91
def test_timedeltaindex_add_timedelta_overflow (self ):
61
- tdimax = pd .to_timedelta (['24658 days 11:15:00' , Timedelta .max ])
62
- tdimin = pd .to_timedelta (['24658 days 11:15:00' , Timedelta .min ])
92
+ for variant in td_pos_variants :
93
+ with pytest .raises (OverflowError ):
94
+ tdimax + variant
63
95
64
- # tdpos.value > 0, tdneg.value < 0
65
- tdpos = Timedelta ('1h' )
66
- tdneg = Timedelta ('-1h' )
96
+ expected = Timedelta .max .value + tdneg .value
97
+ for variant in td_neg_variants :
98
+ res = tdimax + variant
99
+ assert res [1 ].value == expected
67
100
68
- with pytest .raises (OverflowError ):
69
- tdimax + tdpos
101
+ expected = Timedelta .min .value + tdpos .value
102
+ for variant in td_pos_variants :
103
+ res = tdimin + variant
104
+ assert res [1 ].value == expected
70
105
71
- res2 = tdimax + tdneg
72
- assert res2 [1 ].value == Timedelta .max .value + tdneg .value
73
- res3 = tdimin + tdpos
74
- assert res3 [1 ].value == Timedelta .min .value + tdpos .value
75
-
76
- with pytest .raises (OverflowError ):
77
- tdimin + tdneg
106
+ for variant in td_neg_variants :
107
+ with pytest .raises (OverflowError ):
108
+ tdimin + variant
78
109
79
110
def test_timedeltaindex_sub_timedelta_overflow (self ):
80
- tdimax = pd .to_timedelta (['24658 days 11:15:00' , Timedelta .max ])
81
- tdimin = pd .to_timedelta (['24658 days 11:15:00' , Timedelta .min ])
82
-
83
- # tdpos.value > 0, tdneg.value < 0
84
- tdpos = Timedelta ('1h' )
85
- tdneg = Timedelta ('-1h' )
86
-
87
- res1 = tdimax - tdpos
88
- assert res1 [1 ].value == Timedelta .max .value - tdpos .value
111
+ expected = Timedelta .max .value - tdpos .value
112
+ for variant in td_pos_variants :
113
+ res1 = tdimax - variant
114
+ assert res1 [1 ].value == expected
89
115
90
- with pytest .raises (OverflowError ):
91
- tdimax - tdneg
116
+ for variant in td_neg_variants :
117
+ with pytest .raises (OverflowError ):
118
+ tdimax - variant
92
119
93
- with pytest .raises (OverflowError ):
94
- tdimin - tdpos
120
+ for variant in td_pos_variants :
121
+ with pytest .raises (OverflowError ):
122
+ tdimin - variant
95
123
96
- res4 = tdimin - tdneg
97
- assert res4 [1 ].value == Timedelta .min .value - tdneg .value
124
+ expected = Timedelta .min .value - tdneg .value
125
+ for variant in td_neg_variants :
126
+ res = tdimin - variant
127
+ assert res [1 ].value == expected
98
128
99
129
def test_datetimeindex_add_nat_masking (self ):
100
130
# Checking for NaTs and checking that we don't get an OverflowError
101
- dtinat = pd .to_datetime (['now' , 'NaT' ])
131
+ for variant in td_pos_variants :
132
+ res = dtinat + variant
133
+ assert res [1 ] is NaT
102
134
103
- # tdpos.value > 0, tdneg.value < 0
104
- tdpos = Timedelta ('1h' )
105
- tdneg = Timedelta ('-1h' )
106
-
107
- res1 = dtinat + tdpos
108
- assert res1 [1 ] is NaT
109
- res2 = dtinat + tdneg
110
- assert res2 [1 ] is NaT
135
+ for variant in td_neg_variants :
136
+ res = dtinat + variant
137
+ assert res [1 ] is NaT
111
138
112
139
def test_datetimeindex_sub_nat_masking (self ):
113
140
# Checking for NaTs and checking that we don't get an OverflowError
114
- dtinat = pd .to_datetime (['now' , 'NaT' ])
115
-
116
- # tdpos.value > 0, tdneg.value < 0
117
- tdpos = Timedelta ('1h' )
118
- tdneg = Timedelta ('-1h' )
141
+ for variant in td_pos_variants :
142
+ res = dtinat - variant
143
+ assert res [1 ] is NaT
119
144
120
- res1 = dtinat - tdpos
121
- assert res1 [1 ] is NaT
122
- res2 = dtinat - tdneg
123
- assert res2 [1 ] is NaT
145
+ for variant in td_neg_variants :
146
+ res = dtinat - variant
147
+ assert res [1 ] is NaT
124
148
125
149
def test_datetimeindex_add_timedelta_overflow (self ):
126
- dtimax = pd .to_datetime (['now' , Timestamp .max ])
127
- dtimin = pd .to_datetime (['now' , Timestamp .min ])
128
-
129
- # tdpos.value < 0, tdneg.value > 0
130
- tdpos = Timedelta ('1h' )
131
- tdneg = Timedelta ('-1h' )
150
+ for variant in td_pos_variants :
151
+ with pytest .raises (OverflowError ):
152
+ dtimax + variant
132
153
133
- with pytest .raises (OverflowError ):
134
- dtimax + tdpos
154
+ expected = Timestamp .max .value + tdneg .value
155
+ for variant in td_neg_variants :
156
+ res = dtimax + variant
157
+ assert res [1 ].value == expected
135
158
136
- res2 = dtimax + tdneg
137
- assert res2 [1 ].value == Timestamp .max .value + tdneg .value
159
+ expected = Timestamp .min .value + tdpos .value
160
+ for variant in td_pos_variants :
161
+ res = dtimin + variant
162
+ assert res [1 ].value == expected
138
163
139
- res3 = dtimin + tdpos
140
- assert res3 [1 ].value == Timestamp .min .value + tdpos .value
141
-
142
- with pytest .raises (OverflowError ):
143
- dtimin + tdneg
164
+ for variant in td_neg_variants :
165
+ with pytest .raises (OverflowError ):
166
+ dtimin + variant
144
167
145
168
def test_datetimeindex_sub_timedelta_overflow (self ):
146
- dtimax = pd .to_datetime (['now' , Timestamp .max ])
147
- dtimin = pd .to_datetime (['now' , Timestamp .min ])
148
-
149
- # tdpos.value < 0, tdneg.value > 0
150
- tdpos = Timedelta ('1h' )
151
- tdneg = Timedelta ('-1h' )
152
-
153
- res1 = dtimax - tdpos
154
- assert res1 [1 ].value == Timestamp .max .value - tdpos .value
169
+ expected = Timestamp .max .value - tdpos .value
170
+ for variant in td_pos_variants :
171
+ res = dtimax - variant
172
+ assert res [1 ].value == expected
155
173
156
- with pytest .raises (OverflowError ):
157
- dtimax - tdneg
174
+ for variant in td_neg_variants :
175
+ with pytest .raises (OverflowError ):
176
+ dtimax - variant
158
177
159
- with pytest .raises (OverflowError ):
160
- dtimin - tdpos
178
+ for variant in td_pos_variants :
179
+ with pytest .raises (OverflowError ):
180
+ dtimin - variant
161
181
162
- res4 = dtimin - tdneg
163
- assert res4 [1 ].value == Timestamp .min .value - tdneg .value
182
+ expected = Timestamp .min .value - tdneg .value
183
+ for variant in td_neg_variants :
184
+ res = dtimin - variant
185
+ assert res [1 ].value == expected
164
186
165
187
def test_datetimeindex_sub_timestamp_overflow (self ):
166
- dtimax = pd .to_datetime (['now' , Timestamp .max ])
167
- dtimin = pd .to_datetime (['now' , Timestamp .min ])
168
-
169
- # tsneg.value < 0, tspos.value > 0
170
- tsneg = Timestamp ('1950-01-01' )
171
- tspos = Timestamp ('1980-01-01' )
172
-
173
- with pytest .raises (OverflowError ):
174
- dtimax - tsneg
175
-
176
- res2 = dtimax - tspos
177
- assert res2 [1 ].value == Timestamp .max .value - tspos .value
178
-
179
- res3 = dtimin - tsneg
180
- assert res3 [1 ].value == Timestamp .min .value - tsneg .value
181
-
182
- with pytest .raises (OverflowError ):
183
- dtimin - tspos
188
+ for variant in ts_neg_variants :
189
+ with pytest .raises (OverflowError ):
190
+ dtimax - variant
191
+
192
+ expected = Timestamp .max .value - tspos .value
193
+ for variant in ts_pos_variants :
194
+ res = dtimax - variant
195
+ assert res [1 ].value == expected
196
+
197
+ expected = Timestamp .min .value - tsneg .value
198
+ for variant in ts_neg_variants :
199
+ res = dtimin - variant
200
+ assert res [1 ].value == expected
201
+
202
+ for variant in ts_pos_variants :
203
+ with pytest .raises (OverflowError ):
204
+ dtimin - variant
0 commit comments