Skip to content

Commit 285b197

Browse files
committed
Handle construction from scalar
1 parent 63444d0 commit 285b197

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

pandas/_libs/lib.pyx

+2-1
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

+26
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,
@@ -795,6 +798,29 @@ def infer_dtype_from_scalar(val) -> tuple[DtypeObj, Any]:
795798
dtype = np.dtype("m8[ns]")
796799
val = np.timedelta64(val.value, "ns")
797800

801+
elif isinstance(val, dt.time):
802+
if val.tzinfo is None:
803+
# pyarrow doesn't have a dtype for timetz.
804+
opt = get_option("future.infer_time")
805+
if opt is None:
806+
warnings.warn(
807+
"Pandas type inference with a `datetime.time` "
808+
"object is deprecated. In a future version, this will give "
809+
"time32[pyarrow] dtype, which will require pyarrow to be "
810+
"installed. To opt in to the new behavior immediately set "
811+
"`pd.set_option('future.infer_time', True)`. To keep the "
812+
"old behavior pass `dtype=object`.",
813+
FutureWarning,
814+
stacklevel=find_stack_level(),
815+
)
816+
elif opt is True:
817+
import pyarrow as pa
818+
819+
pa_dtype = pa.time64("us")
820+
from pandas.core.arrays.arrow import ArrowDtype
821+
822+
dtype = ArrowDtype(pa_dtype)
823+
798824
elif is_bool(val):
799825
dtype = np.dtype(np.bool_)
800826

pandas/tests/frame/test_constructors.py

+34
Original file line numberDiff line numberDiff line change
@@ -3123,6 +3123,40 @@ def test_tzaware_data_tznaive_dtype(self, constructor, box, frame_or_series):
31233123
with pytest.raises(err, match=msg):
31243124
constructor(ts, dtype="M8[ns]")
31253125

3126+
@pytest.mark.parametrize(
3127+
"future", [pytest.param(True, marks=td.skip_if_no("pyarrow")), False, None]
3128+
)
3129+
def test_from_pytime(self, constructor, box, frame_or_series, future):
3130+
item = Timestamp("2023-05-04 08:53").time()
3131+
3132+
warn = None
3133+
if box is list or (box is dict and frame_or_series is Series):
3134+
msg = (
3135+
"Pandas type inference with a sequence of `datetime.time` "
3136+
"objects is deprecated"
3137+
)
3138+
else:
3139+
msg = "Pandas type inference with a `datetime.time` object is deprecated"
3140+
exp_dtype = np.dtype(object)
3141+
if future is None:
3142+
warn = FutureWarning
3143+
elif future is True:
3144+
import pyarrow as pa
3145+
3146+
pa_type = pa.time64("us")
3147+
exp_dtype = pd.ArrowDtype(pa_type)
3148+
3149+
with pd.option_context("future.infer_time", future):
3150+
with tm.assert_produces_warning(warn, match=msg):
3151+
result = constructor(item)
3152+
dtype = tm.get_dtype(result)
3153+
assert dtype == exp_dtype
3154+
3155+
aware = Timestamp("2023-05-04 08:53", tz="US/Pacific").timetz()
3156+
result2 = constructor(aware)
3157+
dtype = tm.get_dtype(result2)
3158+
assert dtype == np.dtype(object)
3159+
31263160

31273161
# TODO: better location for this test?
31283162
class TestAllowNonNano:

0 commit comments

Comments
 (0)