Skip to content

Commit

Permalink
Add convinient way of accessing bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
aranega committed Oct 25, 2024
1 parent e65976f commit e605626
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 8 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,28 @@ print(result)
print(result.bindings[0]['value'])
# displays: 3

print(pattern.match(a2))
result = pattern.match(a2)
print(result)
# displays: <True - [{'value': 4}]>
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.

Expand Down
17 changes: 10 additions & 7 deletions iguala/matchers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from collections.abc import MutableMapping
import itertools
from re import compile
from types import LambdaType

Expand Down Expand Up @@ -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}>"

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down
14 changes: 14 additions & 0 deletions tests/test_object_matchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}

0 comments on commit e605626

Please sign in to comment.