Skip to content

Commit 5befaed

Browse files
committed
BUG: Decimal(NaN) incorrectly allowed in ArrowEA constructor with timestamp type
1 parent 51763f9 commit 5befaed

File tree

4 files changed

+28
-0
lines changed

4 files changed

+28
-0
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,8 @@ Datetimelike
707707
- Bug in :meth:`to_datetime` with ``format="ISO8601"`` and ``utc=True`` where naive timestamps incorrectly inherited timezone offset from previous timestamps in a series. (:issue:`61389`)
708708
- Bug in :meth:`to_datetime` wrongly converts when ``arg`` is a ``np.datetime64`` object with unit of ``ps``. (:issue:`60341`)
709709
- Bug in setting scalar values with mismatched resolution into arrays with non-nanosecond ``datetime64``, ``timedelta64`` or :class:`DatetimeTZDtype` incorrectly truncating those scalars (:issue:`56410`)
710+
- Bug in constructing arrays with :class:`ArrowDtype` with ``timestamp`` type incorrectly allowing ``Decimal("NaN")`` (:issue:`??`)
711+
-
710712

711713
Timedelta
712714
^^^^^^^^^

pandas/core/arrays/arrow/array.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,12 @@ def _box_pa_array(
500500
value = to_timedelta(value, unit=pa_type.unit).as_unit(pa_type.unit)
501501
value = value.to_numpy()
502502

503+
if pa_type is not None and pa.types.is_timestamp(pa_type):
504+
# Use to_datetime to handle NaNs, disallow Decimal("NaN")
505+
from pandas import to_datetime
506+
507+
value = to_datetime(value).as_unit(pa_type.unit)
508+
503509
try:
504510
pa_array = pa.array(value, type=pa_type, from_pandas=True)
505511
except (pa.ArrowInvalid, pa.ArrowTypeError):

pandas/tests/extension/test_arrow.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3544,3 +3544,17 @@ def test_arrow_json_type():
35443544
dtype = ArrowDtype(pa.json_(pa.string()))
35453545
result = dtype.type
35463546
assert result == str
3547+
3548+
3549+
def test_timestamp_dtype_disallows_decimal():
3550+
# constructing with pyarrow timestamp dtype should disallow Decimal NaN,
3551+
# just like pd.to_datetime
3552+
vals = [pd.Timestamp("2016-01-02 03:04:05"), Decimal("NaN")]
3553+
3554+
msg = "<class 'decimal.Decimal'> is not convertible to datetime"
3555+
with pytest.raises(TypeError, match=msg):
3556+
# Check that the non-pyarrow version raises as expected
3557+
pd.to_datetime(vals)
3558+
3559+
with pytest.raises(TypeError, match=msg):
3560+
pd.array(vals, dtype=ArrowDtype(pa.timestamp("us")))

pandas/tests/io/test_sql.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
time,
99
timedelta,
1010
)
11+
from decimal import Decimal
1112
from io import StringIO
1213
from pathlib import Path
1314
import sqlite3
@@ -1038,6 +1039,11 @@ def test_dataframe_to_sql_arrow_dtypes(conn, request):
10381039
def test_dataframe_to_sql_arrow_dtypes_missing(conn, request, nulls_fixture):
10391040
# GH 52046
10401041
pytest.importorskip("pyarrow")
1042+
if isinstance(nulls_fixture, Decimal):
1043+
pytest.skip(
1044+
reason="Decimal('NaN') not supported in constructor for timestamp dtype"
1045+
)
1046+
10411047
df = DataFrame(
10421048
{
10431049
"datetime": pd.array(

0 commit comments

Comments
 (0)