def parse(self, inp): """""" if not inp or inp == NO_STR: value = tuple() elif isinstance(inp, (tuple, list)) or is_lazy_iterable(inp): value = make_tuple(inp) elif isinstance(inp, six.string_types): if self._brace_expand: elems = brace_expand(inp, split_csv=True, escape_csv_sep=self._escape_sep) else: # replace escaped separators if self._escape_sep: escaped_sep = "__law_escaped_csv_sep__" inp = inp.replace("\\" + self.CSV_SEP, escaped_sep) # split elems = inp.split(self.CSV_SEP) # add back escaped separators per element if self._escape_sep: elems = [elem.replace(escaped_sep, self.CSV_SEP) for elem in elems] value = tuple(map(self._inst.parse, elems)) else: value = (inp,) # apply uniqueness, sort, length and choices checks value = self._check_unique(value) value = self._check_sort(value) self._check_len(value) self._check_choices(value) return value
def __init__(self, config_file="", skip_defaults=False, skip_fallbacks=False): ConfigParser.__init__(self, allow_no_value=True) self.config_file = None # load defaults if not skip_defaults: self.update(self._default_config) # read from files config_files = [] if config_file: config_files.append(config_file) if not skip_fallbacks: config_files += self._config_files for cf in config_files: cf = os.path.expandvars(os.path.expanduser(cf)) cf = os.path.normpath(os.path.abspath(cf)) if os.path.isfile(cf): self.read(cf) self.config_file = cf logger.debug("config instance created from '{}'".format(cf)) break else: logger.debug("config instance created without a file") # inherit from and/or extend by other configs for option, overwrite_options in [("inherit_configs", False), ("extend_configs", True)]: filenames = self.get_expanded("core", option) if not filenames: continue filenames = [ f.strip() for f in brace_expand(filenames.strip(), split_csv=True) ] for filename in filenames: # try to resolve filename relative to the main config file if self.config_file: basedir = os.path.dirname(self.config_file) filename = os.path.normpath(os.path.join( basedir, filename)) self.include(filename, overwrite_options=overwrite_options) # sync with luigi configuration if self.get_expanded_boolean("core", "sync_luigi_config"): self.sync_luigi_config()
def get_expanded_list(section, option): # get config value, run brace expansion taking into account csv splitting value = cfg.get_expanded(section, option) return value and [ v.strip() for v in brace_expand(value.strip(), split_csv=True) ]
def get_default(self, section, option, default=None, type=None, expand_vars=False, expand_user=False, split_csv=False, dereference=True, default_when_none=True, _skip_refs=None): """ get_default(section, option, default=None, type=None, expand_vars=False, expand_user=False, split_csv=False, dereference=True, default_when_none=True) Returns the config value defined by *section* and *option*. When either the section or the option does not exist, the *default* value is returned instead. When *type* is set, it must be either `"str"`, `"int"`, `"float"`, or `"boolean"`. When *expand_vars* is *True*, environment variables are expanded. When *expand_user* is *True*, user variables are expanded as well. Sequences of values can be identified, split by comma and returned as a list when *split_csv* is *True*, which will also trigger brace expansion. Also, options retrieved by this method are allowed to refer to values of other options within the config, even to those in other sections. The syntax for config references is ``&[::section]::option``. When no section is given, the value refers to an option in the same section. Example: .. code-block:: ini [my_section] a: 123 b: &::a # 123, refers to "a" in the same section [bar_section] a: &::my_section::a # 123, refers to "a" in "my_section" This behavior is the default and, if desired, can be disabled by setting *dereference* to *False*. When the reference is not resolvable, the default value is returned. When *default_when_none* is *True* and the option was found but its value is *None* or ``"None"`` (case-insensitive), the *default* is returned. """ # noqa # return the default when either the section or the option does not exist if not self.has_section(section) or not self.has_option(section, option): return default # get the value value = self.get(section, option) # handle variable expansion and dereferencing when value is a string # (which should always be the case, but subclasses might overwrite get()) if isinstance(value, six.string_types): # expand if expand_vars: value = os.path.expandvars(value) if expand_user: value = os.path.expanduser(value) # resolve references if dereference: ref = self._parse_option_ref(value, default_section=section) if ref: # to avoid circular references, keep track of already resolved ones if _skip_refs is None: _skip_refs = [] elif ref in _skip_refs: return default _skip_refs.append(ref) # return the referenced value return self.get_default(*ref, default=default, type=type, expand_vars=expand_vars, expand_user=expand_user, dereference=dereference, default_when_none=default_when_none, _skip_refs=_skip_refs) # interpret None and "None" as missing? if default_when_none: if value is None: return default elif isinstance(value, six.string_types) and value.lower() == "none": return default # helper for optional type conversion cast_type = lambda value: self._get_type_converter(type, value)(value) if type else value # do csv splitting if requested if split_csv: return [cast_type(v.strip()) for v in brace_expand(value, split_csv=True)] return cast_type(value)