`DateTime.diff()` constructs an `Interval`, whose `__init__` normalised
the start and end values via `pendulum.instance()`. That call used the
default `tz=UTC`, so a naive stdlib `datetime` was turned into a
UTC-aware `DateTime`. When the receiver was itself naive, the subsequent
comparison mixed an offset-naive value with an offset-aware one and
raised:
TypeError: can't compare offset-naive and offset-aware datetimes
`Interval.__new__` already validates that both endpoints share the same
awareness, so forcing a timezone here was both unnecessary and the
source of the bug. Pass each value's own `tzinfo` to `instance()`
instead: naive inputs stay naive and aware inputs keep their timezone
(`DateTime.instance` resolves `tz` as `dt.tzinfo or tz`), so behaviour
for aware datetimes is unchanged.
Fixes python-pendulum#880
Pull Request Check List
Summary
DateTime.diff() raises a TypeError when a naive DateTime is diffed against a naive stdlib datetime:
Root cause
diff() builds an Interval(self, dt). Interval.__new__ validates that both endpoints have the same awareness (both naive or both aware) and otherwise raises. Interval.__init__, however, re-normalises the endpoints through pendulum.instance() using the default tz=UTC. For a naive stdlib datetime that turns it into a UTC-aware DateTime, so a naive receiver and the (now aware) argument end up mixed, and the subsequent start > end / precise_diff comparison raises.
Fix
Pass each endpoint's own tzinfo to instance() instead of letting it default to UTC:
DateTime.instance resolves the timezone as tz = dt.tzinfo or tz, so:
Because __new__ already guarantees both endpoints share the same awareness, forcing a timezone in __init__ was unnecessary and was the sole source of the mismatch. The mixed naive/aware case still raises in __new__ exactly as before.
Testing
Fixes #880