pandas-dev/pandas · error · ValueError
to_pydatetime cannot be called with {self.dtype.pyarrow_dtyp
Error message
to_pydatetime cannot be called with {self.dtype.pyarrow_dtype} type. Convert to pyarrow timestamp type. What it means
Raised by ArrowExtensionArray._dt_to_pydatetime when the array's pyarrow type is a date type (date32 or date64) rather than a timestamp. to_pydatetime needs wall-clock datetime objects; pyarrow date types lack a time component, so conversion is rejected with ValueError and the user is told to convert to a timestamp type first. Reached through Series.dt.to_pydatetime().
Source
Thrown at pandas/core/arrays/arrow/array.py:4242
return self._round_temporally("round", freq, ambiguous, nonexistent)
def _dt_day_name(self, locale: str | None = None) -> Self:
if locale is None:
locale = "C"
result = pc.strftime(self._pa_array, format="%A", locale=locale)
return self._from_pyarrow_array(result)
def _dt_month_name(self, locale: str | None = None) -> Self:
if locale is None:
locale = "C"
result = pc.strftime(self._pa_array, format="%B", locale=locale)
return self._from_pyarrow_array(result)
def _dt_to_pydatetime(self) -> Series:
from pandas import Series
if pa.types.is_date(self.dtype.pyarrow_dtype):
raise ValueError(
f"to_pydatetime cannot be called with {self.dtype.pyarrow_dtype} type. "
"Convert to pyarrow timestamp type."
)
data = self._pa_array.to_pylist()
if self._dtype.pyarrow_dtype.unit == "ns":
data = [None if ts is None else ts.to_pydatetime(warn=False) for ts in data]
return Series(data, dtype=object)
def _dt_tz_localize(
self,
tz,
ambiguous: TimeAmbiguous = "raise",
nonexistent: TimeNonexistent = "raise",
) -> Self:
if ambiguous != "raise":
raise NotImplementedError(f"{ambiguous=} is not supported")
nonexistent_pa = {
"raise": "raise",View on GitHub (pinned to 71959b8cb9)
Solutions
- Cast the Series to a timestamp type first: `s.astype("timestamp[us][pyarrow]").dt.to_pydatetime()`.
- Use `pd.to_datetime(s)` to get datetime64[ns] then `.dt.to_pydatetime()`.
- Operate on the date objects directly via `s.to_numpy()` if you only need date instances.
- Confirm dtype with `s.dtype` and convert date->timestamp before calling to_pydatetime.
Example fix
# before
s = pd.array([datetime.date(2024,1,1)], dtype="date32[pyarrow]")
pd.Series(s).dt.to_pydatetime() # ValueError
# after
pd.Series(s).astype("timestamp[us][pyarrow]").dt.to_pydatetime() Defensive patterns
Strategy: validation
Validate before calling
import pyarrow as pa
def is_timestamp_pyarrow(s) -> bool:
pa_dt = getattr(s.dtype, "pyarrow_dtype", None)
return pa_dt is not None and pa.types.is_timestamp(pa_dt)
def safe_to_pydatetime(s):
if not is_timestamp_pyarrow(s):
s = s.astype("timestamp[us][pyarrow]")
return s.dt.to_pydatetime() Type guard
import pyarrow as pa
def is_timestamp_pyarrow(s) -> bool:
pa_dt = getattr(s.dtype, "pyarrow_dtype", None)
return pa_dt is not None and pa.types.is_timestamp(pa_dt) Try / catch
try:
return s.dt.to_pydatetime()
except ValueError:
return s.astype("timestamp[us][pyarrow]").dt.to_pydatetime() Prevention
- Cast date32/date64 pyarrow columns to timestamp[pyarrow] before to_pydatetime.
- Inspect dtype after loading Parquet/Arrow; DATE logical types become date32/date64.
- Wrap to_pydatetime calls in a helper that normalizes the dtype.
When it happens
Trigger: Calling `s.dt.to_pydatetime()` on a Series whose dtype is `date32[pyarrow]` or `date64[pyarrow]`. Common when loading from Parquet/Arrow that stored DATE logical types, or when constructing via pd.array([datetime.date(...)], dtype=...).
Common situations: ETL from databases (DATE columns) or Parquet files with date logical type; converting date-only columns to Python datetime objects for downstream APIs.
Related errors
- '{self.dtype}' does not have duration components
- as_unit not implemented for {pa_type}
- ambiguous is not supported.
- nonexistent is not supported.
- Must specify a valid frequency: {freq}
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/0da474184b190a9c.
Report an issue: GitHub.