]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Add a bad hack to RepresentableEnum to get docstrings on enum members. Make the docum...
authorHenryk Plötz <henryk@ploetzli.ch>
Tue, 14 Aug 2018 17:16:01 +0000 (19:16 +0200)
committerRaphael Michel <mail@raphaelmichel.de>
Mon, 3 Dec 2018 18:34:29 +0000 (19:34 +0100)
fints/fields.py
fints/formals.py
fints/types.py
fints/utils.py

index dac8442d25aa3fb30359c344aa45d6c81ff6c3c3..62327089fd80ba93894269bea9394c3f5e6761ec 100644 (file)
@@ -85,6 +85,13 @@ class Field:
 
         return self._render_value(value)
 
+    def _inline_doc_comment(self, value):
+        if self.__doc__:
+            d = self.__doc__.splitlines()[0].strip()
+            if d:
+                return " # {}".format(d)
+        return ""
+
 class TypedField(Field, SubclassesMixin):
     flat_length = 1
 
@@ -257,6 +264,18 @@ class CodeField(AlphanumericField):
             retval = str(value.value)
         return super()._render_value(retval)
 
+    def _inline_doc_comment(self, value):
+        retval = super()._inline_doc_comment(value)
+        if self._enum:
+            addendum = value.__doc__
+            if addendum and not addendum is value.__class__.__doc__:
+                if not retval:
+                    retval = " # "
+                else:
+                    retval = retval + ": "
+                retval = retval + addendum
+        return retval
+
 class CountryField(FixedLengthMixin, DigitsField):
     type = 'ctr'
     _FIXED_LENGTH = [3]
index 65b0929a06a97bb864b5f13110400225eb3a5f66..4f88bff70ce03d108a8a33e27ff7b4966c4f9488 100644 (file)
@@ -300,9 +300,9 @@ class AccountInternational(DataElementGroup):
     bank_identifier = DataElementGroupField(type=BankIdentifier)
 
 class SecurityRole(RepresentableEnum):
-    ISS = '1'
-    CON = '3'
-    WIT = '4'
+    ISS = '1' #: Erfasser, Erstsignatur
+    CON = '3' #: Unterstützer, Zweitsignatur
+    WIT = '4' #: Zeuge/Übermittler, nicht Erfasser
 
 class CompressionFunction(RepresentableEnum):
     NULL = '0' #: Keine Kompression
index e2c07d58503fc0194e741c44d51771c8f29788b3..5174aef34f58e090de4d682e968e62cbeb2e2856 100644 (file)
@@ -67,13 +67,13 @@ class ValueList:
     def __repr__(self):
         return "{!r}".format(list(self))
 
-    def print_nested(self, stream=None, level=0, indent="    ", prefix="", first_level_indent=True, trailer=""):
+    def print_nested(self, stream=None, level=0, indent="    ", prefix="", first_level_indent=True, trailer="", print_doc=True, first_line_suffix=""):
         import sys
         stream = stream or sys.stdout
 
         stream.write(
             ( (prefix + level*indent) if first_level_indent else "")
-            + "[\n"
+            + "[{}\n".format(first_line_suffix)
         )
         for val in self:
             if not hasattr( getattr(val, 'print_nested', None), '__call__'):
@@ -81,7 +81,7 @@ class ValueList:
                     (prefix + (level+1)*indent) + "{!r},\n".format(val)
                 )
             else:
-                val.print_nested(stream=stream, level=level+2, indent=indent, prefix=prefix, trailer=",")
+                val.print_nested(stream=stream, level=level+2, indent=indent, prefix=prefix, trailer=",", print_doc=print_doc)
         stream.write( (prefix + level*indent) + "]{}\n".format(trailer) )
 
 class SegmentSequence:
@@ -102,15 +102,17 @@ class SegmentSequence:
     def __repr__(self):
         return "{}.{}({!r})".format(self.__class__.__module__, self.__class__.__name__, self.segments)
 
-    def print_nested(self, stream=None, level=0, indent="    ", prefix="", first_level_indent=True, trailer=""):
+    def print_nested(self, stream=None, level=0, indent="    ", prefix="", first_level_indent=True, trailer="", print_doc=True, first_line_suffix=""):
         import sys
         stream = stream or sys.stdout
         stream.write(
             ( (prefix + level*indent) if first_level_indent else "")
-            + "{}.{}([".format(self.__class__.__module__, self.__class__.__name__) + "\n"
+            + "{}.{}([".format(self.__class__.__module__, self.__class__.__name__)
+            + first_line_suffix
+            + "\n"
         )
         for segment in self.segments:
