Skip to content

Commit 9743154

Browse files
jbrockmendeljreback
authored andcommitted
TST: Fix maybe_promote floating non-boxed tests (#28880)
1 parent 4f97ca4 commit 9743154

File tree

2 files changed

+47
-16
lines changed

2 files changed

+47
-16
lines changed

pandas/core/dtypes/cast.py

+45-3
Original file line numberDiff line numberDiff line change
@@ -398,14 +398,30 @@ def maybe_promote(dtype, fill_value=np.nan):
398398
dtype = np.dtype(np.float64)
399399
if not isna(fill_value):
400400
fill_value = dtype.type(fill_value)
401+
402+
elif dtype.kind == "f":
403+
if not np.can_cast(fill_value, dtype):
404+
# e.g. dtype is float32, need float64
405+
dtype = np.min_scalar_type(fill_value)
406+
407+
elif dtype.kind == "c":
408+
if not np.can_cast(fill_value, dtype):
409+
if np.can_cast(fill_value, np.dtype("c16")):
410+
dtype = np.dtype(np.complex128)
411+
else:
412+
dtype = np.dtype(np.object_)
413+
414+
if dtype.kind == "c" and not np.isnan(fill_value):
415+
fill_value = dtype.type(fill_value)
416+
401417
elif is_bool(fill_value):
402418
if not issubclass(dtype.type, np.bool_):
403419
dtype = np.object_
404420
else:
405421
fill_value = np.bool_(fill_value)
406422
elif is_integer(fill_value):
407423
if issubclass(dtype.type, np.bool_):
408-
dtype = np.object_
424+
dtype = np.dtype(np.object_)
409425
elif issubclass(dtype.type, np.integer):
410426
# upcast to prevent overflow
411427
arr = np.asarray(fill_value)
@@ -415,11 +431,37 @@ def maybe_promote(dtype, fill_value=np.nan):
415431
# check if we can cast
416432
if _check_lossless_cast(fill_value, dtype):
417433
fill_value = dtype.type(fill_value)
434+
435+
if dtype.kind in ["c", "f"]:
436+
# e.g. if dtype is complex128 and fill_value is 1, we
437+
# want np.complex128(1)
438+
fill_value = dtype.type(fill_value)
439+
418440
elif is_complex(fill_value):
419441
if issubclass(dtype.type, np.bool_):
420-
dtype = np.object_
442+
dtype = np.dtype(np.object_)
421443
elif issubclass(dtype.type, (np.integer, np.floating)):
422-
dtype = np.complex128
444+
c8 = np.dtype(np.complex64)
445+
info = np.finfo(dtype) if dtype.kind == "f" else np.iinfo(dtype)
446+
if (
447+
np.can_cast(fill_value, c8)
448+
and np.can_cast(info.min, c8)
449+
and np.can_cast(info.max, c8)
450+
):
451+
dtype = np.dtype(np.complex64)
452+
else:
453+
dtype = np.dtype(np.complex128)
454+
455+
elif dtype.kind == "c":
456+
mst = np.min_scalar_type(fill_value)
457+
if mst > dtype and mst.kind == "c":
458+
# e.g. mst is np.complex128 and dtype is np.complex64
459+
dtype = mst
460+
461+
if dtype.kind == "c":
462+
# make sure we have a np.complex and not python complex
463+
fill_value = dtype.type(fill_value)
464+
423465
elif fill_value is None:
424466
if is_float_dtype(dtype) or is_complex_dtype(dtype):
425467
fill_value = np.nan

pandas/tests/dtypes/cast/test_promote.py

+2-13
Original file line numberDiff line numberDiff line change
@@ -408,25 +408,14 @@ def test_maybe_promote_float_with_float(dtype, fill_value, expected_dtype, box):
408408

409409
if box_dtype == object:
410410
pytest.xfail("falsely upcasts to object")
411-
if boxed and is_float_dtype(dtype) and is_complex_dtype(expected_dtype):
411+
elif boxed and is_float_dtype(dtype) and is_complex_dtype(expected_dtype):
412412
pytest.xfail("does not upcast to complex")
413-
if (dtype, expected_dtype) in [
413+
elif boxed and (dtype, expected_dtype) in [
414414
("float32", "float64"),
415415
("float32", "complex64"),
416416
("complex64", "complex128"),
417417
]:
418418
pytest.xfail("does not upcast correctly depending on value")
419-
# this following xfails are "only" a consequence of the - now strictly
420-
# enforced - principle that maybe_promote_with_scalar always casts
421-
if not boxed and abs(fill_value) < 2:
422-
pytest.xfail("wrong return type of fill_value")
423-
if (
424-
not boxed
425-
and dtype == "complex128"
426-
and expected_dtype == "complex128"
427-
and is_float_dtype(type(fill_value))
428-
):
429-
pytest.xfail("wrong return type of fill_value")
430419

431420
# output is not a generic float, but corresponds to expected_dtype
432421
exp_val_for_scalar = np.array([fill_value], dtype=expected_dtype)[0]

0 commit comments

Comments
 (0)