Skip to content

Commit 1692ec4

Browse files
committed
Change config layout produced by get_config(). Add customized description for Config.
1 parent 366c777 commit 1692ec4

File tree

2 files changed

+181
-533
lines changed

2 files changed

+181
-533
lines changed

firebird/base/config.py

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)