"""An implementation configuration class that holds environment variables."""__author__='Paul Landes'fromtypingimportDict,Setimportloggingimportcollectionsimportosfromzensols.persistimportpersistedfrom.importConfigurableError,Configurablelogger=logging.getLogger(__name__)
[docs]classEnvironmentConfig(Configurable):"""An implementation configuration class that holds environment variables. This config will need to be added to children to :class:`.ImportIniConfig` if used in the configuration or import sections. """
[docs]def__init__(self,section_name:str='env',map_delimiter:str=None,skip_delimiter:bool=False,includes:Set[str]=None):"""Initialize with a string given as described in the class docs. The string ``<DOLLAR>`` used with ``map_delimiter`` is the same as ``$`` since adding the dollar in some configuration scenarios has parsing issues. One example is when ``$$`` failes on copying section to an :class:`.IniConfig`. :param section_name: the name of the created section with the environment variables :param map_delimiter: when given, all environment values are replaced with a duplicate; set this to ``$`` when using :class:`configparser.ExtendedInterpolation` for environment variables such as ``PS1`` :param skip_delimiter: a string, when present, causes the environment variable to be skipped; this is useful for environment variables that cause interpolation errors :param includes: if given, the set of environment variables to set excluding the rest; include all if ``None`` """super().__init__(section_name)ifmap_delimiter=='<DOLLAR>':map_delimiter='$'self.map_delimiter=map_delimiterself.skip_delimiter=skip_delimiterself.includes=includes
@persisted('_parsed_config')def_get_parsed_config(self)->Dict[str,str]:"""Parse the configuration string given in the initializer (see class docs). """conf=collections.defaultdict(lambda:{})forkvinself.config_str.split(self.option_sep):m=self.KEY_VAL_REGEX.match(kv)ifmisNone:raiseConfigurableError(f'unexpected format: {kv}')sec,name,value=m.groups()sec=self.default_sectionifsecisNoneelseseciflogger.isEnabledFor(logging.DEBUG):logger.debug(f'section={sec}, name={name}, value={value}')conf[sec][name]=valuereturnconf@persisted('_keys')def_get_keys(self)->Dict[str,str]:returnself._get_parsed_config().keys()@property@persisted('_sections')defsections(self)->Set[str]:returnfrozenset([self.default_section])