fix: force interpolation of %(here)s
, %(__file__)s
in config files
we were previously doing this only for the `wutta.config.include` and `wutta.config.require` settings, and pyramid (or paste?) has been handling certain other ones, e.g. for beaker session cache paths. but we really need to be able to rely on this being available "everywhere" or else it's just confusing.
This commit is contained in:
parent
659d7e551e
commit
fa76eb6aa9
|
@ -252,34 +252,44 @@ class WuttaConfig:
|
|||
if path in self.files_read:
|
||||
return
|
||||
|
||||
# try to load config from the given path
|
||||
try:
|
||||
config = configuration.config_from_ini(path, read_from_file=True)
|
||||
except FileNotFoundError:
|
||||
if not require:
|
||||
log.warning("INI config file not found: %s", path)
|
||||
return
|
||||
raise
|
||||
# try to load config with standard parser, and default vars
|
||||
here = os.path.dirname(path)
|
||||
config = configparser.ConfigParser(defaults={'here': here, '__file__': path})
|
||||
if not config.read(path):
|
||||
if require:
|
||||
raise FileNotFoundError(f"could not read required config file: {path}")
|
||||
return
|
||||
|
||||
# ok add that one to the mix
|
||||
# load all values into (yet another) temp config
|
||||
temp_config = configparser.RawConfigParser()
|
||||
for section in config.sections():
|
||||
temp_config.add_section(section)
|
||||
# nb. must interpolate most values but *not* for logging formatters
|
||||
raw = section.startswith('formatter_')
|
||||
for option in config.options(section):
|
||||
temp_config.set(section, option, config.get(section, option, raw=raw))
|
||||
|
||||
# re-write as temp file with "final" values
|
||||
fd, temp_path = tempfile.mkstemp(suffix='.ini')
|
||||
os.close(fd)
|
||||
with open(temp_path, 'wt') as f:
|
||||
temp_config.write(f)
|
||||
|
||||
# and finally, load that into our main config
|
||||
config = configuration.config_from_ini(temp_path, read_from_file=True)
|
||||
configs.append(config)
|
||||
self.files_read.append(path)
|
||||
|
||||
# need parent folder of that path, for %(here)s interpolation
|
||||
here = os.path.dirname(path)
|
||||
|
||||
# bring in any "required" files
|
||||
requires = config.get(f'{self.appname}.config.require')
|
||||
if requires:
|
||||
for path in self.parse_list(requires):
|
||||
path = path % {'here': here}
|
||||
self._load_ini_configs(path, configs, require=True)
|
||||
|
||||
# bring in any "included" files
|
||||
includes = config.get(f'{self.appname}.config.include')
|
||||
if includes:
|
||||
for path in self.parse_list(includes):
|
||||
path = path % {'here': here}
|
||||
self._load_ini_configs(path, configs, require=False)
|
||||
|
||||
def get_prioritized_files(self):
|
||||
|
|
|
@ -159,6 +159,17 @@ require = %(here)s/first.conf
|
|||
self.assertEqual(files[0], second)
|
||||
self.assertEqual(files[1], first)
|
||||
|
||||
def test_default_vars_interpolated(self):
|
||||
myconf = self.write_file('my.conf', """
|
||||
[foo]
|
||||
bar = %(here)s/bar.txt
|
||||
baz = %(__file__)s
|
||||
""")
|
||||
|
||||
config = conf.WuttaConfig(files=[myconf])
|
||||
self.assertEqual(config.get('foo.bar'), f'{self.tempdir}/bar.txt')
|
||||
self.assertEqual(config.get('foo.baz'), myconf)
|
||||
|
||||
def test_constructor_defaults(self):
|
||||
config = conf.WuttaConfig()
|
||||
self.assertEqual(config.defaults, {})
|
||||
|
|
Loading…
Reference in a new issue