From 4d58954d6407e95ba21251bd2910880529a5efbd Mon Sep 17 00:00:00 2001 From: jackylee-ch Date: Wed, 23 Sep 2026 16:06:10 +0800 Subject: [PATCH] [python] Run native commit tests only in the Rust Plan CI job The native commit tests were gated only by @requires_native (the pypaimon_rust module being importable), so the standard test job ran them against the PyPI pypaimon-rust wheel. That wheel predates the v14 commit bridge, so native commit preparation raises, is caught, and the commit falls back to Python, tripping the "must not fall back" assertion on Python 3.10-3.13 (3.6 and 3.7 have no wheel and skip). Mark these tests native_plan, as was done for native reads (#10067), so they are excluded from the wheel-based test job and run only in the Rust Plan job against the from-source paimon-rust runtime, where the commit bridge matches. --- paimon-python/pypaimon/tests/native_commit_test.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/paimon-python/pypaimon/tests/native_commit_test.py b/paimon-python/pypaimon/tests/native_commit_test.py index 67c9656c3962..e2a653b93480 100644 --- a/paimon-python/pypaimon/tests/native_commit_test.py +++ b/paimon-python/pypaimon/tests/native_commit_test.py @@ -33,8 +33,13 @@ from pypaimon.write.table_write import StreamTableWrite -requires_native = pytest.mark.skipif( - not native_commit_available(), reason='pypaimon-rust runtime required') +def requires_native(test): + # Native commit needs the from-source paimon-rust runtime built in the Rust + # Plan CI job; the PyPI pypaimon-rust wheel used by the standard test job + # predates the commit bridge. Route these like the other native_plan tests. + test = pytest.mark.native_plan(test) + return pytest.mark.skipif( + not native_commit_available(), reason='pypaimon-rust runtime required')(test) def _table(tmp_path, mode='append', backend='filesystem'): @@ -223,7 +228,7 @@ def test_native_overwrite_normalizes_python_boolean_option(tmp_path, value): commit.close() -@pytest.mark.parametrize('native', [False, True]) +@pytest.mark.parametrize('native', [False, pytest.param(True, marks=pytest.mark.native_plan)]) @pytest.mark.parametrize('case', ['unpartitioned', 'static-empty', 'static-missing', 'dynamic-empty']) def test_empty_overwrite_records_java_snapshot(tmp_path, native, case): if native and not native_commit_available(): @@ -393,7 +398,7 @@ def test_snapshot_properties_select_python_before_native(tmp_path, properties, o commit.close() -@pytest.mark.parametrize('warmup', [False, True]) +@pytest.mark.parametrize('warmup', [False, pytest.param(True, marks=pytest.mark.native_plan)]) def test_callbacks_added_after_construction_select_python(tmp_path, warmup): if warmup and not native_commit_available(): pytest.skip('native warmup requires the commit bindings')