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

  1. Cast the Series to a timestamp type first: `s.astype("timestamp[us][pyarrow]").dt.to_pydatetime()`.
  2. Use `pd.to_datetime(s)` to get datetime64[ns] then `.dt.to_pydatetime()`.
  3. Operate on the date objects directly via `s.to_numpy()` if you only need date instances.
  4. 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

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


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/0da474184b190a9c. Report an issue: GitHub.