pandas-dev/pandas · error · AssertionError
[datetimelike_compat=True] {left._values} is not equal to {r
Error message
[datetimelike_compat=True] {left._values} is not equal to {right._values}. What it means
Raised by assert_series_equal (asserters.py:1193-1207) in the datetimelike-compat branch. When check_datetimelike_compat=True and one side has a datetime-like dtype (needs_i8_conversion), the code compares the underlying values directly because datetime objects may differ in Python type (datetime.datetime vs Timestamp) yet be equal. If Index(left._values).equals(Index(right._values)) is False, it raises AssertionError with the [datetimelike_compat=True] prefix.
Source
Thrown at pandas/_testing/asserters.py:1207
obj=str(obj),
class_obj=f"{obj} values",
index_values=left.index,
)
elif check_datetimelike_compat and (
needs_i8_conversion(left.dtype) or needs_i8_conversion(right.dtype)
):
# we want to check only if we have compat dtypes
# e.g. integer and M|m are NOT compat, but we can simply check
# the values in that case
# datetimelike may have different objects (e.g. datetime.datetime
# vs Timestamp) but will compare equal
if not Index(left._values).equals(Index(right._values)):
msg = (
f"[datetimelike_compat=True] {left._values} "
f"is not equal to {right._values}."
)
raise AssertionError(msg)
elif isinstance(left.dtype, IntervalDtype) and isinstance(
right.dtype, IntervalDtype
):
assert_interval_array_equal(
cast("IntervalArray", left.array), cast("IntervalArray", right.array)
)
elif isinstance(left.dtype, CategoricalDtype) or isinstance(
right.dtype, CategoricalDtype
):
_testing.assert_almost_equal(
left._values,
right._values,
rtol=rtol,
atol=atol,
check_dtype=bool(check_dtype),
obj=str(obj),
index_values=left.index,
)View on GitHub (pinned to 71959b8cb9)
Solutions
- Inspect the printed left._values vs right._values to find the first differing element.
- Normalize timezones on both sides (e.g. .dt.tz_convert('UTC')) before comparing.
- If only the Python-level object type differs but instants match, ensure both sides use Timestamp (e.g. pd.to_datetime) so they fall in the standard equality branch.
- Re-evaluate whether check_datetimelike_compat=True is needed; remove it if both sides have identical dtypes.
Example fix
# before
assert_series_equal(
pd.Series(pd.to_datetime(['2020-01-01'])),
pd.Series(pd.to_datetime(['2020-01-01 00:00:01'])),
check_datetimelike_compat=True,
)
# after — align the values
assert_series_equal(
pd.Series(pd.to_datetime(['2020-01-01'])),
pd.Series(pd.to_datetime(['2020-01-01'])),
) Defensive patterns
Strategy: validation
Validate before calling
import pandas as pd
# normalize tz/dtype before comparing datetimelike series
left_n = left.dt.tz_convert('UTC') if left.dt.tz else left
right_n = right.dt.tz_convert('UTC') if right.dt.tz else right
assert_series_equal(left_n, right_n) Prevention
- Normalize timezones on both sides before comparing datetimelike data.
- Use pd.to_datetime on both sides so they share Timestamp scalars.
- Drop check_datetimelike_compat=True when both dtypes already match.
When it happens
Trigger: Calling assert_series_equal(left, right, check_datetimelike_compat=True) where one Series is datetime64/datetime tz-aware/period/timedelta and the underlying values genuinely differ (different timestamps, different tz offsets, NaT mismatches). This branch only activates when at least one dtype needs i8 conversion.
Common situations: Comparing timezone-aware datetimes across different tz representations; mixing datetime.datetime scalars with pd.Timestamp; period vs datetime confusion; NaT handling differences between the two sides.
Related errors
- {cls_name} Expected type {cls}, found {type(left)} instead
- {cls_name} Expected type {cls}, found {type(right)} instead
- {obj} are different {message}
- {left_base!r} is not {right_base!r}
- {left_base!r} is {right_base!r}
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/ec18d0e316331086.
Report an issue: GitHub.