From 96c796f312b190b786fbc9b2ae73394ccac580b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kriszti=C3=A1n=20Sz=C5=B1cs?= Date: Thu, 26 Oct 2023 18:33:30 +0200 Subject: [PATCH] fix(patterns): `Object` pattern should match on positional arguments first --- ibis/common/patterns.py | 2 +- ibis/common/tests/test_patterns.py | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/ibis/common/patterns.py b/ibis/common/patterns.py index 566b78ee8abe..7cccc3ff9204 100644 --- a/ibis/common/patterns.py +++ b/ibis/common/patterns.py @@ -1262,7 +1262,7 @@ def match(self, value, context): if self.type.match(value, context) is NoMatch: return NoMatch - patterns = {**self.kwargs, **dict(zip(value.__match_args__, self.args))} + patterns = {**dict(zip(value.__match_args__, self.args)), **self.kwargs} fields = {} changed = False diff --git a/ibis/common/tests/test_patterns.py b/ibis/common/tests/test_patterns.py index 8a80f1412191..67e507ca6894 100644 --- a/ibis/common/tests/test_patterns.py +++ b/ibis/common/tests/test_patterns.py @@ -607,6 +607,30 @@ def __coerce__(cls, other): assert p_call == Object(MyCoercibleType, 1, 2) +def test_object_pattern_matching_order(): + class Foo: + __match_args__ = ("a", "b", "c") + + def __init__(self, a, b, c): + self.a = a + self.b = b + self.c = c + + def __eq__(self, other): + return ( + type(self) == type(other) + and self.a == other.a + and self.b == other.b + and self.c == other.c + ) + + a = var("a") + p = Object(Foo, a, c=EqualTo(a)) + + assert match(p, Foo(1, 2, 3)) is NoMatch + assert match(p, Foo(1, 2, 1)) == Foo(1, 2, 1) + + def test_callable_with(): def func(a, b): return str(a) + b