Skip to content

REF: simplify maybe_promote integer cases #28899

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 10, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 3 additions & 46 deletions pandas/core/dtypes/cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,57 +423,14 @@ def maybe_promote(dtype, fill_value=np.nan):
if issubclass(dtype.type, np.bool_):
dtype = np.dtype(np.object_)
elif issubclass(dtype.type, np.integer):
# upcast to prevent overflow
mst = np.min_scalar_type(fill_value)
if mst > dtype:
# np.dtype ordering considers:
# int[n] < int[2*n]
# uint[n] < uint[2*n]
# u?int[n] < object_
dtype = mst

elif np.can_cast(fill_value, dtype):
pass

elif dtype.kind == "u" and mst.kind == "i":
if not np.can_cast(fill_value, dtype):
# upcast to prevent overflow
mst = np.min_scalar_type(fill_value)
dtype = np.promote_types(dtype, mst)
if dtype.kind == "f":
# Case where we disagree with numpy
dtype = np.dtype(np.object_)

elif dtype.kind == "i" and mst.kind == "u":

if fill_value > np.iinfo(np.int64).max:
# object is the only way to represent fill_value and keep
# the range allowed by the given dtype
dtype = np.dtype(np.object_)

elif mst.itemsize < dtype.itemsize:
pass

elif dtype.itemsize == mst.itemsize:
# We never cast signed to unsigned because that loses
# parts of the original range, so find the smallest signed
# integer that can hold all of `mst`.
ndt = {
np.int64: np.object_,
np.int32: np.int64,
np.int16: np.int32,
np.int8: np.int16,
}[dtype.type]
dtype = np.dtype(ndt)

else:
# bump to signed integer dtype that holds all of `mst` range
# Note: we have to use itemsize because some (windows)
# builds don't satisfiy e.g. np.uint32 == np.uint32
ndt = {
4: np.int64,
2: np.int32,
1: np.int16, # TODO: Test for this case
}[mst.itemsize]
dtype = np.dtype(ndt)

fill_value = dtype.type(fill_value)

elif issubclass(dtype.type, np.floating):
Expand Down