From 3b97f3df62eae28cb3c6f23631e449ca002b1f5e Mon Sep 17 00:00:00 2001 From: beinan Date: Mon, 19 Jan 2026 07:16:25 +0000 Subject: [PATCH 1/4] test: verify text persistence round trip --- tests/test_persistence.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tests/test_persistence.py diff --git a/tests/test_persistence.py b/tests/test_persistence.py new file mode 100644 index 0000000..1ec7ba3 --- /dev/null +++ b/tests/test_persistence.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +import sys +from pathlib import Path + +import pytest + +PACKAGE_ROOT = Path(__file__).resolve().parents[1] / "python" / "python" +if str(PACKAGE_ROOT) not in sys.path: + sys.path.insert(0, str(PACKAGE_ROOT)) + +lance = pytest.importorskip("lance") + +from lance_context.api import Context + + +def _read_rows(uri: str, version: int | None = None) -> list[dict[str, object]]: + dataset = lance.dataset(uri, version=version) if version is not None else lance.dataset(uri) + table = dataset.to_table() + return table.to_pylist() + + +def test_text_round_trip(tmp_path: Path) -> None: + uri = tmp_path / "context.lance" + ctx = Context.create(str(uri)) + ctx.add("user", "hello world") + + rows = _read_rows(str(uri)) + assert len(rows) == 1 + + record = rows[0] + assert record["role"] == "user" + assert record["text_payload"] == "hello world" + assert record["binary_payload"] is None + assert record["content_type"] == "text/plain" From 1087212e33de2b18a95b858707be92e8d977df19 Mon Sep 17 00:00:00 2001 From: beinan Date: Mon, 19 Jan 2026 07:18:58 +0000 Subject: [PATCH 2/4] test: verify image persistence --- tests/test_persistence.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 1ec7ba3..6e7d4cd 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -1,6 +1,7 @@ from __future__ import annotations import sys +from io import BytesIO from pathlib import Path import pytest @@ -10,6 +11,7 @@ sys.path.insert(0, str(PACKAGE_ROOT)) lance = pytest.importorskip("lance") +Image = pytest.importorskip("PIL.Image") from lance_context.api import Context @@ -20,6 +22,12 @@ def _read_rows(uri: str, version: int | None = None) -> list[dict[str, object]]: return table.to_pylist() +def _image_bytes(image: Image.Image, *, format: str | None = None) -> bytes: + buffer = BytesIO() + image.save(buffer, format=format or image.format or "PNG") + return buffer.getvalue() + + def test_text_round_trip(tmp_path: Path) -> None: uri = tmp_path / "context.lance" ctx = Context.create(str(uri)) @@ -33,3 +41,20 @@ def test_text_round_trip(tmp_path: Path) -> None: assert record["text_payload"] == "hello world" assert record["binary_payload"] is None assert record["content_type"] == "text/plain" + + +def test_image_round_trip(tmp_path: Path) -> None: + uri = tmp_path / "context.lance" + ctx = Context.create(str(uri)) + + image = Image.new("RGB", (4, 4), color="magenta") + ctx.add("assistant", image) + + rows = _read_rows(str(uri)) + assert len(rows) == 1 + + record = rows[0] + assert record["role"] == "assistant" + assert record["text_payload"] is None + assert record["content_type"] == "image/png" + assert record["binary_payload"] == _image_bytes(image) From b219fc61e63eef7594f71a2070bc5ed20d65438b Mon Sep 17 00:00:00 2001 From: beinan Date: Mon, 19 Jan 2026 07:21:26 +0000 Subject: [PATCH 3/4] test: cover version checkout persistence --- tests/test_persistence.py | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 6e7d4cd..f42c9e9 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -3,6 +3,7 @@ import sys from io import BytesIO from pathlib import Path +from typing import Any import pytest @@ -11,7 +12,6 @@ sys.path.insert(0, str(PACKAGE_ROOT)) lance = pytest.importorskip("lance") -Image = pytest.importorskip("PIL.Image") from lance_context.api import Context @@ -22,9 +22,9 @@ def _read_rows(uri: str, version: int | None = None) -> list[dict[str, object]]: return table.to_pylist() -def _image_bytes(image: Image.Image, *, format: str | None = None) -> bytes: +def _image_bytes(image: Any, *, format: str | None = None) -> bytes: buffer = BytesIO() - image.save(buffer, format=format or image.format or "PNG") + image.save(buffer, format=format or getattr(image, "format", None) or "PNG") return buffer.getvalue() @@ -44,6 +44,7 @@ def test_text_round_trip(tmp_path: Path) -> None: def test_image_round_trip(tmp_path: Path) -> None: + Image = pytest.importorskip("PIL.Image") uri = tmp_path / "context.lance" ctx = Context.create(str(uri)) @@ -58,3 +59,24 @@ def test_image_round_trip(tmp_path: Path) -> None: assert record["text_payload"] is None assert record["content_type"] == "image/png" assert record["binary_payload"] == _image_bytes(image) + + +def test_time_travel_checkout(tmp_path: Path) -> None: + uri = tmp_path / "context.lance" + ctx = Context.create(str(uri)) + + ctx.add("system", "first-entry") + version_first = ctx.version() + + ctx.add("system", "second-entry") + version_second = ctx.version() + assert version_second >= version_first + + ctx.checkout(version_first) + + rows_versioned = _read_rows(str(uri), version=ctx.version()) + assert len(rows_versioned) == 1 + assert rows_versioned[0]["text_payload"] == "first-entry" + + latest_rows = _read_rows(str(uri)) + assert [row["text_payload"] for row in latest_rows] == ["first-entry", "second-entry"] From a47dbb481eb6d883f4a1b713dfc8e17ffcf8d578 Mon Sep 17 00:00:00 2001 From: beinan Date: Mon, 19 Jan 2026 07:41:59 +0000 Subject: [PATCH 4/4] chore: house persistence tests under python package --- {tests => python/tests}/test_persistence.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename {tests => python/tests}/test_persistence.py (97%) diff --git a/tests/test_persistence.py b/python/tests/test_persistence.py similarity index 97% rename from tests/test_persistence.py rename to python/tests/test_persistence.py index f42c9e9..adab7c9 100644 --- a/tests/test_persistence.py +++ b/python/tests/test_persistence.py @@ -7,7 +7,7 @@ import pytest -PACKAGE_ROOT = Path(__file__).resolve().parents[1] / "python" / "python" +PACKAGE_ROOT = Path(__file__).resolve().parents[2] / "python" / "python" if str(PACKAGE_ROOT) not in sys.path: sys.path.insert(0, str(PACKAGE_ROOT))