From e60562641aca2bc5e45c5857db471c08f8735f17 Mon Sep 17 00:00:00 2001 From: aranega Date: Fri, 25 Oct 2024 10:25:47 -0600 Subject: [PATCH] Add convinient way of accessing bindings --- README.md | 18 +++++++++++++++++- iguala/matchers.py | 17 ++++++++++------- tests/test_object_matchers.py | 14 ++++++++++++++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d3ad73e..ca1d5a5 100644 --- a/README.md +++ b/README.md @@ -246,12 +246,28 @@ print(result) print(result.bindings[0]['value']) # displays: 3 -print(pattern.match(a2)) +result = pattern.match(a2) +print(result) # displays: print(result.bindings[0]['value']) # displays: 4 ``` +There is a convenient way of accessing a specific varible and get its value in all the contexts using the access to dict syntax. +This allows you to get a list of the value of a variable in each context. +You can also add a specific list type to create a result of this collection type instead of a pure list. + +```python +# considering the previous example +result = pattern.match(a1) +print(result["value"]) +# displays: [3] + +print(result["value"::set]) +# displays: {3} +``` + + Each right side of the property dictionnary that starts with an `@` means that it's a variable. If the name is found again in the pattern, then, it means that the data needs to have the same value for those variable in those positions. diff --git a/iguala/matchers.py b/iguala/matchers.py index 96338c2..edca77a 100644 --- a/iguala/matchers.py +++ b/iguala/matchers.py @@ -1,5 +1,4 @@ from collections.abc import MutableMapping -import itertools from re import compile from types import LambdaType @@ -37,6 +36,11 @@ def analyse_contexts(self): def bindings(self): return [c.bindings for c in self.contexts] + def __getitem__(self, key): + if isinstance(key, slice): + return key.step([binding[key.start] for binding in self.bindings if key.start in binding]) + return [binding[key] for binding in self.bindings if key in binding] + def __str__(self): return f"<{self.is_match} - {self.bindings}>" @@ -149,10 +153,6 @@ def is_collection_matcher(self): def is_list_wildcard(self): return self.matcher.is_list_wildcard - def __rmatmul__(self, other): - self.matcher = as_matcher(other) - return self - def match_context(self, obj, context): context[self.alias] = obj return self.matcher.match_context(obj, context) @@ -584,7 +584,7 @@ def as_matcher(obj): return LiteralMatcher(obj) if obj is Ellipsis: return ListWildcardMatcher("") - if isinstance(obj, (list, tuple)): + if isinstance(obj, list): return SequenceMatcher(obj) if isinstance(obj, dict): return DictMatcher(obj) @@ -594,7 +594,10 @@ def as_matcher(obj): return RangeMatcher(obj) if isinstance(obj, type): return ObjectMatcher(obj, {}) - return obj.as_matcher() + try: + return obj.as_matcher() + except AttributeError: + return IdentityMatcher(obj) cond = ConditionalMatcher diff --git a/tests/test_object_matchers.py b/tests/test_object_matchers.py index 5abd19f..4ba0556 100644 --- a/tests/test_object_matchers.py +++ b/tests/test_object_matchers.py @@ -121,3 +121,17 @@ def test_lambda_matcher_desorder4(): result = pattern.match(obj_test) assert result.is_match is False + + +def test_results_binding_access(): + pattern = (~match(object))[ + "y": as_matcher(lambda x: x * 2) @ "y", + "x": "@x", + ] + result = pattern.match(obj_test) + assert result.is_match is True + + assert result["x"] == [4] + assert result["y"] == [8] + + assert result["x"::set] == {4} \ No newline at end of file