-            segment.print_nested(stream=stream, level=level+1, indent=indent, prefix=prefix, first_level_indent=True, trailer=",")
+            segment.print_nested(stream=stream, level=level+1, indent=indent, prefix=prefix, first_level_indent=True, trailer=",", print_doc=print_doc)
         stream.write( (prefix + level*indent) + "]){}\n".format(trailer) )
 
     def find_segments(self, query=None, version=None, callback=None, recurse=True):
@@ -243,7 +245,7 @@ class Container(metaclass=ContainerMeta):
             )
         )
 
-    def print_nested(self, stream=None, level=0, indent="    ", prefix="", first_level_indent=True, trailer=""):
+    def print_nested(self, stream=None, level=0, indent="    ", prefix="", first_level_indent=True, trailer="", print_doc=True, first_line_suffix=""):
         """Structured nested print of the object to the given stream.
 
         The print-out is eval()able to reconstruct the object."""
@@ -252,17 +254,23 @@ class Container(metaclass=ContainerMeta):
 
         stream.write(
             ( (prefix + level*indent) if first_level_indent else "")
-            + "{}.{}(".format(self.__class__.__module__, self.__class__.__name__) + "\n"
+            + "{}.{}(".format(self.__class__.__module__, self.__class__.__name__)
+            + first_line_suffix
+            + "\n"
         )
         for name, value in self._repr_items:
             val = getattr(self, name)
+            if print_doc:
+                docstring = self._fields[name]._inline_doc_comment(val)
+            else:
+                docstring = ""
             if not hasattr( getattr(val, 'print_nested', None), '__call__'):
                 stream.write(
-                    (prefix + (level+1)*indent) + "{} = {!r},\n".format(name, val)
+                    (prefix + (level+1)*indent) + "{} = {!r},{}\n".format(name, val, docstring)
                 )
             else:
                 stream.write(
                     (prefix + (level+1)*indent) + "{} = ".format(name)
                 )
-                val.print_nested(stream=stream, level=level+2, indent=indent, prefix=prefix, first_level_indent=False, trailer=",")
+                val.print_nested(stream=stream, level=level+2, indent=indent, prefix=prefix, first_level_indent=False, trailer=",", print_doc=print_doc, first_line_suffix=docstring)
         stream.write( (prefix + level*indent) + "){}\n".format(trailer) )
index 440f8cd51edcab38d876b6fe4bec24e6e1275517..f92faada42cd29977843d9a568fbfb09ab2420cc 100644 (file)
@@ -1,3 +1,4 @@
+import inspect
 import re
 from contextlib import contextmanager
 from datetime import datetime
@@ -118,10 +119,10 @@ class ShortReprMixin:
             )
         )
 
-    def print_nested(self, stream=None, level=0, indent="    ", prefix="", first_level_indent=True, trailer=""):
+    def print_nested(self, stream=None, level=0, indent="    ", prefix="", first_level_indent=True, trailer="", print_doc=True, first_line_suffix=""):
         stream.write(
             ( (prefix + level*indent) if first_level_indent else "")
-            + "{!r}{}\n".format(self, trailer)
+            + "{!r}{}{}\n".format(self, trailer, first_line_suffix)
         )
 
 
@@ -250,9 +251,30 @@ class Password(str):
         return self.__str__().replace(*args, **kwargs)
 
 class RepresentableEnum(Enum):
+    def __init__(self, *args, **kwargs):
+        Enum.__init__(self)
+
+        # Hack alert: Try to parse the docstring from the enum source, if available. Fail softly.
+        # FIXME Needs test
+        try:
+            val_1 = val_2 = repr(args[0])
+            if val_1.startswith("'"):
+                val_2 = '"' + val_1[1:-1] + '"'
+            elif val_1.startswith('"'):
+                val_2 = "'" + val_1[1:-1] + "'"
+            regex = re.compile(r"^.*?\S+\s*=\s*(?:(?:{})|(?:{}))\s*#:\s*(\S.*)$".format(
+                        re.escape(val_1), re.escape(val_2)))
+            for line in inspect.getsourcelines(self.__class__)[0]:
+                m = regex.match(line)
+                if m:
+                    self.__doc__ = m.group(1).strip()
+                    break
+        except:
+            raise
+
     def __repr__(self):
         return "{}.{}.{}".format(self.__class__.__module__, self.__class__.__name__, self.name)
 
     def __str__(self):
         return self.value
-    
+