Files
Bhavana Sundar c85075e427 fix(python): make commit control args keyword-only across mutating APIs (#4283)
# Description

Added `deprecate_positional_commit_args` to `_util.py` as a helper that
preserves legacy positional behavior per method, emits a
DeprecationWarning, rejects invalid usage, and normalizes to canonical
commit_properties-first order.

Wired into all public mutating APIs across `table.py`,
`writer/convert_to.py`, and `transaction.py`. `write_deltalake` params
reordered to canonical order (already keyword-only, no shim needed).
`restore` left untouched (already keyword-only).

Unit tests added in `tests/test_util.py`.
# Related Issue(s)

- closes #4252 

Notes:
- `_internal.pyi stubs are already in canonical order
- `create()` and `vacuum()` handle legacy positional args inline (they
had extra trailing params beyond the commit args, so the shared helper
is bypassed for those two)
Follow-up PR will make all APIs keyword-only and remove the
compatibility path

AI disclosure: I used Claude as a coding assistant to help map out
affected methods. I reviewed every modification, ran the full test suite
locally, and understand each change made.

---------

Signed-off-by: Bhavana Sundar <bhavana7899@gmail.com>
Co-authored-by: Ethan Urbanski <ethanurbanski@gmail.com>
2026-03-18 23:49:12 -04:00

57 lines
1.8 KiB
Python

import pytest
from deltalake._util import deprecate_positional_commit_args
def test_no_args_returns_kwargs_unchanged():
commit_props = object()
post_hook_props = object()
result = deprecate_positional_commit_args("foo", (), commit_props, post_hook_props)
assert result == (commit_props, post_hook_props)
def test_positional_arg_emits_deprecation_warning():
commit_props = object()
with pytest.warns(DeprecationWarning, match="foo\\(\\)"):
result = deprecate_positional_commit_args("foo", (commit_props,), None, None)
assert result == (commit_props, None)
def test_positional_args_canonical_order():
commit_props = object()
post_hook_props = object()
with pytest.warns(DeprecationWarning):
result = deprecate_positional_commit_args(
"foo", (commit_props, post_hook_props), None, None
)
assert result == (commit_props, post_hook_props)
def test_positional_args_reversed_legacy_order():
commit_props = object()
post_hook_props = object()
with pytest.warns(DeprecationWarning):
result = deprecate_positional_commit_args(
"foo",
(post_hook_props, commit_props),
None,
None,
legacy_order=("post_commithook_properties", "commit_properties"),
)
assert result == (commit_props, post_hook_props)
def test_extra_positional_args_raises_type_error():
with pytest.raises(TypeError, match="takes at most 2"):
deprecate_positional_commit_args(
"foo", (object(), object(), object()), None, None
)
def test_keyword_and_positional_conflict_raises_type_error():
commit_props = object()
with pytest.raises(TypeError, match="multiple values for 'commit_properties'"):
deprecate_positional_commit_args(
"foo", (commit_props,), commit_properties=commit_props
)