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 (
|
from typing import (
|
||||||
cast,
|
cast,
|
||||||
|
Hashable,
|
||||||
Iterable,
|
Iterable,
|
||||||
|
Iterator,
|
||||||
Optional,
|
Optional,
|
||||||
Pattern,
|
Pattern,
|
||||||
|
Set,
|
||||||
|
TypeVar,
|
||||||
Union,
|
Union,
|
||||||
)
|
)
|
||||||
from .beancount_types import (
|
from .beancount_types import (
|
||||||
|
@ -37,6 +41,8 @@ from .beancount_types import (
|
||||||
Transaction,
|
Transaction,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Saying Optional works around <https://github.com/python/mypy/issues/8768>.
|
||||||
|
HashT = TypeVar('HashT', bound=Optional[Hashable])
|
||||||
Postings = Iterable[data.Posting]
|
Postings = Iterable[data.Posting]
|
||||||
Regexp = Union[str, Pattern]
|
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)
|
regexp = rtutil.RT.metadata_regexp(ticket_id, first_link_only=True)
|
||||||
return filter_meta_match(postings, 'rt-id', regexp)
|
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]:
|
def remove_opening_balance_txn(entries: Entries) -> Optional[Transaction]:
|
||||||
"""Remove an opening balance transaction from entries returned by Beancount
|
"""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
|
return item1 if all_same else self.INCONSISTENT
|
||||||
|
|
||||||
def entities(self, pred: Callable[[data.Posting], bool]=bool) -> Iterator[MetaValue]:
|
def entities(self, pred: Callable[[data.Posting], bool]=bool) -> Iterator[MetaValue]:
|
||||||
seen: Set[MetaValue] = set()
|
return filters.iter_unique(
|
||||||
for post in self:
|
post.meta['entity']
|
||||||
if pred(post):
|
for post in self
|
||||||
try:
|
if pred(post) and 'entity' in post.meta
|
||||||
entity = post.meta['entity']
|
)
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
if entity not in seen:
|
|
||||||
yield entity
|
|
||||||
seen.add(entity)
|
|
||||||
|
|
||||||
def first_links(self, key: MetaKey, default: Optional[str]=None) -> Iterator[Optional[str]]:
|
def first_links(self, key: MetaKey, default: Optional[str]=None) -> Iterator[Optional[str]]:
|
||||||
return (post.meta.first_link(key, default) for post in self)
|
return (post.meta.first_link(key, default) for post in self)
|
||||||
|
|
|
@ -183,3 +183,6 @@ def test_audit_date(entry):
|
||||||
assert actual is None
|
assert actual is None
|
||||||
else:
|
else:
|
||||||
assert actual == entry.date
|
assert actual == entry.date
|
||||||
|
|
||||||
|
def test_iter_unique():
|
||||||
|
assert list(filters.iter_unique('1213231')) == list('123')
|
||||||
|
|
Loading…
Reference in a new issue