4
4
from numpy import iinfo
5
5
import pytest
6
6
7
+ import pandas .compat as compat
8
+
7
9
import pandas as pd
8
10
from pandas import DataFrame , Index , Series , to_numeric
9
11
from pandas .util import testing as tm
@@ -172,7 +174,11 @@ def test_all_nan():
172
174
tm .assert_series_equal (result , expected )
173
175
174
176
175
- @pytest .mark .parametrize ("errors" , [None , "ignore" , "raise" , "coerce" ])
177
+ @pytest .fixture (params = [None , "ignore" , "raise" , "coerce" ])
178
+ def errors (request ):
179
+ return request .param
180
+
181
+
176
182
def test_type_check (errors ):
177
183
# see gh-11776
178
184
df = DataFrame ({"a" : [1 , - 3.14 , 7 ], "b" : ["4" , "5" , "6" ]})
@@ -183,11 +189,123 @@ def test_type_check(errors):
183
189
to_numeric (df , ** kwargs )
184
190
185
191
186
- @pytest .mark .parametrize ("val" , [
187
- 1 , 1.1 , "1" , "1.1" , - 1.5 , "-1.5"
192
+ @pytest .fixture (params = [True , False ])
193
+ def signed (request ):
194
+ return request .param
195
+
196
+
197
+ @pytest .fixture (params = [lambda x : x , str ], ids = ["identity" , "str" ])
198
+ def transform (request ):
199
+ return request .param
200
+
201
+
202
+ @pytest .mark .parametrize ("val" , [1 , 1.1 , 20001 ])
203
+ def test_scalar (val , signed , transform ):
204
+ val = - val if signed else val
205
+ assert to_numeric (transform (val )) == float (val )
206
+
207
+
208
+ @pytest .fixture (params = [
209
+ 47393996303418497800 ,
210
+ 100000000000000000000
188
211
])
189
- def test_scalar (val ):
190
- assert to_numeric (val ) == float (val )
212
+ def large_val (request ):
213
+ return request .param
214
+
215
+
216
+ def test_really_large_scalar (large_val , signed , transform , errors ):
217
+ # see gh-24910
218
+ kwargs = dict (errors = errors ) if errors is not None else dict ()
219
+ val = - large_val if signed else large_val
220
+
221
+ val = transform (val )
222
+ val_is_string = isinstance (val , str )
223
+
224
+ if val_is_string and errors in (None , "raise" ):
225
+ msg = "Integer out of range. at position 0"
226
+ with pytest .raises (ValueError , match = msg ):
227
+ to_numeric (val , ** kwargs )
228
+ else :
229
+ expected = float (val ) if (errors == "coerce" and
230
+ val_is_string ) else val
231
+ assert tm .assert_almost_equal (to_numeric (val , ** kwargs ), expected )
232
+
233
+
234
+ @pytest .fixture (params = [True , False ])
235
+ def multiple_elts (request ):
236
+ return request .param
237
+
238
+
239
+ def test_really_large_in_arr (large_val , signed , transform ,
240
+ multiple_elts , errors ):
241
+ # see gh-24910
242
+ kwargs = dict (errors = errors ) if errors is not None else dict ()
243
+ val = - large_val if signed else large_val
244
+ val = transform (val )
245
+
246
+ extra_elt = "string"
247
+ arr = [val ] + multiple_elts * [extra_elt ]
248
+
249
+ val_is_string = isinstance (val , str )
250
+ coercing = errors == "coerce"
251
+
252
+ if errors in (None , "raise" ) and (val_is_string or multiple_elts ):
253
+ if val_is_string :
254
+ msg = "Integer out of range. at position 0"
255
+ else :
256
+ msg = 'Unable to parse string "string" at position 1'
257
+
258
+ with pytest .raises (ValueError , match = msg ):
259
+ to_numeric (arr , ** kwargs )
260
+ else :
261
+ result = to_numeric (arr , ** kwargs )
262
+
263
+ exp_val = float (val ) if (coercing and val_is_string ) else val
264
+ expected = [exp_val ]
265
+
266
+ if multiple_elts :
267
+ if coercing :
268
+ expected .append (np .nan )
269
+ exp_dtype = float
270
+ else :
271
+ expected .append (extra_elt )
272
+ exp_dtype = object
273
+ else :
274
+ exp_dtype = float if isinstance (exp_val , (
275
+ int , compat .long , float )) else object
276
+
277
+ tm .assert_almost_equal (result , np .array (expected , dtype = exp_dtype ))
278
+
279
+
280
+ def test_really_large_in_arr_consistent (large_val , signed ,
281
+ multiple_elts , errors ):
282
+ # see gh-24910
283
+ #
284
+ # Even if we discover that we have to hold float, does not mean
285
+ # we should be lenient on subsequent elements that fail to be integer.
286
+ kwargs = dict (errors = errors ) if errors is not None else dict ()
287
+ arr = [str (- large_val if signed else large_val )]
288
+
289
+ if multiple_elts :
290
+ arr .insert (0 , large_val )
291
+
292
+ if errors in (None , "raise" ):
293
+ index = int (multiple_elts )
294
+ msg = "Integer out of range. at position {index}" .format (index = index )
295
+
296
+ with pytest .raises (ValueError , match = msg ):
297
+ to_numeric (arr , ** kwargs )
298
+ else :
299
+ result = to_numeric (arr , ** kwargs )
300
+
301
+ if errors == "coerce" :
302
+ expected = [float (i ) for i in arr ]
303
+ exp_dtype = float
304
+ else :
305
+ expected = arr
306
+ exp_dtype = object
307
+
308
+ tm .assert_almost_equal (result , np .array (expected , dtype = exp_dtype ))
191
309
192
310
193
311
@pytest .mark .parametrize ("errors,checker" , [
0 commit comments