@@ -227,9 +227,72 @@ def test_maybe_promote_float_with_int(float_dtype, any_int_dtype, box):
227227 )
228228
229229
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+ )
233296
234297
235298def test_maybe_promote_bool_with_any (any_numpy_dtype_reduced , box ):
@@ -300,9 +363,45 @@ def test_maybe_promote_any_with_bytes():
300363 pass
301364
302365
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+ )
306405
307406
308407# override parametrization of box to add special case for dt_dtype
@@ -505,9 +604,45 @@ def test_maybe_promote_any_numpy_dtype_with_datetimetz(
505604 )
506605
507606
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+ )
511646
512647
513648@pytest .mark .parametrize (
0 commit comments