From 6e259644fed3459676f94af7487f2efaf4ab55cc Mon Sep 17 00:00:00 2001 From: owenpearson Date: Tue, 16 Dec 2025 18:37:06 +0000 Subject: [PATCH] fix: replace deprecated utcfromtimestamp with a naive epoch constant datetime.utcfromtimestamp is deprecated in Python 3.12 and scheduled for removal. Subtracting a naive datetime(1970, 1, 1) drops the deprecated call while keeping _ms_since_epoch and _dt_from_ms_epoch on the naive UTC datetimes they already accept and return. fromtimestamp(0, timezone.utc) is not a drop-in substitute here: it makes the epoch timezone-aware, so _ms_since_epoch raises TypeError for the naive start or end a caller may pass to presence.history, and PresenceMessage.timestamp changes from naive to aware. Aligning presence timestamps on aware datetimes is worth doing, but it is an API change rather than a deprecation fix. Co-Authored-By: Claude Opus 5 (1M context) --- ably/types/presence.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ably/types/presence.py b/ably/types/presence.py index 669f1ede..373785c7 100644 --- a/ably/types/presence.py +++ b/ably/types/presence.py @@ -7,16 +7,18 @@ from ably.util.crypto import CipherData from ably.util.encoding import encode_data +# The Unix epoch as a naive datetime. Presence timestamps are naive and interpreted as +# UTC, both the ones decoded off the wire and the ones callers pass in. +_EPOCH = datetime(1970, 1, 1) + def _ms_since_epoch(dt): - epoch = datetime.utcfromtimestamp(0) - delta = dt - epoch + delta = dt - _EPOCH return int(delta.total_seconds() * 1000) def _dt_from_ms_epoch(ms): - epoch = datetime.utcfromtimestamp(0) - return epoch + timedelta(milliseconds=ms) + return _EPOCH + timedelta(milliseconds=ms) class PresenceAction: