Skip to content

Commit 820d202

Browse files
committed
Handle construction from scalar
1 parent cc1212c commit 820d202

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

pandas/_libs/lib.pyx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2573,7 +2573,7 @@ def maybe_convert_objects(ndarray[object] objects,
25732573
seen.object_ = True
25742574
break
25752575
elif PyTime_Check(val):
2576-
if convert_time:
2576+
if convert_non_numeric and val.tzinfo is None:
25772577
seen.time_ = True
25782578
else:
25792579
seen.object_ = True
@@ -2644,6 +2644,7 @@ def maybe_convert_objects(ndarray[object] objects,
26442644

26452645
elif seen.time_:
26462646
if is_time_array(objects):
2647+
# FIXME: need to ensure this is not timetz
26472648
opt = get_option("future.infer_time")
26482649
if opt is True:
26492650
import pyarrow as pa

pandas/core/dtypes/cast.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
import numpy as np
2222

23+
from pandas._config import get_option
24+
2325
from pandas._libs import lib
2426
from pandas._libs.missing import (
2527
NA,
@@ -40,6 +42,7 @@
4042
IntCastingNaNError,
4143
LossySetitemError,
4244
)
45+
from pandas.util._exceptions import find_stack_level
4346

4447
from pandas.core.dtypes.common import (
4548
ensure_int8,
@@ -808,6 +811,29 @@ def infer_dtype_from_scalar(val) -> tuple[DtypeObj, Any]:
808811
val = val.asm8
809812
dtype = val.dtype
810813

814+
elif isinstance(val, dt.time):
815+
if val.tzinfo is None:
816+
# pyarrow doesn't have a dtype for timetz.
817+
opt = get_option("future.infer_time")
818+
if opt is None:
819+
warnings.warn(
820+
"Pandas type inference with a `datetime.time` "
821+
"object is deprecated. In a future version, this will give "
822+
"time32[pyarrow] dtype, which will require pyarrow to be "
823+
"installed. To opt in to the new behavior immediately set "
824+
"`pd.set_option('future.infer_time', True)`. To keep the "
825+
"old behavior pass `dtype=object`.",
826+
FutureWarning,
827+
stacklevel=find_stack_level(),
828+
)
829+
elif opt is True:
830+
import pyarrow as pa
831+
832+
pa_dtype = pa.time64("us")
833+
from pandas.core.arrays.arrow import ArrowDtype
834+
835+
dtype = ArrowDtype(pa_dtype)
836+
811837
elif is_bool(val):
812838
dtype = np.dtype(np.bool_)
813839

pandas/tests/frame/test_constructors.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3136,6 +3136,40 @@ def test_tzaware_data_tznaive_dtype(self, constructor, box, frame_or_series):
31363136
with pytest.raises(err, match=msg):
31373137
constructor(ts, dtype="M8[ns]")
31383138

3139+
@pytest.mark.parametrize(
3140+
"future", [pytest.param(True, marks=td.skip_if_no("pyarrow")), False, None]
3141+
)
3142+
def test_from_pytime(self, constructor, box, frame_or_series, future):
3143+
item = Timestamp("2023-05-04 08:53").time()
3144+
3145+
warn = None
3146+
if box is list or (box is dict and frame_or_series is Series):
3147+
msg = (
3148+
"Pandas type inference with a sequence of `datetime.time` "
3149+
"objects is deprecated"
3150+
)
3151+
else:
3152+
msg = "Pandas type inference with a `datetime.time` object is deprecated"
3153+
exp_dtype = np.dtype(object)
3154+
if future is None:
3155+
warn = FutureWarning
3156+
elif future is True:
3157+
import pyarrow as pa
3158+
3159+
pa_type = pa.time64("us")
3160+
exp_dtype = pd.ArrowDtype(pa_type)
3161+
3162+
with pd.option_context("future.infer_time", future):
3163+
with tm.assert_produces_warning(warn, match=msg):
3164+
result = constructor(item)
3165+
dtype = tm.get_dtype(result)
3166+
assert dtype == exp_dtype
3167+
3168+
aware = Timestamp("2023-05-04 08:53", tz="US/Pacific").timetz()
3169+
result2 = constructor(aware)
3170+
dtype = tm.get_dtype(result2)
3171+
assert dtype == np.dtype(object)
3172+
31393173

31403174
# TODO: better location for this test?
31413175
class TestAllowNonNano:

0 commit comments

Comments
 (0)