Skip to content

Commit ae7fc01

Browse files
henrykraphaelm
authored andcommitted
Implement finding
1 parent 09f1d6b commit ae7fc01

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

fints/formals.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from contextlib import suppress
44
from inspect import getmro
55
from copy import deepcopy
6-
from collections import OrderedDict
6+
from collections import OrderedDict, Iterable
77

88
from fints.utils import classproperty, SubclassesMixin, Password
99

@@ -392,11 +392,42 @@ def find_segments(self, type=None, version=None, callback=None, recurse=True):
392392
The match results of all given parameters will be AND-combined.
393393
"""
394394

395+
if type is None:
396+
type = []
397+
elif isinstance(type, str) or not isinstance(type, (list, tuple, Iterable)):
398+
type = [type]
399+
400+
if version is None:
401+
version = []
402+
elif not isinstance(version, (list, tuple, Iterable)):
403+
version = [version]
404+
405+
if callback is None:
406+
callback = lambda s: True
407+
408+
for s in self.segments:
409+
if ((not type) or any(s.header.type == t for t in type)) and \
410+
((not version) or any(s.header.version == v for v in version)) and \
411+
callback(s):
412+
yield s
413+
414+
if recurse:
415+
for name, field in s._fields.items():
416+
if isinstance(field, SegmentSequenceField):
417+
val = getattr(s, name)
418+
if val:
419+
yield from val.find_segments(type=type, version=version, callback=callback, recurse=recurse)
420+
395421
def find_segment_first(self, *args, **kwargs):
396422
"""Finds the first matching segment.
397423
398424
Same parameters as find_segments(), but only returns the first match, or None if no match is found."""
399425

426+
for m in self.find_segments(*args, **kwargs):
427+
return m
428+
429+
return None
430+
400431
class SegmentSequenceField(DataElementField):
401432
type = 'sf'
402433

tests/test_formals.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,26 @@ class A(Container):
333333

334334
with pytest.warns(UserWarning, match=r'Generic field used for type None value \[\]'):
335335
i2 = A(a=[])
336+
337+
def test_find_1():
338+
from conftest import COMPLICATED_EXAMPLE
339+
from fints.parser import FinTS3Parser
340+
from fints.segments import HNHBS1, HNHBK3
341+
342+
m = FinTS3Parser().parse_message(COMPLICATED_EXAMPLE)
343+
344+
assert len(list(m.find_segments('HNHBK'))) == 1
345+
assert len(list(m.find_segments( ['HNHBK', 'HNHBS'] ))) == 2
346+
347+
assert len(list(m.find_segments( ['HNHBK', 'HNHBS'], 1))) == 1
348+
assert len(list(m.find_segments( ['HNHBK', 'HNHBS'], (1, 3) ))) == 2
349+
350+
assert isinstance(m.find_segment_first('HNHBK'), HNHBK3)
351+
assert isinstance(m.find_segment_first('HNHBS'), HNHBS1)
352+
353+
assert m.find_segment_first('ITST') is None
354+
355+
assert len( m.find_segment_first('HITANS', 1).parameters.twostep_parameters ) == 2
356+
assert len( m.find_segment_first('HITANS', 3).parameters.twostep_parameters ) == 6
357+
358+
assert m.find_segment_first('HITANS', recurse=False) is None

0 commit comments

Comments
 (0)