Skip to content

Commit a688049

Browse files
henrykraphaelm
authored andcommitted
Check that FinTS3Segments only have DE or DEG fields
1 parent 4916b18 commit a688049

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

fints/segments/__init__.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
import re
22

3-
from fints.formals import Container, SegmentHeader, DataElementGroupField, DataElementField, ReferenceMessage, SegmentSequenceField, SecurityProfile, SecurityIdentificationDetails, SecurityDateTime, EncryptionAlgorithm, KeyName, Certificate, HashAlgorithm, SignatureAlgorithm, UserDefinedSignature, Response
3+
from fints.formals import Container, ContainerMeta, SegmentHeader, DataElementGroupField, DataElementField, ReferenceMessage, SegmentSequenceField, SecurityProfile, SecurityIdentificationDetails, SecurityDateTime, EncryptionAlgorithm, KeyName, Certificate, HashAlgorithm, SignatureAlgorithm, UserDefinedSignature, Response
44

55
from fints.utils import classproperty, SubclassesMixin
66

77
TYPE_VERSION_RE = re.compile(r'^([A-Z]+)(\d+)$')
88

9-
class FinTS3Segment(Container, SubclassesMixin):
9+
class FinTS3SegmentMeta(ContainerMeta):
10+
@staticmethod
11+
def _check_fields_recursive(instance):
12+
for name, field in instance._fields.items():
13+
if not isinstance(field, (DataElementField, DataElementGroupField)):
14+
raise TypeError("{}={!r} is not DataElementField or DataElementGroupField".format(name, field))
15+
if isinstance(field, DataElementGroupField):
16+
FinTS3SegmentMeta._check_fields_recursive(field.type)
17+
18+
def __new__(cls, name, bases, classdict):
19+
retval = super().__new__(cls, name, bases, classdict)
20+
FinTS3SegmentMeta._check_fields_recursive(retval)
21+
return retval
22+
23+
class FinTS3Segment(Container, SubclassesMixin, metaclass=FinTS3SegmentMeta):
1024
header = DataElementGroupField(type=SegmentHeader)
1125

1226
@classproperty

tests/test_models.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,24 @@ def test_metaclass_foo():
1010
assert list(a._fields) == ['header', 'message_size', 'hbci_version', 'dialogue_id', 'message_number', 'reference_message']
1111
assert a._fields['header']
1212

13+
def test_fints3_only_de_and_deg():
14+
from fints.formals import Field, Container, DataElementGroupField, ContainerField
15+
16+
with pytest.raises(TypeError, match="b=.* is not DataElementField or DataElementGroupField"):
17+
class Foo(FinTS3Segment):
18+
a = NumericField()
19+
b = Field()
20+
21+
class A(Container):
22+
a = Field()
23+
24+
class B(Container):
25+
b = DataElementGroupField(type=A)
26+
27+
with pytest.raises(TypeError, match="a=.* is not DataElementField or DataElementGroupField"):
28+
class Foo(FinTS3Segment):
29+
c = DataElementGroupField(type=B)
30+
1331
def test_descriptor_subclassing():
1432
a = DataElementField(type='an')
1533
assert isinstance(a, AlphanumericField)

0 commit comments

Comments
 (0)