@@ -389,7 +389,7 @@ def __init__(self, name: str, version: str | None=None, *, force_home: bool=Fals
389389 force_home: When True, general directories (i.e. all except user-specific and
390390 TMP) would be always based on HOME directory.
391391 """
392- super ().__init__ (name , version , force_home )
392+ super ().__init__ (name , version , force_home = force_home )
393393 app_dir = Path (self .name )
394394 if self .version is not None :
395395 app_dir /= self .version
@@ -462,7 +462,7 @@ def __init__(self, name: str, version: str | None=None, *, force_home: bool=Fals
462462 name: Appplication name.
463463 version: Application version.
464464 """
465- super ().__init__ (name , version , force_home )
465+ super ().__init__ (name , version , force_home = force_home )
466466 app_dir = Path (self .name )
467467 if self .version is not None :
468468 app_dir /= self .version
@@ -733,8 +733,9 @@ def get_config(self, *, plain: bool=False) -> str:
733733 """
734734 if self .optional and not self .name :
735735 return ''
736- lines = [f"[{ self .name } ]\n " , '; \n ' ]
736+ lines = [f"[{ self .name } ]\n " ]
737737 if not plain :
738+ lines .append (';\n ' )
738739 for line in self .get_description ().strip ().splitlines ():
739740 lines .append (f"; { line } \n " )
740741 for option in self .options :
@@ -1146,7 +1147,7 @@ def set_as_str(self, value: str) -> None:
11461147 try :
11471148 self ._value = Decimal (value )
11481149 except DecimalException as exc :
1149- raise ValueError (str ( exc ) ) from exc
1150+ raise ValueError ("Cannot convert string to Decimal" ) from exc
11501151 def get_as_str (self ) -> str :
11511152 """Returns value as string.
11521153 """
@@ -1747,14 +1748,17 @@ def __init__(self, name: str, item_type: type | Sequence[type], description: str
17471748 self ._value : list = None
17481749 #: Datatypes of list items. If there is more than one type, each value in
17491750 #: config file must have format: `type_name:value_as_str`.
1750- self .item_types : Sequence [type ] = ( item_type , ) if isinstance (item_type , type ) else item_type
1751+ self .item_types : Sequence [type ] = item_type if isinstance (item_type , Sequence ) else ( item_type , )
17511752 #: String that separates list item values when options value is read from
17521753 #: `ConfigParser`. Default separator is None. It's possible to use a line break as
17531754 #: separator. If separator is `None` and the value contains line breaks, it uses
17541755 #: the line break as separator, otherwise it uses comma as separator.
17551756 self .separator : str | None = separator
1756- self ._convertor : Convertor = get_convertor (item_type ) if isinstance (item_type , type ) else None
1757+ self ._convertor : Convertor = get_convertor (item_type ) if not isinstance (item_type , Sequence ) else None
17571758 super ().__init__ (name , list , description , required = required , default = default )
1759+ # Value fixup, store copy of default list instead direct assignment
1760+ if default is not None :
1761+ self .set_value (list (default ))
17581762 def _get_value_description (self ) -> str :
17591763 return f"list [{ ', ' .join (x .__name__ for x in self .item_types )} ]\n "
17601764 def _check_value (self , value : list ) -> None :
@@ -1776,13 +1780,13 @@ def clear(self, *, to_default: bool=True) -> None:
17761780 Arguments:
17771781 to_default: If True, sets the option value to default value, else to None.
17781782 """
1779- self ._value = self .default if to_default else None
1783+ self ._value = list ( self .default ) if to_default and self . default is not None else None
17801784 def get_formatted (self ) -> str :
17811785 """Returns value formatted for use in config file.
17821786 """
17831787 if self ._value is None :
17841788 return '<UNDEFINED>'
1785- result = [convert_to_str (i ) for i in self ._value ]
1789+ result = [self . _get_as_typed_str (i ) for i in self ._value ]
17861790 sep = self .separator
17871791 if sep is None :
17881792 sep = '\n ' if sum (len (i ) for i in result ) > 80 else ',' # noqa: PLR2004
@@ -1821,7 +1825,7 @@ def set_as_str(self, value: str) -> None:
18211825 def get_as_str (self ) -> str :
18221826 """Returns value as string.
18231827 """
1824- result = [convert_to_str (i ) for i in self ._value ]
1828+ result = [self . _get_as_typed_str (i ) for i in self ._value ]
18251829 sep = self .separator
18261830 if sep is None :
18271831 sep = '\n ' if sum (len (i ) for i in result ) > 80 else ',' # noqa: PLR2004
@@ -2227,6 +2231,8 @@ def validate(self) -> None:
22272231 """
22282232 if self .required and self .get_value ().name == '' :
22292233 raise Error (f"Missing value for required option '{ self .name } '" )
2234+ if self .get_value ().name != '' :
2235+ self .value .validate ()
22302236 def clear (self , * , to_default : bool = True ) -> None :
22312237 """Clears the option value.
22322238
@@ -2368,6 +2374,14 @@ def clear(self, *, to_default: bool=True) -> None: # noqa: ARG002
23682374 to_default: As ConfigListOption does not have default value, this parameter is ignored.
23692375 """
23702376 self ._value .clear ()
2377+ def validate (self ) -> None :
2378+ """Validates option state.
2379+
2380+ Raises:
2381+ Error: When required option does not have a value.
2382+ """
2383+ if self .required and len (self .get_value ()) == 0 :
2384+ raise Error (f"Missing value for required option '{ self .name } '" )
23712385 def get_formatted (self ) -> str :
23722386 """Returns value formatted for use in config file.
23732387 """
0 commit comments