]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Check that FinTS3Segments only have DE or DEG fields
authorHenryk Plötz <henryk@ploetzli.ch>
Wed, 8 Aug 2018 16:04:04 +0000 (18:04 +0200)
committerRaphael Michel <mail@raphaelmichel.de>
Mon, 3 Dec 2018 18:34:17 +0000 (19:34 +0100)
fints/segments/__init__.py
tests/test_models.py

index 117438147cec675742056a7c032a191f5e87a5c8..a3a44cce51db3f537857be1bfd409dcdcab6c25a 100644 (file)
@@ -1,12 +1,26 @@
 import re
 
-from fints.formals import Container, SegmentHeader, DataElementGroupField, DataElementField, ReferenceMessage, SegmentSequenceField, SecurityProfile, SecurityIdentificationDetails, SecurityDateTime, EncryptionAlgorithm, KeyName, Certificate, HashAlgorithm, SignatureAlgorithm, UserDefinedSignature, Response
+from fints.formals import Container, ContainerMeta, SegmentHeader, DataElementGroupField, DataElementField, ReferenceMessage, SegmentSequenceField, SecurityProfile, SecurityIdentificationDetails, SecurityDateTime, EncryptionAlgorithm, KeyName, Certificate, HashAlgorithm, SignatureAlgorithm, UserDefinedSignature, Response
 
 from fints.utils import classproperty, SubclassesMixin
 
 TYPE_VERSION_RE = re.compile(r'^([A-Z]+)(\d+)$')
 
-class FinTS3Segment(Container, SubclassesMixin):
+class FinTS3SegmentMeta(ContainerMeta):
+    @staticmethod
+    def _check_fields_recursive(instance):
+        for name, field in instance._fields.items():
+            if not isinstance(field, (DataElementField, DataElementGroupField)):
+                raise TypeError("{}={!r} is not DataElementField or DataElementGroupField".format(name, field))
+            if isinstance(field, DataElementGroupField):
+                FinTS3SegmentMeta._check_fields_recursive(field.type)
+
+    def __new__(cls, name, bases, classdict):
+        retval = super().__new__(cls, name, bases, classdict)
+        FinTS3SegmentMeta._check_fields_recursive(retval)
+        return retval
+
+class FinTS3Segment(Container, SubclassesMixin, metaclass=FinTS3SegmentMeta):
     header = DataElementGroupField(type=SegmentHeader)
 
     @classproperty
index 91b8b26f8121d695c8bb2addc24c69c05d8c1e24..ecad6790f317ce68031688743e87b6ee2c87a243 100644 (file)
@@ -10,6 +10,24 @@ def test_metaclass_foo():
     assert list(a._fields) == ['header', 'message_size', 'hbci_version', 'dialogue_id', 'message_number', 'reference_message']
     assert a._fields['header']
 
+def test_fints3_only_de_and_deg():
+    from fints.formals import Field, Container, DataElementGroupField, ContainerField
+
+    with pytest.raises(TypeError, match="b=.* is not DataElementField or DataElementGroupField"):
+        class Foo(FinTS3Segment):
+            a = NumericField()
+            b = Field()
+
+    class A(Container):
+        a = Field()
+
+    class B(Container):
+        b = DataElementGroupField(type=A)
+
+    with pytest.raises(TypeError, match="a=.* is not DataElementField or DataElementGroupField"):
+        class Foo(FinTS3Segment):
+            c = DataElementGroupField(type=B)
+
 def test_descriptor_subclassing():
     a = DataElementField(type='an')
     assert isinstance(a, AlphanumericField)