]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Implement finding
authorHenryk Plötz <henryk@ploetzli.ch>
Sat, 11 Aug 2018 14:05:47 +0000 (16:05 +0200)
committerRaphael Michel <mail@raphaelmichel.de>
Mon, 3 Dec 2018 18:34:17 +0000 (19:34 +0100)
fints/formals.py
tests/test_formals.py

index a6a6899f76e7b3264f10a037703a2c2989bda32d..29f77155c4953a3378b0ddd049796695d22df834 100644 (file)
@@ -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'
 
index 90b60de923c2f6276f393d7f1be66096bc90bb1b..90536703ba187fc79cc55fd0c6de94ef08b819f0 100644 (file)
@@ -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