Skip to content

Commit ca5f652

Browse files
committed
Fix patch.object targeting wrong Transaction class in CI
In CI, pyiceberg.table module is loaded twice, creating two distinct Transaction class objects. patch.object on the test-imported Transaction does not affect the runtime Transaction used by Table.append(). Fix by resolving Transaction from pyiceberg.table module at runtime. Signed-off-by: Sotaro Hikita <bering1814@gmail.com>
1 parent f7550d1 commit ca5f652

1 file changed

Lines changed: 26 additions & 33 deletions

File tree

tests/table/test_commit_retry.py

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,21 @@ def test_commit_retry_on_commit_failed(catalog: Catalog) -> None:
7373
tbl1.append(df)
7474

7575
# Second append should succeed via retry (append vs append never conflicts)
76-
tbl2.append(df)
76+
import pyiceberg.table as _table_module
77+
78+
RuntimeTransaction = _table_module.Transaction
79+
original_rebuild = RuntimeTransaction._rebuild_snapshot_updates
80+
rebuild_count = 0
81+
82+
def counting_rebuild(self_tx: Any) -> None:
83+
nonlocal rebuild_count
84+
rebuild_count += 1
85+
original_rebuild(self_tx)
86+
87+
with patch.object(RuntimeTransaction, "_rebuild_snapshot_updates", counting_rebuild):
88+
tbl2.append(df)
89+
90+
assert rebuild_count == 1, "Expected exactly one retry via _rebuild_snapshot_updates"
7791

7892
# Both appends should be visible
7993
refreshed = catalog.load_table("default.retry_test")
@@ -209,44 +223,20 @@ def test_concurrent_delete_append_retries_successfully(catalog: Catalog) -> None
209223

210224
tbl1.delete("x == 1")
211225

212-
print(f"DEBUG tbl1.metadata.current_snapshot_id={tbl1.metadata.current_snapshot_id}")
213-
print(f"DEBUG tbl2.metadata.current_snapshot_id={tbl2.metadata.current_snapshot_id}")
214-
print(f"DEBUG tbl1.metadata is tbl2.metadata: {tbl1.metadata is tbl2.metadata}")
215-
print(f"DEBUG tbl1 is tbl2: {tbl1 is tbl2}")
216-
print(f"DEBUG id(tbl1)={id(tbl1)} id(tbl2)={id(tbl2)}")
217-
print(f"DEBUG id(tbl1.metadata)={id(tbl1.metadata)} id(tbl2.metadata)={id(tbl2.metadata)}")
226+
import pyiceberg.table as _table_module
218227

219-
original_rebuild = Transaction._rebuild_snapshot_updates
228+
RuntimeTransaction = _table_module.Transaction
229+
original_rebuild = RuntimeTransaction._rebuild_snapshot_updates
220230
rebuild_count = 0
221231

222-
def counting_rebuild(self_tx: Transaction) -> None:
232+
def counting_rebuild(self_tx: Any) -> None:
223233
nonlocal rebuild_count
224234
rebuild_count += 1
225-
print(f"DEBUG _rebuild_snapshot_updates called, count={rebuild_count}")
226235
original_rebuild(self_tx)
227236

228-
original_do_commit = type(tbl2)._do_commit
229-
commit_count = 0
230-
231-
def counting_do_commit(self: Any, updates: Any, requirements: Any) -> None:
232-
nonlocal commit_count
233-
commit_count += 1
234-
print(f"DEBUG _do_commit called, count={commit_count}")
235-
return original_do_commit(self, updates, requirements)
236-
237-
with (
238-
patch.object(Transaction, "_rebuild_snapshot_updates", counting_rebuild),
239-
patch.object(type(tbl2), "_do_commit", counting_do_commit),
240-
):
241-
# Verify patch target matches runtime class
242-
from pyiceberg.table import Transaction as RuntimeTransaction
243-
244-
print(f"DEBUG Transaction is RuntimeTransaction: {Transaction is RuntimeTransaction}")
245-
print(f"DEBUG id(Transaction)={id(Transaction)} id(RuntimeTransaction)={id(RuntimeTransaction)}")
246-
print(f"DEBUG patched: {Transaction._rebuild_snapshot_updates is counting_rebuild}")
237+
with patch.object(RuntimeTransaction, "_rebuild_snapshot_updates", counting_rebuild):
247238
tbl2.append(df)
248239

249-
print(f"DEBUG rebuild_count={rebuild_count} commit_count={commit_count}")
250240
assert rebuild_count == 1
251241

252242
refreshed = catalog.load_table("default.del_app_test")
@@ -407,16 +397,19 @@ def test_uncommitted_manifests_tracked_correctly(catalog: Catalog) -> None:
407397

408398
tbl1.append(df)
409399

410-
original_rebuild = Transaction._rebuild_snapshot_updates
400+
import pyiceberg.table as _table_module2
401+
402+
RuntimeTransaction2 = _table_module2.Transaction
403+
original_rebuild = RuntimeTransaction2._rebuild_snapshot_updates
411404
uncommitted_count_during_rebuild = 0
412405

413-
def checking_rebuild(self_tx: Transaction) -> None:
406+
def checking_rebuild(self_tx: Any) -> None:
414407
nonlocal uncommitted_count_during_rebuild
415408
original_rebuild(self_tx)
416409
for producer in self_tx._snapshot_producers:
417410
uncommitted_count_during_rebuild += len(producer._uncommitted_manifests)
418411

419-
with patch.object(Transaction, "_rebuild_snapshot_updates", checking_rebuild):
412+
with patch.object(RuntimeTransaction2, "_rebuild_snapshot_updates", checking_rebuild):
420413
tbl2.append(df)
421414

422415
# After rebuild, the first attempt's manifests should be in _uncommitted_manifests

0 commit comments

Comments
 (0)