From 4420873c967e2d029ef651a6d274ea587b08da10 2020-04-22 14:34:55 From: Brett Smith Date: 2020-04-22 14:34:55 Subject: [PATCH] filters: Add filter_meta_match function. --- diff --git a/conservancy_beancount/filters.py b/conservancy_beancount/filters.py index 7168eb9e32d07fcedc86e9240413767808426499..b63a9f7a5c7c903d2599af2c3319cab338adb975 100644 --- a/conservancy_beancount/filters.py +++ b/conservancy_beancount/filters.py @@ -14,10 +14,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import re + from . import data from typing import ( Iterable, + Pattern, + Union, ) from .beancount_types import ( MetaKey, @@ -25,6 +29,7 @@ from .beancount_types import ( ) Postings = Iterable[data.Posting] +Regexp = Union[str, Pattern] def filter_meta_equal(postings: Postings, key: MetaKey, value: MetaValue) -> Postings: for post in postings: @@ -33,3 +38,11 @@ def filter_meta_equal(postings: Postings, key: MetaKey, value: MetaValue) -> Pos yield post except KeyError: pass + +def filter_meta_match(postings: Postings, key: MetaKey, regexp: Regexp) -> Postings: + for post in postings: + try: + if re.search(regexp, post.meta[key]): + yield post + except (KeyError, TypeError): + pass diff --git a/tests/test_filters.py b/tests/test_filters.py index 502b29daffe16453cf8367d3af9caf91a178f207..79bdeb98877a8bb9ff26279969e774e8a415841e 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -81,3 +81,17 @@ def test_filter_meta_equal(cc_txn_pair, key, value, expected_indexes): postings = data.Posting.from_entries(cc_txn_pair) actual = filters.filter_meta_equal(postings, key, value) check_filter(actual, cc_txn_pair, expected_indexes) + +@pytest.mark.parametrize('key,regexp,expected_indexes', [ + ('entity', '^Smith-', range(5)), + ('receipt', r'\.pdf$', range(5)), + ('receipt', 'Receipt', range(3)), + ('statement', '.', [4]), + ('metadate', 'foo', ()), + ('BadKey', '.', ()), + ('emptykey', '.', ()), +]) +def test_filter_meta_match(cc_txn_pair, key, regexp, expected_indexes): + postings = data.Posting.from_entries(cc_txn_pair) + actual = filters.filter_meta_match(postings, key, regexp) + check_filter(actual, cc_txn_pair, expected_indexes)