Use astimezone, add timezone tests, linting
This commit is contained in:
parent
9c56f56660
commit
880551deba
4 changed files with 42 additions and 10 deletions
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Document timestamps include timezone information and satisfy the MCP
|
||||
date-time output schema.
|
||||
|
||||
## [0.82.0] - 2026-09-03
|
||||
|
||||
### Removed
|
||||
|
|
|
|||
|
|
@ -34,14 +34,8 @@ class Document(BaseModel):
|
|||
|
||||
@field_validator("created_at", "updated_at")
|
||||
@classmethod
|
||||
def _assume_utc(cls, value: datetime) -> datetime:
|
||||
"""Attach UTC to a timezone-less timestamp instead of leaving it ambiguous.
|
||||
|
||||
A row written before timestamps carried an explicit offset parses back
|
||||
with no tzinfo. Treat it as UTC rather than pass it on naive, which the
|
||||
MCP tools' declared JSON schema rejects as an invalid date-time.
|
||||
"""
|
||||
return value if value.tzinfo else value.replace(tzinfo=UTC)
|
||||
def _to_utc(cls, value: datetime) -> datetime:
|
||||
return value if value.tzinfo else value.astimezone(UTC)
|
||||
|
||||
def set_docling(self, docling_doc: "DoclingDocument") -> None:
|
||||
"""Serialize and store a DoclingDocument, splitting structure and pages.
|
||||
|
|
|
|||
|
|
@ -77,8 +77,12 @@ class DocumentRepository:
|
|||
docling_document=doc.docling_document,
|
||||
docling_pages=doc.docling_pages,
|
||||
docling_version=doc.docling_version,
|
||||
created_at=datetime.fromisoformat(created) if created else datetime.now(UTC),
|
||||
updated_at=datetime.fromisoformat(updated) if updated else datetime.now(UTC),
|
||||
created_at=datetime.fromisoformat(created)
|
||||
if created
|
||||
else datetime.now(UTC),
|
||||
updated_at=datetime.fromisoformat(updated)
|
||||
if updated
|
||||
else datetime.now(UTC),
|
||||
)
|
||||
|
||||
def _to_documents_record(self, entity: Document, doc_id: str) -> DocumentRecord:
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
import os
|
||||
import time
|
||||
from datetime import UTC, datetime
|
||||
|
||||
import pytest
|
||||
|
||||
from haiku.rag.store.engine import Store
|
||||
|
|
@ -549,3 +553,28 @@ async def test_document_get_by_uri_with_special_characters(
|
|||
assert retrieved is not None
|
||||
assert retrieved.id == created_doc.id
|
||||
assert retrieved.uri == "Hamish and Andy's Gap Year"
|
||||
|
||||
|
||||
@pytest.mark.skipif(not hasattr(time, "tzset"), reason="time.tzset is POSIX-only")
|
||||
def test_naive_timestamp_is_converted_from_local_time():
|
||||
original_tz = os.environ.get("TZ")
|
||||
os.environ["TZ"] = "Europe/Athens"
|
||||
time.tzset()
|
||||
try:
|
||||
created = datetime(2026, 1, 1, 14, 0, 0) # January is EET, UTC+2
|
||||
updated = datetime(2026, 1, 1, 14, 30, 0)
|
||||
doc = Document(content="x", created_at=created, updated_at=updated)
|
||||
assert doc.created_at == datetime(2026, 1, 1, 12, 0, 0, tzinfo=UTC)
|
||||
assert doc.updated_at == datetime(2026, 1, 1, 12, 30, 0, tzinfo=UTC)
|
||||
finally:
|
||||
if original_tz is None:
|
||||
os.environ.pop("TZ", None)
|
||||
else:
|
||||
os.environ["TZ"] = original_tz
|
||||
time.tzset()
|
||||
|
||||
|
||||
def test_created_at_serializes_with_timezone_offset():
|
||||
doc = Document(content="x")
|
||||
value = doc.model_dump(mode="json")["created_at"]
|
||||
assert datetime.fromisoformat(value).utcoffset() is not None
|
||||
|
|
|
|||
Loading…
Reference in a new issue