Bug
sessions.py (line ~1071) strips a trailing Z from ISO timestamps before parsing:
dt = datetime.fromisoformat(str(value).replace("Z", "+00:00"))
…but the knowledge stores call datetime.fromisoformat(...) raw, without the Z handling:
src/selectools/knowledge.py:294,297,470,473,567,575
src/selectools/knowledge_store_supabase.py:72,75
src/selectools/knowledge_store_redis.py:72,75
On Python 3.10, datetime.fromisoformat("2026-01-01T00:00:00Z") raises ValueError (the Z suffix is only accepted on 3.11+). Supabase/Postgres timestamptz columns can serialize with a Z, so reading such a row back raises on 3.10.
Fix (also a cleanup)
The fromisoformat + naive→UTC-coercion idiom is hand-rolled ~18× across knowledge.py, the knowledge stores, unified_memory.py, and sessions.py. Consolidate into a small src/selectools/_time.py:
def ensure_aware(dt): # naive -> UTC
return dt if dt.tzinfo is not None else dt.replace(tzinfo=timezone.utc)
def parse_iso_utc(value):
return ensure_aware(datetime.fromisoformat(value.replace("Z", "+00:00")))
Replace the hand-rolled sites with parse_iso_utc / ensure_aware. This fixes the Z bug everywhere in one place.
Acceptance
- A knowledge store round-trips a
…Z-suffixed timestamp without raising on Python 3.10.
- The ~18 hand-rolled parse sites call the shared helper.
- A regression test covers the
Z-suffix parse.
Bug
sessions.py(line ~1071) strips a trailingZfrom ISO timestamps before parsing:…but the knowledge stores call
datetime.fromisoformat(...)raw, without theZhandling:src/selectools/knowledge.py:294,297,470,473,567,575src/selectools/knowledge_store_supabase.py:72,75src/selectools/knowledge_store_redis.py:72,75On Python 3.10,
datetime.fromisoformat("2026-01-01T00:00:00Z")raisesValueError(theZsuffix is only accepted on 3.11+). Supabase/Postgrestimestamptzcolumns can serialize with aZ, so reading such a row back raises on 3.10.Fix (also a cleanup)
The
fromisoformat+ naive→UTC-coercion idiom is hand-rolled ~18× acrossknowledge.py, the knowledge stores,unified_memory.py, andsessions.py. Consolidate into a smallsrc/selectools/_time.py:Replace the hand-rolled sites with
parse_iso_utc/ensure_aware. This fixes theZbug everywhere in one place.Acceptance
…Z-suffixed timestamp without raising on Python 3.10.Z-suffix parse.