From: Henryk Plötz Date: Wed, 8 Aug 2018 16:04:04 +0000 (+0200) Subject: Check that FinTS3Segments only have DE or DEG fields X-Git-Tag: v2.0.0~1^2~148 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6880495ec5eece31c22454c7cc3e6fe22cd5eeb;p=thirdparty%2Fpython-fints.git Check that FinTS3Segments only have DE or DEG fields --- diff --git a/fints/segments/__init__.py b/fints/segments/__init__.py index 1174381..a3a44cc 100644 --- a/fints/segments/__init__.py +++ b/fints/segments/__init__.py @@ -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 diff --git a/tests/test_models.py b/tests/test_models.py index 91b8b26..ecad679 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -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)