Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,8 @@ Datetimelike
- Bug in constructing arrays with :class:`ArrowDtype` with ``timestamp`` type incorrectly allowing ``Decimal("NaN")`` (:issue:`61773`)
- Bug in constructing arrays with a timezone-aware :class:`ArrowDtype` from timezone-naive datetime objects incorrectly treating those as UTC times instead of wall times like :class:`DatetimeTZDtype` (:issue:`61775`)
- Bug in setting scalar values with mismatched resolution into arrays with non-nanosecond ``datetime64``, ``timedelta64`` or :class:`DatetimeTZDtype` incorrectly truncating those scalars (:issue:`56410`)
- Bug in :func:`pandas.to_datetime` where passing an ``lxml.etree._ElementUnicodeResult`` together with ``format=...`` raised ``TypeError``. Now subclasses of ``str`` are handled. (:issue:`60933`, :pr:`62604`)


Timedelta
^^^^^^^^^
Expand Down
5 changes: 5 additions & 0 deletions pandas/_libs/tslibs/strptime.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,11 @@ def array_strptime(
if len(val) == 0 or val in nat_strings:
iresult[i] = NPY_NAT
continue
elif type(val) is not str:
# GH#60933: normalize string subclasses
# (e.g. lxml.etree._ElementUnicodeResult). The downstream Cython
# path expects an exact `str`, so ensure we pass a plain str
val = str(val)
elif checknull_with_nat_and_na(val):
iresult[i] = NPY_NAT
continue
Expand Down
12 changes: 12 additions & 0 deletions pandas/tests/tools/test_to_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -3790,3 +3790,15 @@ def test_to_datetime_wrapped_datetime64_ps():
["1970-01-01 00:00:01.901901901"], dtype="datetime64[ns]", freq=None
)
tm.assert_index_equal(result, expected)


def test_to_datetime_lxml_elementunicoderesult_with_format(cache):
pytest.importorskip("lxml")
from lxml import etree # pyright: ignore[reportMissingImports]

s = "2025-02-05 16:59:57"
node = etree.XML(f"<date>{s}</date>")
val = node.xpath("/date/node()")[0] # _ElementUnicodeResult

out = to_datetime(Series([val]), format="%Y-%m-%d %H:%M:%S", cache=cache)
tm.assert_equal(out.iloc[0], Timestamp(s))
Loading