From 442199af5dcb63eb318c613359d651a10a623602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kriszti=C3=A1n=20Sz=C5=B1cs?= Date: Thu, 14 Dec 2023 16:10:18 +0100 Subject: [PATCH] fix(ir): raise if `Concrete.copy()` receives unexpected arguments --- ibis/common/grounds.py | 2 ++ ibis/common/tests/test_grounds.py | 34 +++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/ibis/common/grounds.py b/ibis/common/grounds.py index af5674312368..7f498b03fcdb 100644 --- a/ibis/common/grounds.py +++ b/ibis/common/grounds.py @@ -229,5 +229,7 @@ def argnames(self) -> tuple[str, ...]: def copy(self, **overrides) -> Self: kwargs = dict(zip(self.__argnames__, self.__args__)) + if unknown_args := overrides.keys() - kwargs.keys(): + raise AttributeError(f"Unexpected arguments: {unknown_args}") kwargs.update(overrides) return self.__recreate__(kwargs) diff --git a/ibis/common/tests/test_grounds.py b/ibis/common/tests/test_grounds.py index d36c7f71b3b9..9b871d874169 100644 --- a/ibis/common/tests/test_grounds.py +++ b/ibis/common/tests/test_grounds.py @@ -616,21 +616,39 @@ class Test(Annotable): assert Test(1, 2, a=3, b=4, c=5).options == {"a": 3, "b": 4, "c": 5} -def test_concrete_copy_with_variadic_argument(): - class Test(Annotable): +def test_copy_with_variadic_argument(): + class Foo(Annotable): + a = is_int + b = is_int + args = varargs(is_int) + + class Bar(Concrete): a = is_int b = is_int args = varargs(is_int) - t = Test(1, 2, 3, 4, 5) + for t in [Foo(1, 2, 3, 4, 5), Bar(1, 2, 3, 4, 5)]: + assert t.a == 1 + assert t.b == 2 + assert t.args == (3, 4, 5) + + u = t.copy(a=6, args=(8, 9, 10)) + assert u.a == 6 + assert u.b == 2 + assert u.args == (8, 9, 10) + + +def test_concrete_copy_with_unknown_argument_raise(): + class Bar(Concrete): + a = is_int + b = is_int + + t = Bar(1, 2) assert t.a == 1 assert t.b == 2 - assert t.args == (3, 4, 5) - u = t.copy(a=6, args=(8, 9, 10)) - assert u.a == 6 - assert u.b == 2 - assert u.args == (8, 9, 10) + with pytest.raises(AttributeError, match="Unexpected arguments"): + t.copy(c=3, d=4) def test_concrete_pickling_variadic_arguments():