Handle mutations in config.py correctly

This commit is contained in:
Florian Bruhin 2017-09-14 17:31:14 +02:00
parent cb806aefa3
commit b3734b151b
4 changed files with 27 additions and 7 deletions

View File

@ -500,15 +500,17 @@ class ConfigContainer:
Attributes:
_config: The Config object.
_prefix: The __getattr__ chain leading up to this object.
_confpy: If True, get values suitable for config.py.
"""
def __init__(self, config, prefix=''):
def __init__(self, config, confpy=False, prefix=''):
self._config = config
self._prefix = prefix
self._confpy = confpy
def __repr__(self):
return utils.get_repr(self, constructor=True, config=self._config,
prefix=self._prefix)
confpy=self._confpy, prefix=self._prefix)
def __getattr__(self, attr):
"""Get an option or a new ConfigContainer with the added prefix.
@ -524,9 +526,13 @@ class ConfigContainer:
name = self._join(attr)
if configdata.is_valid_prefix(name):
return ConfigContainer(config=self._config, prefix=name)
return ConfigContainer(config=self._config, confpy=self._confpy,
prefix=name)
return self._config.get(name)
if self._confpy:
return self._config.get_obj(name)
else:
return self._config.get(name)
def __setattr__(self, attr, value):
"""Set the given option in the config."""

View File

@ -134,7 +134,8 @@ def read_config_py(filename=None):
if not os.path.exists(filename):
return None
api = ConfigAPI(config.instance, config.key_instance, config.val)
container = config.ConfigContainer(config.instance, confpy=True)
api = ConfigAPI(config.instance, config.key_instance, container)
module = types.ModuleType('config')
module.config = api
module.c = api.val
@ -145,6 +146,8 @@ def read_config_py(filename=None):
code = compile(source, filename, 'exec')
exec(code, module.__dict__)
config.instance.update_mutables()
return api

View File

@ -777,8 +777,14 @@ class TestContainer:
new_container = new_container.favicons
assert new_container._prefix == 'tabs.favicons'
def test_getattr_option(self, container):
assert container.tabs.show == 'always'
@pytest.mark.parametrize('confpy, expected', [
(True, 'rgb'),
(False, QColor.Rgb),
])
def test_getattr_option(self, container, confpy, expected):
container._confpy = confpy
# Use an option with a to_py() so we can check the conversion.
assert container.colors.downloads.system.fg == expected
def test_getattr_invalid(self, container):
with pytest.raises(configexc.NoOptionError) as excinfo:

View File

@ -161,6 +161,11 @@ class TestConfigPy:
expected = {'normal': {'o': None}}
assert config.instance._values['bindings.commands'] == expected
def test_mutating(self, confpy):
confpy.write('c.aliases["foo"] = "message-info foo"')
configfiles.read_config_py(confpy.filename)
assert config.instance._values['aliases']['foo'] == 'message-info foo'
def test_reading_default_location(self, config_tmpdir):
(config_tmpdir / 'config.py').write_text(
'c.colors.hints.bg = "red"', 'utf-8')