Skip to content

Commit

Permalink
feat(common): allow matching on dictionaries in possibly nested patterns
Browse files Browse the repository at this point in the history
Currently only exact matches are supported, we can extend this to allow
more advanced dictionary patterns in the future.
  • Loading branch information
kszucs committed Dec 14, 2023
1 parent e4e2993 commit 1d314f7
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
2 changes: 1 addition & 1 deletion ibis/common/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -1586,7 +1586,7 @@ def pattern(obj: AnyType) -> Pattern:
elif isinstance(obj, (Deferred, Resolver)):
return Capture(obj)
elif isinstance(obj, Mapping):
raise TypeError("Cannot create a pattern from a mapping")
return EqualTo(FrozenDict(obj))
elif isinstance(obj, Sequence):
if isinstance(obj, (str, bytes)):
return EqualTo(obj)
Expand Down
23 changes: 23 additions & 0 deletions ibis/common/tests/test_patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,26 @@ def __eq__(self, other):
assert match(p, Foo(1, 2, 1)) == Foo(1, 2, 1)


def test_object_pattern_matching_dictionary_field():
a = Bar(1, FrozenDict())
b = Bar(1, {})
c = Bar(1, None)
d = Bar(1, {"foo": 1})

pattern = Object(Bar, 1, d={})
assert match(pattern, a) is a
assert match(pattern, b) is b
assert match(pattern, c) is NoMatch

pattern = Object(Bar, 1, d=None)
assert match(pattern, a) is NoMatch
assert match(pattern, c) is c

pattern = Object(Bar, 1, d={"foo": 1})
assert match(pattern, a) is NoMatch
assert match(pattern, d) is d


def test_callable_with():
def func(a, b):
return str(a) + b
Expand Down Expand Up @@ -1231,6 +1251,9 @@ def f(x):
# matching deferred to user defined functions
assert pattern(f) == Custom(f)

# matching mapping values
assert pattern({"a": 1, "b": 2}) == EqualTo(FrozenDict({"a": 1, "b": 2}))


class Term(GraphNode):
def __eq__(self, other):
Expand Down

0 comments on commit 1d314f7

Please sign in to comment.