filters: Add iter_unique() function.
This commit is contained in:
parent
9c33517583
commit
e3dceb601c
3 changed files with 21 additions and 11 deletions
|
@ -24,9 +24,13 @@ from . import rtutil
|
|||
|
||||
from typing import (
|
||||
cast,
|
||||
Hashable,
|
||||
Iterable,
|
||||
Iterator,
|
||||
Optional,
|
||||
Pattern,
|
||||
Set,
|
||||
TypeVar,
|
||||
Union,
|
||||
)
|
||||
from .beancount_types import (
|
||||
|
@ -37,6 +41,8 @@ from .beancount_types import (
|
|||
Transaction,
|
||||
)
|
||||
|
||||
# Saying Optional works around <https://github.com/python/mypy/issues/8768>.
|
||||
HashT = TypeVar('HashT', bound=Optional[Hashable])
|
||||
Postings = Iterable[data.Posting]
|
||||
Regexp = Union[str, Pattern]
|
||||
|
||||
|
@ -72,6 +78,13 @@ def filter_for_rt_id(postings: Postings, ticket_id: Union[int, str]) -> Postings
|
|||
regexp = rtutil.RT.metadata_regexp(ticket_id, first_link_only=True)
|
||||
return filter_meta_match(postings, 'rt-id', regexp)
|
||||
|
||||
def iter_unique(seq: Iterable[HashT]) -> Iterator[HashT]:
|
||||
seen: Set[HashT] = set()
|
||||
for item in seq:
|
||||
if item not in seen:
|
||||
seen.add(item)
|
||||
yield item
|
||||
|
||||
def remove_opening_balance_txn(entries: Entries) -> Optional[Transaction]:
|
||||
"""Remove an opening balance transaction from entries returned by Beancount
|
||||
|
||||
|
|
|
@ -207,17 +207,11 @@ class AccrualPostings(core.RelatedPostings):
|
|||
return item1 if all_same else self.INCONSISTENT
|
||||
|
||||
def entities(self, pred: Callable[[data.Posting], bool]=bool) -> Iterator[MetaValue]:
|
||||
seen: Set[MetaValue] = set()
|
||||
for post in self:
|
||||
if pred(post):
|
||||
try:
|
||||
entity = post.meta['entity']
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
if entity not in seen:
|
||||
yield entity
|
||||
seen.add(entity)
|
||||
return filters.iter_unique(
|
||||
post.meta['entity']
|
||||
for post in self
|
||||
if pred(post) and 'entity' in post.meta
|
||||
)
|
||||
|
||||
def first_links(self, key: MetaKey, default: Optional[str]=None) -> Iterator[Optional[str]]:
|
||||
return (post.meta.first_link(key, default) for post in self)
|
||||
|
|
|
@ -183,3 +183,6 @@ def test_audit_date(entry):
|
|||
assert actual is None
|
||||
else:
|
||||
assert actual == entry.date
|
||||
|
||||
def test_iter_unique():
|
||||
assert list(filters.iter_unique('1213231')) == list('123')
|
||||
|
|
Loading…
Reference in a new issue