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: Attributes:
_config: The Config object. _config: The Config object.
_prefix: The __getattr__ chain leading up to this 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._config = config
self._prefix = prefix self._prefix = prefix
self._confpy = confpy
def __repr__(self): def __repr__(self):
return utils.get_repr(self, constructor=True, config=self._config, return utils.get_repr(self, constructor=True, config=self._config,
prefix=self._prefix) confpy=self._confpy, prefix=self._prefix)
def __getattr__(self, attr): def __getattr__(self, attr):
"""Get an option or a new ConfigContainer with the added prefix. """Get an option or a new ConfigContainer with the added prefix.
@ -524,8 +526,12 @@ class ConfigContainer:
name = self._join(attr) name = self._join(attr)
if configdata.is_valid_prefix(name): if configdata.is_valid_prefix(name):
return ConfigContainer(config=self._config, prefix=name) return ConfigContainer(config=self._config, confpy=self._confpy,
prefix=name)
if self._confpy:
return self._config.get_obj(name)
else:
return self._config.get(name) return self._config.get(name)
def __setattr__(self, attr, value): def __setattr__(self, attr, value):

View File

@ -134,7 +134,8 @@ def read_config_py(filename=None):
if not os.path.exists(filename): if not os.path.exists(filename):
return None 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 = types.ModuleType('config')
module.config = api module.config = api
module.c = api.val module.c = api.val
@ -145,6 +146,8 @@ def read_config_py(filename=None):
code = compile(source, filename, 'exec') code = compile(source, filename, 'exec')
exec(code, module.__dict__) exec(code, module.__dict__)
config.instance.update_mutables()
return api return api

View File

@ -777,8 +777,14 @@ class TestContainer:
new_container = new_container.favicons new_container = new_container.favicons
assert new_container._prefix == 'tabs.favicons' assert new_container._prefix == 'tabs.favicons'
def test_getattr_option(self, container): @pytest.mark.parametrize('confpy, expected', [
assert container.tabs.show == 'always' (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): def test_getattr_invalid(self, container):
with pytest.raises(configexc.NoOptionError) as excinfo: with pytest.raises(configexc.NoOptionError) as excinfo:

View File

@ -161,6 +161,11 @@ class TestConfigPy:
expected = {'normal': {'o': None}} expected = {'normal': {'o': None}}
assert config.instance._values['bindings.commands'] == expected 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): def test_reading_default_location(self, config_tmpdir):
(config_tmpdir / 'config.py').write_text( (config_tmpdir / 'config.py').write_text(
'c.colors.hints.bg = "red"', 'utf-8') 'c.colors.hints.bg = "red"', 'utf-8')