@@ -227,9 +227,72 @@ def test_maybe_promote_float_with_int(float_dtype, any_int_dtype, box):
227
227
)
228
228
229
229
230
- def test_maybe_promote_float_with_float ():
231
- # placeholder due to too many xfails; see GH 23982 / 25425
232
- pass
230
+ @pytest .mark .parametrize (
231
+ "dtype, fill_value, expected_dtype" ,
232
+ [
233
+ # float filled with float
234
+ ("float32" , 1 , "float32" ),
235
+ ("float32" , np .finfo ("float32" ).max * 1.1 , "float64" ),
236
+ ("float64" , 1 , "float64" ),
237
+ ("float64" , np .finfo ("float32" ).max * 1.1 , "float64" ),
238
+ # complex filled with float
239
+ ("complex64" , 1 , "complex64" ),
240
+ ("complex64" , np .finfo ("float32" ).max * 1.1 , "complex128" ),
241
+ ("complex128" , 1 , "complex128" ),
242
+ ("complex128" , np .finfo ("float32" ).max * 1.1 , "complex128" ),
243
+ # float filled with complex
244
+ ("float32" , 1 + 1j , "complex64" ),
245
+ ("float32" , np .finfo ("float32" ).max * (1.1 + 1j ), "complex128" ),
246
+ ("float64" , 1 + 1j , "complex128" ),
247
+ ("float64" , np .finfo ("float32" ).max * (1.1 + 1j ), "complex128" ),
248
+ # complex filled with complex
249
+ ("complex64" , 1 + 1j , "complex64" ),
250
+ ("complex64" , np .finfo ("float32" ).max * (1.1 + 1j ), "complex128" ),
251
+ ("complex128" , 1 + 1j , "complex128" ),
252
+ ("complex128" , np .finfo ("float32" ).max * (1.1 + 1j ), "complex128" ),
253
+ ],
254
+ )
255
+ def test_maybe_promote_float_with_float (dtype , fill_value , expected_dtype , box ):
256
+
257
+ dtype = np .dtype (dtype )
258
+ expected_dtype = np .dtype (expected_dtype )
259
+ boxed , box_dtype = box # read from parametrized fixture
260
+
261
+ if box_dtype == object :
262
+ pytest .xfail ("falsely upcasts to object" )
263
+ if boxed and is_float_dtype (dtype ) and is_complex_dtype (expected_dtype ):
264
+ pytest .xfail ("does not upcast to complex" )
265
+ if (dtype , expected_dtype ) in [
266
+ ("float32" , "float64" ),
267
+ ("float32" , "complex64" ),
268
+ ("complex64" , "complex128" ),
269
+ ]:
270
+ pytest .xfail ("does not upcast correctly depending on value" )
271
+ # this following xfails are "only" a consequence of the - now strictly
272
+ # enforced - principle that maybe_promote_with_scalar always casts
273
+ if not boxed and abs (fill_value ) < 2 :
274
+ pytest .xfail ("wrong return type of fill_value" )
275
+ if (
276
+ not boxed
277
+ and dtype == "complex128"
278
+ and expected_dtype == "complex128"
279
+ and is_float_dtype (type (fill_value ))
280
+ ):
281
+ pytest .xfail ("wrong return type of fill_value" )
282
+
283
+ # output is not a generic float, but corresponds to expected_dtype
284
+ exp_val_for_scalar = np .array ([fill_value ], dtype = expected_dtype )[0 ]
285
+ exp_val_for_array = np .nan
286
+
287
+ _check_promote (
288
+ dtype ,
289
+ fill_value ,
290
+ boxed ,
291
+ box_dtype ,
292
+ expected_dtype ,
293
+ exp_val_for_scalar ,
294
+ exp_val_for_array ,
295
+ )
233
296
234
297
235
298
def test_maybe_promote_bool_with_any (any_numpy_dtype_reduced , box ):
@@ -300,9 +363,45 @@ def test_maybe_promote_any_with_bytes():
300
363
pass
301
364
302
365
303
- def test_maybe_promote_datetime64_with_any ():
304
- # placeholder due to too many xfails; see GH 23982 / 25425
305
- pass
366
+ def test_maybe_promote_datetime64_with_any (
367
+ datetime64_dtype , any_numpy_dtype_reduced , box
368
+ ):
369
+ dtype = np .dtype (datetime64_dtype )
370
+ fill_dtype = np .dtype (any_numpy_dtype_reduced )
371
+ boxed , box_dtype = box # read from parametrized fixture
372
+
373
+ if is_datetime64_dtype (fill_dtype ):
374
+ if box_dtype == object :
375
+ pytest .xfail ("falsely upcasts to object" )
376
+ else :
377
+ if boxed and box_dtype is None :
378
+ pytest .xfail ("does not upcast to object" )
379
+ if not boxed :
380
+ pytest .xfail ("does not upcast to object or raises" )
381
+
382
+ # create array of given dtype; casts "1" to correct dtype
383
+ fill_value = np .array ([1 ], dtype = fill_dtype )[0 ]
384
+
385
+ # filling datetime with anything but datetime casts to object
386
+ if is_datetime64_dtype (fill_dtype ):
387
+ expected_dtype = dtype
388
+ # for datetime dtypes, scalar values get cast to to_datetime64
389
+ exp_val_for_scalar = pd .Timestamp (fill_value ).to_datetime64 ()
390
+ exp_val_for_array = np .datetime64 ("NaT" , "ns" )
391
+ else :
392
+ expected_dtype = np .dtype (object )
393
+ exp_val_for_scalar = fill_value
394
+ exp_val_for_array = np .nan
395
+
396
+ _check_promote (
397
+ dtype ,
398
+ fill_value ,
399
+ boxed ,
400
+ box_dtype ,
401
+ expected_dtype ,
402
+ exp_val_for_scalar ,
403
+ exp_val_for_array ,
404
+ )
306
405
307
406
308
407
# override parametrization of box to add special case for dt_dtype
@@ -505,9 +604,45 @@ def test_maybe_promote_any_numpy_dtype_with_datetimetz(
505
604
)
506
605
507
606
508
- def test_maybe_promote_timedelta64_with_any ():
509
- # placeholder due to too many xfails; see GH 23982 / 25425
510
- pass
607
+ def test_maybe_promote_timedelta64_with_any (
608
+ timedelta64_dtype , any_numpy_dtype_reduced , box
609
+ ):
610
+ dtype = np .dtype (timedelta64_dtype )
611
+ fill_dtype = np .dtype (any_numpy_dtype_reduced )
612
+ boxed , box_dtype = box # read from parametrized fixture
613
+
614
+ if is_timedelta64_dtype (fill_dtype ):
615
+ if box_dtype == object :
616
+ pytest .xfail ("falsely upcasts to object" )
617
+ else :
618
+ if boxed and box_dtype is None :
619
+ pytest .xfail ("does not upcast to object" )
620
+ if not boxed :
621
+ pytest .xfail ("does not upcast to object or raises" )
622
+
623
+ # create array of given dtype; casts "1" to correct dtype
624
+ fill_value = np .array ([1 ], dtype = fill_dtype )[0 ]
625
+
626
+ # filling timedelta with anything but timedelta casts to object
627
+ if is_timedelta64_dtype (fill_dtype ):
628
+ expected_dtype = dtype
629
+ # for timedelta dtypes, scalar values get cast to pd.Timedelta.value
630
+ exp_val_for_scalar = pd .Timedelta (fill_value ).to_timedelta64 ()
631
+ exp_val_for_array = np .timedelta64 ("NaT" , "ns" )
632
+ else :
633
+ expected_dtype = np .dtype (object )
634
+ exp_val_for_scalar = fill_value
635
+ exp_val_for_array = np .nan
636
+
637
+ _check_promote (
638
+ dtype ,
639
+ fill_value ,
640
+ boxed ,
641
+ box_dtype ,
642
+ expected_dtype ,
643
+ exp_val_for_scalar ,
644
+ exp_val_for_array ,
645
+ )
511
646
512
647
513
648
@pytest .mark .parametrize (
0 commit comments