Skip to content

Commit

Permalink
Add __getattr__ for MatchResult; add bind_groups for Regex
Browse files Browse the repository at this point in the history
  • Loading branch information
scravy committed Jan 16, 2021
1 parent 7940689 commit 2bb8b22
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 22 deletions.
3 changes: 3 additions & 0 deletions apm/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ def __bool__(self):
def __getitem__(self, item):
return self._context[item]

def __getattr__(self, item):
return self._context[item]

def __contains__(self, item):
return item in self._context

Expand Down
18 changes: 1 addition & 17 deletions apm/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,11 @@
from .try_match import TryMatch


class AttributesAdapter:
def __init__(self, base):
self._base = base

def __bool__(self):
return bool(self._base)

def __getattr__(self, item):
try:
return self._base[item]
except KeyError as err:
raise AttributeError(*err.args)


class NoValue:
pass


def match(value, pattern=NoValue, *extra, multimatch=True, strict=False, argresult=False) -> Union[MatchResult, Any]:
def match(value, pattern=NoValue, *extra, multimatch=True, strict=False) -> Union[MatchResult, Any]:
ctx = MatchContext(
multimatch=multimatch,
strict=strict,
Expand All @@ -43,6 +29,4 @@ def match(value, pattern=NoValue, *extra, multimatch=True, strict=False, argresu
return action
acc = []
result = ctx.match(value, pattern, strict=strict)
if argresult:
result = AttributesAdapter(result)
return result
20 changes: 15 additions & 5 deletions apm/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,27 @@ def match(self, value, *, ctx: MatchContext, strict: bool) -> MatchResult:


class Regex(Pattern, StringPattern):
def __init__(self, regex):
def __init__(self, regex, *, bind_groups: bool = True):
self._regex: re.Pattern = re.compile(regex)
self._bind_groups = bind_groups

def match(self, value, *, ctx: MatchContext, strict: bool) -> MatchResult:
return ctx.match_if(bool(self._regex.fullmatch(value)))
result = self._regex.fullmatch(value)
if not result:
return ctx.no_match()
if self._bind_groups:
for k, v in result.groupdict().items():
ctx[k] = v
return ctx.matches()

def string_match(self, remaining, *, ctx: MatchContext) -> Optional[str]:
result = self._regex.match(remaining)
if result:
return result.group(0)
return None
if not result:
return None
if self._bind_groups:
for k, v in result.groupdict():
ctx[k] = v
return result.group(0)

@property
def regex(self) -> re.Pattern:
Expand Down
22 changes: 22 additions & 0 deletions tests/test_dict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from __future__ import annotations

import unittest

from apm import *


class ComplexMatchTest(unittest.TestCase):

def test_fibonacci(self):
def fibonacci(n):
return match(n,
1, 1,
2, 1,
_, lambda x: fibonacci(x-1) + fibonacci(x-2)
)
self.assertEqual(1, fibonacci(1))
self.assertEqual(1, fibonacci(2))
self.assertEqual(2, fibonacci(3))
self.assertEqual(3, fibonacci(4))
self.assertEqual(5, fibonacci(5))
self.assertEqual(8, fibonacci(6))

0 comments on commit 2bb8b22

Please sign in to comment.