From: Henryk Plötz Date: Sat, 11 Aug 2018 14:05:47 +0000 (+0200) Subject: Implement finding X-Git-Tag: v2.0.0~1^2~122 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ae7fc01b0944f640e0dedd887572a60495d45846;p=thirdparty%2Fpython-fints.git Implement finding --- diff --git a/fints/formals.py b/fints/formals.py index a6a6899..29f7715 100644 --- a/fints/formals.py +++ b/fints/formals.py @@ -3,7 +3,7 @@ import warnings from contextlib import suppress from inspect import getmro from copy import deepcopy -from collections import OrderedDict +from collections import OrderedDict, Iterable from fints.utils import classproperty, SubclassesMixin, Password @@ -392,11 +392,42 @@ class SegmentSequence: The match results of all given parameters will be AND-combined. """ + if type is None: + type = [] + elif isinstance(type, str) or not isinstance(type, (list, tuple, Iterable)): + type = [type] + + if version is None: + version = [] + elif not isinstance(version, (list, tuple, Iterable)): + version = [version] + + if callback is None: + callback = lambda s: True + + for s in self.segments: + if ((not type) or any(s.header.type == t for t in type)) and \ + ((not version) or any(s.header.version == v for v in version)) and \ + callback(s): + yield s + + if recurse: + for name, field in s._fields.items(): + if isinstance(field, SegmentSequenceField): + val = getattr(s, name) + if val: + yield from val.find_segments(type=type, version=version, callback=callback, recurse=recurse) + def find_segment_first(self, *args, **kwargs): """Finds the first matching segment. Same parameters as find_segments(), but only returns the first match, or None if no match is found.""" + for m in self.find_segments(*args, **kwargs): + return m + + return None + class SegmentSequenceField(DataElementField): type = 'sf' diff --git a/tests/test_formals.py b/tests/test_formals.py index 90b60de..9053670 100644 --- a/tests/test_formals.py +++ b/tests/test_formals.py @@ -333,3 +333,26 @@ def test_container_generic(): with pytest.warns(UserWarning, match=r'Generic field used for type None value \[\]'): i2 = A(a=[]) + +def test_find_1(): + from conftest import COMPLICATED_EXAMPLE + from fints.parser import FinTS3Parser + from fints.segments import HNHBS1, HNHBK3 + + m = FinTS3Parser().parse_message(COMPLICATED_EXAMPLE) + + assert len(list(m.find_segments('HNHBK'))) == 1 + assert len(list(m.find_segments( ['HNHBK', 'HNHBS'] ))) == 2 + + assert len(list(m.find_segments( ['HNHBK', 'HNHBS'], 1))) == 1 + assert len(list(m.find_segments( ['HNHBK', 'HNHBS'], (1, 3) ))) == 2 + + assert isinstance(m.find_segment_first('HNHBK'), HNHBK3) + assert isinstance(m.find_segment_first('HNHBS'), HNHBS1) + + assert m.find_segment_first('ITST') is None + + assert len( m.find_segment_first('HITANS', 1).parameters.twostep_parameters ) == 2 + assert len( m.find_segment_first('HITANS', 3).parameters.twostep_parameters ) == 6 + + assert m.find_segment_first('HITANS', recurse=False) is None