13
13
be added to the array-specific tests in `pandas/tests/arrays/`.
14
14
15
15
"""
16
+ from __future__ import annotations
17
+
16
18
import string
19
+ from typing import cast
17
20
18
21
import numpy as np
19
22
import pytest
@@ -90,7 +93,7 @@ def data_for_grouping(dtype, chunked):
90
93
return maybe_split_array (arr , chunked )
91
94
92
95
93
- class TestDtype (base .BaseDtypeTests ):
96
+ class TestStringArray (base .ExtensionTests ):
94
97
def test_eq_with_str (self , dtype ):
95
98
assert dtype == f"string[{ dtype .storage } ]"
96
99
super ().test_eq_with_str (dtype )
@@ -100,43 +103,25 @@ def test_is_not_string_type(self, dtype):
100
103
# because StringDtype is a string type
101
104
assert is_string_dtype (dtype )
102
105
103
-
104
- class TestInterface (base .BaseInterfaceTests ):
105
106
def test_view (self , data , request , arrow_string_storage ):
106
107
if data .dtype .storage in arrow_string_storage :
107
108
pytest .skip (reason = "2D support not implemented for ArrowStringArray" )
108
109
super ().test_view (data )
109
110
110
-
111
- class TestConstructors (base .BaseConstructorsTests ):
112
111
def test_from_dtype (self , data ):
113
112
# base test uses string representation of dtype
114
113
pass
115
114
116
-
117
- class TestReshaping (base .BaseReshapingTests ):
118
115
def test_transpose (self , data , request , arrow_string_storage ):
119
116
if data .dtype .storage in arrow_string_storage :
120
117
pytest .skip (reason = "2D support not implemented for ArrowStringArray" )
121
118
super ().test_transpose (data )
122
119
123
-
124
- class TestGetitem (base .BaseGetitemTests ):
125
- pass
126
-
127
-
128
- class TestSetitem (base .BaseSetitemTests ):
129
120
def test_setitem_preserves_views (self , data , request , arrow_string_storage ):
130
121
if data .dtype .storage in arrow_string_storage :
131
122
pytest .skip (reason = "2D support not implemented for ArrowStringArray" )
132
123
super ().test_setitem_preserves_views (data )
133
124
134
-
135
- class TestIndex (base .BaseIndexTests ):
136
- pass
137
-
138
-
139
- class TestMissing (base .BaseMissingTests ):
140
125
def test_dropna_array (self , data_missing ):
141
126
result = data_missing .dropna ()
142
127
expected = data_missing [[1 ]]
@@ -154,51 +139,80 @@ def test_fillna_no_op_returns_copy(self, data):
154
139
assert result is not data
155
140
tm .assert_extension_array_equal (result , data )
156
141
142
+ def _get_expected_exception (
143
+ self , op_name : str , obj , other
144
+ ) -> type [Exception ] | None :
145
+ if op_name in ["__divmod__" , "__rdivmod__" ]:
146
+ if isinstance (obj , pd .Series ) and cast (
147
+ StringDtype , tm .get_dtype (obj )
148
+ ).storage in [
149
+ "pyarrow" ,
150
+ "pyarrow_numpy" ,
151
+ ]:
152
+ # TODO: re-raise as TypeError?
153
+ return NotImplementedError
154
+ elif isinstance (other , pd .Series ) and cast (
155
+ StringDtype , tm .get_dtype (other )
156
+ ).storage in [
157
+ "pyarrow" ,
158
+ "pyarrow_numpy" ,
159
+ ]:
160
+ # TODO: re-raise as TypeError?
161
+ return NotImplementedError
162
+ return TypeError
163
+ elif op_name in ["__mod__" , "__rmod__" , "__pow__" , "__rpow__" ]:
164
+ if cast (StringDtype , tm .get_dtype (obj )).storage in [
165
+ "pyarrow" ,
166
+ "pyarrow_numpy" ,
167
+ ]:
168
+ return NotImplementedError
169
+ return TypeError
170
+ elif op_name in ["__mul__" , "__rmul__" ]:
171
+ # Can only multiply strings by integers
172
+ return TypeError
173
+ elif op_name in [
174
+ "__truediv__" ,
175
+ "__rtruediv__" ,
176
+ "__floordiv__" ,
177
+ "__rfloordiv__" ,
178
+ "__sub__" ,
179
+ "__rsub__" ,
180
+ ]:
181
+ if cast (StringDtype , tm .get_dtype (obj )).storage in [
182
+ "pyarrow" ,
183
+ "pyarrow_numpy" ,
184
+ ]:
185
+ import pyarrow as pa
186
+
187
+ # TODO: better to re-raise as TypeError?
188
+ return pa .ArrowNotImplementedError
189
+ return TypeError
190
+
191
+ return None
157
192
158
- class TestReduce (base .BaseReduceTests ):
159
193
def _supports_reduction (self , ser : pd .Series , op_name : str ) -> bool :
160
194
return (
161
195
op_name in ["min" , "max" ]
162
196
or ser .dtype .storage == "pyarrow_numpy" # type: ignore[union-attr]
163
197
and op_name in ("any" , "all" )
164
198
)
165
199
166
-
167
- class TestMethods (base .BaseMethodsTests ):
168
- pass
169
-
170
-
171
- class TestCasting (base .BaseCastingTests ):
172
- pass
173
-
174
-
175
- class TestComparisonOps (base .BaseComparisonOpsTests ):
176
200
def _cast_pointwise_result (self , op_name : str , obj , other , pointwise_result ):
177
- dtype = tm .get_dtype (obj )
178
- # error: Item "dtype[Any]" of "dtype[Any] | ExtensionDtype" has no
179
- # attribute "storage"
180
- if dtype .storage == "pyarrow" : # type: ignore[union-attr]
181
- cast_to = "boolean[pyarrow]"
182
- elif dtype .storage == "pyarrow_numpy" : # type: ignore[union-attr]
201
+ dtype = cast ( StringDtype , tm .get_dtype (obj ) )
202
+ if op_name in [ "__add__" , "__radd__" ]:
203
+ cast_to = dtype
204
+ elif dtype .storage == "pyarrow" :
205
+ cast_to = "boolean[pyarrow]" # type: ignore[assignment]
206
+ elif dtype .storage == "pyarrow_numpy" :
183
207
cast_to = np .bool_ # type: ignore[assignment]
184
208
else :
185
- cast_to = "boolean"
209
+ cast_to = "boolean" # type: ignore[assignment]
186
210
return pointwise_result .astype (cast_to )
187
211
188
212
def test_compare_scalar (self , data , comparison_op ):
189
213
ser = pd .Series (data )
190
214
self ._compare_other (ser , data , comparison_op , "abc" )
191
215
192
-
193
- class TestParsing (base .BaseParsingTests ):
194
- pass
195
-
196
-
197
- class TestPrinting (base .BasePrintingTests ):
198
- pass
199
-
200
-
201
- class TestGroupBy (base .BaseGroupbyTests ):
202
216
@pytest .mark .filterwarnings ("ignore:Falling back:pandas.errors.PerformanceWarning" )
203
217
def test_groupby_extension_apply (self , data_for_grouping , groupby_apply_op ):
204
218
super ().test_groupby_extension_apply (data_for_grouping , groupby_apply_op )
0 commit comments