This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git
The following commit(s) were added to refs/heads/main by this push:
new e6eb6a93b REST: Preserve view metadata location (#4088)
e6eb6a93b is described below
commit e6eb6a93b94c547a5f2b68f5eb68f64a44cc48af
Author: Soumyadyuti Dey <[email protected]>
AuthorDate: Sun Oct 25 03:27:03 2026 +0000
REST: Preserve view metadata location (#4088)
* REST: preserve view metadata location
* View: clarify metadata location semantics
* View: include metadata location in equality
Match Table.__eq__ and the REST spec, which uses metadata location to detect
view changes.
Co-authored-by: Copilot App <[email protected]>
---------
Co-authored-by: Kevin Liu <[email protected]>
Co-authored-by: Copilot App <[email protected]>
---
pyiceberg/catalog/rest/__init__.py | 1 +
pyiceberg/view/__init__.py | 10 +++++++++-
tests/catalog/test_rest.py | 8 +++++++-
tests/integration/test_rest_catalog.py | 1 +
4 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/pyiceberg/catalog/rest/__init__.py
b/pyiceberg/catalog/rest/__init__.py
index 2b8b4496f..97b2e2350 100644
--- a/pyiceberg/catalog/rest/__init__.py
+++ b/pyiceberg/catalog/rest/__init__.py
@@ -1187,6 +1187,7 @@ class RestCatalog(Catalog):
identifier=identifier_tuple,
metadata=view_response.metadata,
config=view_response.config,
+ metadata_location=view_response.metadata_location,
)
def _refresh_token(self) -> None:
diff --git a/pyiceberg/view/__init__.py b/pyiceberg/view/__init__.py
index 4f298e5b6..1f7c0e906 100644
--- a/pyiceberg/view/__init__.py
+++ b/pyiceberg/view/__init__.py
@@ -30,16 +30,20 @@ class View:
_identifier: Identifier
metadata: ViewMetadata
config: dict[str, str]
+ # None when no metadata location is available, such as for directly
constructed views.
+ metadata_location: str | None
def __init__(
self,
identifier: Identifier,
metadata: ViewMetadata,
config: dict[str, str] = EMPTY_DICT,
+ metadata_location: str | None = None,
) -> None:
self._identifier = identifier
self.metadata = metadata
self.config = config
+ self.metadata_location = metadata_location
def name(self) -> Identifier:
"""Return the identifier of this view."""
@@ -92,4 +96,8 @@ class View:
def __eq__(self, other: Any) -> bool:
"""Return the equality of two instances of the View class."""
- return self.name() == other.name() and self.metadata == other.metadata
if isinstance(other, View) else False
+ return (
+ self.name() == other.name() and self.metadata == other.metadata
and self.metadata_location == other.metadata_location
+ if isinstance(other, View)
+ else False
+ )
diff --git a/tests/catalog/test_rest.py b/tests/catalog/test_rest.py
index 4877ee2f7..b1b46e467 100644
--- a/tests/catalog/test_rest.py
+++ b/tests/catalog/test_rest.py
@@ -1799,6 +1799,7 @@ def test_create_view_200(rest_mock: Mocker,
table_schema_simple: Schema, example
expected = View(
identifier=("fokko", "fokko2"),
metadata=ViewMetadata(**example_view_metadata_rest_json["metadata"]),
+ metadata_location=example_view_metadata_rest_json["metadata-location"],
)
assert actual == expected
assert actual.config == example_view_metadata_rest_json["config"]
@@ -1846,7 +1847,11 @@ def test_load_view_200(rest_mock: Mocker,
example_view_metadata_rest_json: dict[
)
catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN)
actual = catalog.load_view(("fokko", "view"))
- expected = View(identifier=("fokko", "view"),
metadata=ViewMetadata(**example_view_metadata_rest_json["metadata"]))
+ expected = View(
+ identifier=("fokko", "view"),
+ metadata=ViewMetadata(**example_view_metadata_rest_json["metadata"]),
+ metadata_location=example_view_metadata_rest_json["metadata-location"],
+ )
assert actual == expected
assert actual.config == example_view_metadata_rest_json["config"]
@@ -2806,6 +2811,7 @@ def test_register_view_200(rest_mock: Mocker,
example_view_metadata_rest_json: d
expected = View(
identifier=("default", "registered_view"),
metadata=ViewMetadata(**example_view_metadata_rest_json["metadata"]),
+ metadata_location=example_view_metadata_rest_json["metadata-location"],
)
assert actual == expected
assert actual.config == example_view_metadata_rest_json["config"]
diff --git a/tests/integration/test_rest_catalog.py
b/tests/integration/test_rest_catalog.py
index 05039a982..1705dcfb2 100644
--- a/tests/integration/test_rest_catalog.py
+++ b/tests/integration/test_rest_catalog.py
@@ -92,6 +92,7 @@ def test_load_view(catalog: RestCatalog, table_schema_nested:
Schema, database_n
)
view = catalog.create_view(identifier, table_schema_nested,
view_version=view_version)
loaded_view = catalog.load_view(identifier)
+ assert view.metadata_location is not None
assert view == loaded_view