rambleraptor commented on code in PR #4212:
URL: https://github.com/apache/iceberg-python/pull/4212#discussion_r4429374666


##########
pyiceberg/table/update/__init__.py:
##########
@@ -544,11 +544,14 @@ def _(update: RemoveSnapshotsUpdate, base_metadata: 
TableMetadata, context: _Tab
         for snapshot in base_metadata.snapshots
         if snapshot.snapshot_id not in update.snapshot_ids
     ]
-    snapshot_log = [
-        snapshot_log_entry
-        for snapshot_log_entry in base_metadata.snapshot_log
-        if snapshot_log_entry.snapshot_id not in update.snapshot_ids
-    ]
+    expired_ids = set(update.snapshot_ids)
+    snapshot_log: list[SnapshotLogEntry] = []
+    for entry in base_metadata.snapshot_log:
+        if entry.snapshot_id in expired_ids:

Review Comment:
   ```suggestion
           if entry.snapshot_id not in {s.snapshot_id for s in snapshots} :
   ```
   
   As it stands, this only works on expired ids. Java also works on situations 
when the snapshot no longer exists in the table.



##########
tests/table/test_expire_snapshots.py:
##########
@@ -14,18 +14,69 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+import json
 import threading
-from datetime import datetime, timedelta
+from datetime import UTC, datetime, timedelta
+from types import SimpleNamespace
 from unittest.mock import MagicMock, Mock
 from uuid import uuid4
 
 import pytest
 
+from pyiceberg.catalog import Catalog
 from pyiceberg.table import CommitTableResponse, Table
 from pyiceberg.table.update import RemoveSnapshotsUpdate, update_table_metadata
 from pyiceberg.table.update.snapshot import ExpireSnapshots
 
 
[email protected]("expiration", ["by_id", "older_than"])
+def test_expiration_does_not_substitute_older_history(catalog: Catalog, 
monkeypatch: pytest.MonkeyPatch, expiration: str) -> None:
+    import pyarrow as pa
+
+    catalog.create_namespace("history")
+    table = catalog.create_table("history.events", schema=pa.schema([("x", 
pa.int64())]))
+    # Keep snapshot and metadata timestamps consistent; commits and file IO 
remain real.
+    clock_ms = table.metadata.last_updated_ms
+    monkeypatch.setattr("pyiceberg.table.snapshots.time", 
SimpleNamespace(time=lambda: clock_ms / 1000))

Review Comment:
   Do we need to monkeypatch for these? I'd really like to avoid monkeypatching 
whenever possible.



##########
pyiceberg/table/update/__init__.py:
##########
@@ -544,11 +544,14 @@ def _(update: RemoveSnapshotsUpdate, base_metadata: 
TableMetadata, context: _Tab
         for snapshot in base_metadata.snapshots
         if snapshot.snapshot_id not in update.snapshot_ids
     ]
-    snapshot_log = [
-        snapshot_log_entry
-        for snapshot_log_entry in base_metadata.snapshot_log
-        if snapshot_log_entry.snapshot_id not in update.snapshot_ids
-    ]
+    expired_ids = set(update.snapshot_ids)
+    snapshot_log: list[SnapshotLogEntry] = []
+    for entry in base_metadata.snapshot_log:
+        if entry.snapshot_id in expired_ids:

Review Comment:
   Actually, might be better to set this to a variable to avoid constantly 
recalculating it.



##########
tests/table/test_init.py:
##########
@@ -1186,6 +1186,46 @@ def test_update_remove_snapshots_doesnt_exist(table_v2: 
Table) -> None:
         update_table_metadata(table_v2.metadata, (update,))
 
 
[email protected]("table", [lf("table_v1"), lf("table_v2"), 
lf("table_v3")])
+def test_remove_snapshots_retains_contiguous_history(table: Table) -> None:
+    snapshots = [
+        Snapshot(snapshot_id=snapshot_id, timestamp_ms=snapshot_id, 
manifest_list=f"file:///manifest-{snapshot_id}.avro")
+        for snapshot_id in (10, 20, 30, 40)
+    ]
+    cases: list[tuple[str, list[int], list[int], list[int]]] = [

Review Comment:
   This should probably be parameterized. That being said, I think it'll make 
the test pretty messy.
   
   What would you think about having multiple tests + a helper? I'll be honest, 
my eyes are glazing over reading all of these integers and trying to make sure 
that these all seem valid 😆 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to