@@ -378,6 +378,8 @@ def _check_value(self, value: T) -> None:
378378 raise TypeError (f"Option '{ self .name } ' value must be a "
379379 f"'{ self .datatype .__name__ } ',"
380380 f" not '{ type (value ).__name__ } '" )
381+ def _get_value_description (self ) -> str :
382+ return f'{ self .datatype .__name__ } \n '
381383 def _get_config_lines (self ) -> List [str ]:
382384 """Returns list of strings containing text lines suitable for use in configuration
383385 file processed with `~configparser.ConfigParser`.
@@ -388,18 +390,16 @@ def _get_config_lines(self) -> List[str]:
388390 This function is intended for internal use. To get string describing current
389391 configuration that is suitable for configuration files, use `get_config` method.
390392 """
391- lines = [f"; { self .name } \n " ,
392- f"; { '-' * len (self .name )} \n " ,
393- ";\n " ,
394- f"; data type: { self .datatype .__name__ } \n " ,
395- ";\n " ]
393+ hdr = f"{ self .name } [{ self .datatype .__name__ } ][{ 'REQUIRED' if self .required else 'optional' } ]"
394+ lines = []
396395 if self .required :
397- description = '[REQUIRED] ' + self .description
398- else :
399- description = '[optional] ' + self .description
400- for line in description .split ('\n ' ):
396+ lines .append ("; REQUIRED option.\n " )
397+ for line in self .description .strip ().splitlines ():
401398 lines .append (f"; { line } \n " )
402- lines .append (';\n ' )
399+ first = True
400+ for line in self ._get_value_description ().splitlines ():
401+ lines .append (f"; { 'Type: ' if first else '' } { line } \n " )
402+ first = False
403403 value = self .get_value ()
404404 nodef = ';' if value == self .default else ''
405405 value = '<UNDEFINED>' if value is None else self .get_formatted ()
@@ -508,15 +508,17 @@ class Config:
508508 Important:
509509 Descendants must define individual options and sub configs as instance attributes.
510510 """
511- def __init__ (self , name : str , * , optional : bool = False ):
511+ def __init__ (self , name : str , * , optional : bool = False , description : str = None ):
512512 """
513513 Arguments:
514514 name: Name associated with Config (default section name).
515515 optional: Whether config is optional (False) or mandatory (True) for
516516 configuration file (see `.load_config()` for details).
517+ description: Optional configuration description. Can span multiple lines.
517518 """
518519 self ._name : str = name
519520 self ._optional : bool = optional
521+ self ._description : str = description if description is not None else self .__doc__
520522 def validate (self ) -> None :
521523 """Checks whether:
522524 - all required options have value other than None.
@@ -542,17 +544,16 @@ def clear(self, *, to_default: bool=True) -> None:
542544 def get_description (self ) -> str :
543545 """Configuration description. Can span multiple lines.
544546
545- Note: Default implementation returns class doc string.
547+ Note: If description is not provided on instance creation, class doc string.
546548 """
547- return self .__doc__
549+ return '' if self ._description is None else self . _description
548550 def get_config (self ) -> str :
549551 """Returns string containing text lines suitable for use in configuration file
550552 processed with `~configparser.ConfigParser`.
551553 """
552554 lines = [f'[{ self .name } ]\n ' , ';\n ' ]
553- for line in self .get_description ().splitlines ():
555+ for line in self .get_description ().strip (). splitlines ():
554556 lines .append (f"; { line } \n " )
555- lines .append (';\n ' )
556557 for option in self .options :
557558 lines .append ('\n ' )
558559 lines .append (option .get_config ())
@@ -1180,15 +1181,8 @@ def __init__(self, name: str, enum_class: Enum, description: str, *, required: b
11801181 self .allowed : Sequence = enum_class if allowed is None else allowed
11811182 self ._members : Dict = {i .name .lower (): i for i in self .allowed }
11821183 super ().__init__ (name , enum_class , description , required , default )
1183- def get_config (self ) -> str :
1184- """Returns string containing text lines suitable for use in configuration file
1185- processed with `~configparser.ConfigParser`.
1186-
1187- Text lines with configuration start with comment marker ; and end with newline.
1188- """
1189- lines : List = super ()._get_config_lines ()
1190- lines .insert (4 , f"; values: { ', ' .join (x .name .lower () for x in self .allowed )} \n " )
1191- return '' .join (lines )
1184+ def _get_value_description (self ) -> str :
1185+ return f"enum [{ ', ' .join (x .name .lower () for x in self .allowed )} ]\n "
11921186 def clear (self , * , to_default : bool = True ) -> None :
11931187 """Clears the option value.
11941188
@@ -1282,15 +1276,8 @@ def __init__(self, name: str, flag_class: Flag, description: str, *, required: b
12821276 self .allowed : Sequence = flag_class if allowed is None else allowed
12831277 self ._members : Dict = {i .name .lower (): i for i in self .allowed }
12841278 super ().__init__ (name , flag_class , description , required , default )
1285- def get_config (self ) -> str :
1286- """Returns string containing text lines suitable for use in configuration file
1287- processed with `~configparser.ConfigParser`.
1288-
1289- Text lines with configuration start with comment marker ; and end with newline.
1290- """
1291- lines : List = super ()._get_config_lines ()
1292- lines .insert (4 , f"; values: { ', ' .join (x .name .lower () for x in self .allowed )} \n " )
1293- return '' .join (lines )
1279+ def _get_value_description (self ) -> str :
1280+ return f"flag [{ ', ' .join (x .name .lower () for x in self .allowed )} ]\n "
12941281 def clear (self , * , to_default : bool = True ) -> None :
12951282 """Clears the option value.
12961283
@@ -1565,6 +1552,8 @@ def __init__(self, name: str, item_type: Union[Type, Sequence[Type]], descriptio
15651552 self .separator : Optional [str ] = separator
15661553 self ._convertor : Convertor = get_convertor (item_type ) if isinstance (item_type , type ) else None
15671554 super ().__init__ (name , list , description , required , default )
1555+ def _get_value_description (self ) -> str :
1556+ return f"list [{ ', ' .join (x .__name__ for x in self .item_types )} ]\n "
15681557 def _check_value (self , value : List ) -> None :
15691558 super ()._check_value (value )
15701559 if value is not None :
@@ -2019,6 +2008,8 @@ def __init__(self, name: str, description: str, config: Config, *, required: boo
20192008 assert isinstance (config , Config )
20202009 self ._value : Config = config
20212010 super ().__init__ (name , str , description , required , default )
2011+ def _get_value_description (self ) -> str :
2012+ return f"configuration section name\n "
20222013 def validate (self ) -> None :
20232014 """Validates option state.
20242015
@@ -2151,6 +2142,8 @@ def __init__(self, name: str, description: str, item_type: Type[Config], *,
21512142 #: break as separator, otherwise it uses comma as separator.
21522143 self .separator : Optional [str ] = separator
21532144 super ().__init__ (name , list , description , required , [])
2145+ def _get_value_description (self ) -> str :
2146+ return f"list of configuration section names\n "
21542147 def _check_value (self , value : List ) -> None :
21552148 super ()._check_value (value )
21562149 if value is not None :
@@ -2297,6 +2290,9 @@ def __init__(self, name: str, dataclass: Type, description: str, *, required: bo
22972290 #: uses the line break as separator, otherwise it uses comma as separator.
22982291 self .separator : Optional [str ] = separator
22992292 super ().__init__ (name , dataclass , description , required , default )
2293+ def _get_value_description (self ) -> str :
2294+ return "list of values, where each list item defines value for a dataclass field.\n " \
2295+ "Item format: field_name:value_as_str\n "
23002296 def _get_str_fields (self ) -> List [str ]:
23012297 result = []
23022298 if self ._value is not None :
0 commit comments