6363
6464PROTO_CONFIG = 'firebird.base.ConfigProto'
6565
66+ def has_verticals (value : str ) -> bool :
67+ "Returns True if lines in multiline string contains leading '|' character."
68+ return any (1 for line in value .split ('\n ' ) if line .startswith ('|' ))
69+
70+ def has_leading_spaces (value : str ) -> bool :
71+ "Returns True if any line in multiline string starts with space(s)."
72+ return any (1 for line in value .split ('\n ' ) if line .startswith (' ' ))
73+
6674def unindent_verticals (value : str ) -> str :
67- """Removes trailing '|' character from each line in multiline string."""
75+ """Removes leading '|' character from each line in multiline string."""
6876 lines = []
6977 indent = None
7078 for line in value .split ('\n ' ):
@@ -81,11 +89,13 @@ def _eq(a: Any, b: Any) -> bool:
8189
8290def create_config (_cls : Type [Config ], name : str ) -> Config : # pragma: no cover
8391 """Return newly created `Config` instance. Intended to be used with `functools.partial`.
92+
93+ .. deprecated:: 1.6
94+ Will be removed in version 2.0
8495 """
8596 return _cls (name )
8697
8798# Next two functions are copied from stdlib enum module, as they were removed in Python 3.11
88-
8999def _decompose (flag , value ):
90100 """
91101 Extract all members from the value.
@@ -409,8 +419,8 @@ def get_directory_scheme(app_name: str, version: str=None, *, force_home: bool=F
409419 app_name: Application name
410420 version: Application version string
411421 force_home: When True, the general directies are always set to subdirectories of
412- `DirectoryScheme.home` directory. When False, these the home is used
413- ONLY when it's set by "<app_name>_HOME" environment variable.
422+ `DirectoryScheme.home` directory. When False, then home is used ONLY
423+ when it's set by "<app_name>_HOME" environment variable.
414424 """
415425 return {'Windows' : WindowsDirectoryScheme ,
416426 'Linux' :LinuxDirectoryScheme ,
@@ -461,7 +471,7 @@ def _get_config_lines(self, plain: bool=False) -> List[str]:
461471 file processed with `~configparser.ConfigParser`.
462472
463473 Text lines with configuration start with comment marker `;` and end with newline.
464-
474+
465475 Arguments:
466476 plain: When True, it outputs only the option value. When False, it includes also
467477 option description and other helpful information.
@@ -517,7 +527,7 @@ def validate(self) -> None:
517527 def get_config (self , * , plain : bool = False ) -> str :
518528 """Returns string containing text lines suitable for use in configuration file
519529 processed with `~configparser.ConfigParser`.
520-
530+
521531 Arguments:
522532 plain: When True, it outputs only the option value. When False, it includes also
523533 option description and other helpful information.
@@ -655,7 +665,7 @@ def get_config(self, *, plain: bool=False) -> str:
655665 for config in self .configs :
656666 if not plain :
657667 lines .append ('\n ' )
658- lines .append (config .get_config ())
668+ lines .append (config .get_config (plain = plain ))
659669 return '' .join (lines )
660670 def load_config (self , config : ConfigParser , section : str = None ) -> None :
661671 """Update configuration.
@@ -738,6 +748,17 @@ def configs(self) -> List[Config]:
738748# Options
739749class StrOption (Option [str ]):
740750 """Configuration option with string value.
751+
752+ .. versionadded:: 1.6.1
753+ Support for verticals to preserve leading whitespace.
754+
755+ Important:
756+ Multiline string values could contain significant leading whitespace, but
757+ ConfigParser multiline string values have leading whitespace removed. To circumvent
758+ this, the `StrOption` supports assignment of text values where lines start with `|`
759+ character. This character is removed, along with any number of subsequent whitespace
760+ characters that are between `|` and first non-whitespace character on first line
761+ starting with `|`.
741762 """
742763 def __init__ (self , name : str , description : str , * , required : bool = False , default : str = None ):
743764 """
@@ -764,9 +785,10 @@ def get_formatted(self) -> str:
764785 result = self ._value
765786 if '\n ' in result :
766787 lines = []
788+ indent = ' | ' if has_leading_spaces (result ) else ' '
767789 for line in result .splitlines (True ):
768790 if lines :
769- lines .append (' ' + line )
791+ lines .append (indent + line )
770792 else :
771793 lines .append (line )
772794 result = '' .join (lines )
@@ -780,6 +802,7 @@ def set_as_str(self, value: str) -> None:
780802 Raises:
781803 ValueError: When the argument is not a valid option value.
782804 """
805+ value = unindent_verticals (value )
783806 self ._value = value
784807 def get_as_str (self ) -> str :
785808 """Returns value as string.
0 commit comments