def values_from_file(docopt_dict, config_option, settable, booleans, repeatable):
"""Parse config file and read settable values.
Can be overridden by both command line arguments and environment variables.
:raise DocoptcfgError: If `config_option` isn't found in docstring.
:raise DocoptcfgFileError: On any error while trying to read and parse config file.
:param dict docopt_dict: Dictionary from docopt with environment variable defaults merged in by docoptcfg().
:param str config_option: Config option long name with file path as its value.
:param iter settable: Option long names available to set by config file.
:param iter booleans: Option long names of boolean/flag types.
:param iter repeatable: Option long names of repeatable options.
:return: Settable values.
:rtype: dict
"""
section = docopt.DocoptExit.usage.split()[1]
settable = set(o for o in settable if o != config_option)
config = ConfigParser()
defaults = dict()
# Sanity checks.
if config_option not in docopt_dict:
raise DocoptcfgError
if docopt_dict[config_option] is None or not settable:
return defaults
# Read config file.
path = DocoptcfgFileError.FILE_PATH = docopt_dict[config_option]
try:
with open(path) as handle:
if hasattr(config, 'read_file'):
config.read_file(handle)
else:
getattr(config, 'readfp')(handle)
except Error as exc:
raise DocoptcfgFileError('Unable to parse config file.', str(exc))
except IOError as exc:
raise DocoptcfgFileError('Unable to read config file.', str(exc))
# Make sure section is in config file.
if not config.has_section(section):
raise DocoptcfgFileError('Section [{0}] not in config file.'.format(section))
# Parse config file.
for key in settable:
if config.has_option(section, key[2:]):
defaults[key] = get_opt(key, config, section, booleans, repeatable)
return defaults
评论列表
文章目录