def test_oserror(self, tmpdir, data_tmpdir, config_tmpdir): with pytest.raises(configexc.ConfigFileErrors) as excinfo: configfiles.read_config_py(str(tmpdir / 'foo')) assert len(excinfo.value.errors) == 1 error = excinfo.value.errors[0] assert isinstance(error.exception, OSError) assert error.text == "Error while reading foo" assert error.traceback is None
def on_file_updated(): """Source the new config when editing finished. This can't use cmdexc.CommandError as it's run async. """ try: configfiles.read_config_py(filename) except configexc.ConfigFileErrors as e: message.error(str(e))
def on_file_updated() -> None: """Source the new config when editing finished. This can't use cmdutils.CommandError as it's run async. """ try: configfiles.read_config_py(filename) except configexc.ConfigFileErrors as e: message.error(str(e))
def early_init(args: argparse.Namespace) -> None: """Initialize the part of the config which works without a QApplication.""" configdata.init() yaml_config = configfiles.YamlConfig() config.instance = config.Config(yaml_config=yaml_config) config.val = config.ConfigContainer(config.instance) configapi.val = config.ConfigContainer(config.instance) config.key_instance = config.KeyConfig(config.instance) config.cache = configcache.ConfigCache() yaml_config.setParent(config.instance) for cf in config.change_filters: cf.validate() config_commands = configcommands.ConfigCommands( config.instance, config.key_instance) objreg.register('config-commands', config_commands, command_only=True) config_file = standarddir.config_py() custom_config_py = args.config_py is not None global _init_errors try: if os.path.exists(config_file) or custom_config_py: # If we have a custom --config-py flag, we want it to be fatal if it doesn't # exist, so we don't silently fall back to autoconfig.yml in that case. configfiles.read_config_py( config_file, warn_autoconfig=not custom_config_py, ) else: configfiles.read_autoconfig() except configexc.ConfigFileErrors as e: log.config.error("Error while loading {}".format(e.basename)) _init_errors = e try: configfiles.init() except configexc.ConfigFileErrors as e: _init_errors = e for opt, val in args.temp_settings: try: config.instance.set_str(opt, val) except configexc.Error as e: message.error("set: {} - {}".format(e.__class__.__name__, e)) objects.backend = get_backend(args) objects.debug_flags = set(args.debug_flags) stylesheet.init() qtargs.init_envvars()
def read(self, error=False): """Read the config.py via configfiles and check for errors.""" if error: with pytest.raises(configexc.ConfigFileErrors) as excinfo: configfiles.read_config_py(self.filename) errors = excinfo.value.errors assert len(errors) == 1 return errors[0] else: configfiles.read_config_py(self.filename, raising=True) return None
def test_load_autoconfig_warning(self, confpy): confpy.write('') with pytest.raises(configexc.ConfigFileErrors) as excinfo: configfiles.read_config_py(confpy.filename, warn_autoconfig=True) assert len(excinfo.value.errors) == 1 error = excinfo.value.errors[0] assert error.text == "autoconfig loading not specified" exception_text = ('Your config.py should call either `config.load_autoconfig()`' ' (to load settings configured via the GUI) or ' '`config.load_autoconfig(False)` (to not do so)') assert str(error.exception) == exception_text
def test_nul_bytes(self, confpy): confpy.write('\0') with pytest.raises(configexc.ConfigFileErrors) as excinfo: configfiles.read_config_py(confpy.filename) assert len(excinfo.value.errors) == 1 error = excinfo.value.errors[0] assert isinstance(error.exception, ValueError) assert error.text == "Error while compiling" exception_text = 'source code string cannot contain null bytes' assert str(error.exception) == exception_text assert error.traceback is None
def early_init(args: argparse.Namespace) -> None: """Initialize the part of the config which works without a QApplication.""" configdata.init() yaml_config = configfiles.YamlConfig() config.instance = config.Config(yaml_config=yaml_config) config.val = config.ConfigContainer(config.instance) configapi.val = config.ConfigContainer(config.instance) config.key_instance = config.KeyConfig(config.instance) config.cache = configcache.ConfigCache() yaml_config.setParent(config.instance) for cf in config.change_filters: cf.validate() config_commands = configcommands.ConfigCommands(config.instance, config.key_instance) objreg.register('config-commands', config_commands, command_only=True) config_file = standarddir.config_py() global _init_errors try: if os.path.exists(config_file): configfiles.read_config_py(config_file) else: configfiles.read_autoconfig() except configexc.ConfigFileErrors as e: log.config.exception("Error while loading {}".format(e.basename)) _init_errors = e try: configfiles.init() except configexc.ConfigFileErrors as e: _init_errors = e for opt, val in args.temp_settings: try: config.instance.set_str(opt, val) except configexc.Error as e: message.error("set: {} - {}".format(e.__class__.__name__, e)) objects.backend = get_backend(args) objects.debug_flags = set(args.debug_flags) configtypes.Font.monospace_fonts = config.val.fonts.monospace config.instance.changed.connect(_update_monospace_fonts) stylesheet.init() _init_envvars()
def test_source_multiple_errors(self, tmpdir, confpy): subfile = tmpdir / 'config' / 'subfile.py' subfile.write_text("c.foo = 42", encoding='utf-8') confpy.write("config.source('subfile.py')", "c.bar = 23") with pytest.raises(configexc.ConfigFileErrors) as excinfo: configfiles.read_config_py(confpy.filename) errors = excinfo.value.errors assert len(errors) == 2 for error in errors: assert isinstance(error.exception, configexc.NoOptionError)
def test_defaults_work(self, confpy): """Get a config.py with default values and run it.""" options = [(None, opt, opt.default) for _name, opt in sorted(configdata.DATA.items())] bindings = dict(configdata.DATA['bindings.default'].default) writer = configfiles.ConfigPyWriter(options, bindings, commented=False) writer.write(confpy.filename) try: configfiles.read_config_py(confpy.filename) except configexc.ConfigFileErrors as exc: # Make sure no other errors happened for error in exc.errors: assert isinstance(error.exception, configexc.BackendError)
def test_syntax_error(self, confpy): confpy.write('+') with pytest.raises(configexc.ConfigFileErrors) as excinfo: configfiles.read_config_py(confpy.filename) assert len(excinfo.value.errors) == 1 error = excinfo.value.errors[0] assert isinstance(error.exception, SyntaxError) assert error.text == "Unhandled exception" exception_text = 'invalid syntax (config.py, line 1)' assert str(error.exception) == exception_text tblines = error.traceback.strip().splitlines() assert tblines[0] == "Traceback (most recent call last):" assert tblines[-1] == "SyntaxError: invalid syntax" assert " +" in tblines assert " ^" in tblines
def early_init(args: argparse.Namespace) -> None: """Initialize the part of the config which works without a QApplication.""" configdata.init() yaml_config = configfiles.YamlConfig() config.instance = config.Config(yaml_config=yaml_config) config.val = config.ConfigContainer(config.instance) configapi.val = config.ConfigContainer(config.instance) config.key_instance = config.KeyConfig(config.instance) config.cache = configcache.ConfigCache() yaml_config.setParent(config.instance) for cf in config.change_filters: cf.validate() config_commands = configcommands.ConfigCommands( config.instance, config.key_instance) objreg.register('config-commands', config_commands) config_file = os.path.join(standarddir.config(), 'config.py') try: if os.path.exists(config_file): configfiles.read_config_py(config_file) else: configfiles.read_autoconfig() except configexc.ConfigFileErrors as e: log.config.exception("Error while loading {}".format(e.basename)) global _init_errors _init_errors = e configfiles.init() for opt, val in args.temp_settings: try: config.instance.set_str(opt, val) except configexc.Error as e: message.error("set: {} - {}".format(e.__class__.__name__, e)) objects.backend = get_backend(args) configtypes.Font.monospace_fonts = config.val.fonts.monospace config.instance.changed.connect(_update_monospace_fonts) _init_envvars()
def early_init(args): """Initialize the part of the config which works without a QApplication.""" configdata.init() yaml_config = configfiles.YamlConfig() config.instance = config.Config(yaml_config=yaml_config) config.val = config.ConfigContainer(config.instance) config.key_instance = config.KeyConfig(config.instance) yaml_config.setParent(config.instance) for cf in config.change_filters: cf.validate() configtypes.Font.monospace_fonts = config.val.fonts.monospace config_commands = configcommands.ConfigCommands(config.instance, config.key_instance) objreg.register('config-commands', config_commands) config_file = os.path.join(standarddir.config(), 'config.py') try: if os.path.exists(config_file): configfiles.read_config_py(config_file) else: configfiles.read_autoconfig() except configexc.ConfigFileErrors as e: log.config.exception("Error while loading {}".format(e.basename)) global _init_errors _init_errors = e configfiles.init() objects.backend = get_backend(args) for opt, val in args.temp_settings: try: config.instance.set_str(opt, val) except configexc.Error as e: message.error("set: {} - {}".format(e.__class__.__name__, e)) if (objects.backend == usertypes.Backend.QtWebEngine and config.val.force_software_rendering): os.environ['QT_XCB_FORCE_SOFTWARE_OPENGL'] = '1'
def test_config_val(self, confpy): """Using config.val should not work in config.py files.""" confpy.write("config.val.colors.hints.bg = 'red'") api = configfiles.read_config_py(confpy.filename) assert len(api.errors) == 1 error = api.errors[0] assert error.text == "Unhandled exception" assert isinstance(error.exception, AttributeError) message = "'ConfigAPI' object has no attribute 'val'" assert str(error.exception) == message
def test_multiple_errors(self, confpy): confpy.write("c.foo = 42", "config.set('foo', 42)", "1/0") with pytest.raises(configexc.ConfigFileErrors) as excinfo: configfiles.read_config_py(confpy.filename) errors = excinfo.value.errors assert len(errors) == 3 for error in errors[:2]: assert error.text == "While setting 'foo'" assert isinstance(error.exception, configexc.NoOptionError) assert str(error.exception) == "No option 'foo'" assert error.traceback is None error = errors[2] assert error.text == "Unhandled exception" assert isinstance(error.exception, ZeroDivisionError) assert error.traceback is not None
def test_syntax_error(self, confpy): confpy.write('+') with pytest.raises(configexc.ConfigFileErrors) as excinfo: configfiles.read_config_py(confpy.filename) assert len(excinfo.value.errors) == 1 error = excinfo.value.errors[0] assert isinstance(error.exception, SyntaxError) assert error.text == "Unhandled exception" exception_text = 'invalid syntax (config.py, line 1)' assert str(error.exception) == exception_text tblines = error.traceback.strip().splitlines() assert tblines[0] == "Traceback (most recent call last):" assert tblines[-1] == "SyntaxError: invalid syntax" assert " +" in tblines # Starting with the new PEG-based parser in Python 3.9, the caret # points at the location *after* the + assert " ^" in tblines or " ^" in tblines
def config_source(self, filename=None, clear=False): """Read a config.py file. Args: filename: The file to load. If not given, loads the default config.py. clear: Clear current settings first. """ if filename is None: filename = os.path.join(standarddir.config(), 'config.py') else: filename = os.path.expanduser(filename) if clear: self.config_clear() try: configfiles.read_config_py(filename) except configexc.ConfigFileErrors as e: raise cmdexc.CommandError(e)
def test_config_error(self, confpy, line): confpy.write(line, "config.load_autoconfig = False") api = configfiles.read_config_py(confpy.filename) assert not api.load_autoconfig assert len(api.errors) == 1 error = api.errors[0] assert error.text == "While setting 'foo'" assert isinstance(error.exception, configexc.NoOptionError) assert str(error.exception) == "No option 'foo'" assert error.traceback is None
def test_unhandled_exception(self, confpy): confpy.write("config.load_autoconfig = False", "1/0") api = configfiles.read_config_py(confpy.filename) assert not api.load_autoconfig assert len(api.errors) == 1 error = api.errors[0] assert error.text == "Unhandled exception" assert isinstance(error.exception, ZeroDivisionError) tblines = error.traceback.strip().splitlines() assert tblines[0] == "Traceback (most recent call last):" assert tblines[-1] == "ZeroDivisionError: division by zero" assert " 1/0" in tblines
def test_multiple_errors(self, confpy): confpy.write("c.foo = 42", "config.set('foo', 42)", "1/0") api = configfiles.read_config_py(confpy.filename) assert len(api.errors) == 3 for error in api.errors[:2]: assert error.text == "While setting 'foo'" assert isinstance(error.exception, configexc.NoOptionError) assert str(error.exception) == "No option 'foo'" assert error.traceback is None error = api.errors[2] assert error.text == "Unhandled exception" assert isinstance(error.exception, ZeroDivisionError) assert error.traceback is not None
def early_init(args): """Initialize the part of the config which works without a QApplication.""" configdata.init() yaml_config = configfiles.YamlConfig() global val, instance, key_instance instance = Config(yaml_config=yaml_config) val = ConfigContainer(instance) key_instance = KeyConfig(instance) for cf in _change_filters: cf.validate() configtypes.Font.monospace_fonts = val.fonts.monospace config_commands = ConfigCommands(instance, key_instance) objreg.register('config-commands', config_commands) config_api = None try: config_api = configfiles.read_config_py() # Raised here so we get the config_api back. if config_api.errors: raise configexc.ConfigFileErrors('config.py', config_api.errors) except configexc.ConfigFileErrors as e: log.config.exception("Error while loading config.py") _init_errors.append(e) try: if getattr(config_api, 'load_autoconfig', True): try: instance.read_yaml() except configexc.ConfigFileErrors as e: raise # caught in outer block except configexc.Error as e: desc = configexc.ConfigErrorDesc("Error", e) raise configexc.ConfigFileErrors('autoconfig.yml', [desc]) except configexc.ConfigFileErrors as e: log.config.exception("Error while loading config.py") _init_errors.append(e) configfiles.init() objects.backend = get_backend(args) earlyinit.init_with_backend(objects.backend)
def read(self): """Read the config.py via configfiles and check for errors.""" api = configfiles.read_config_py(self.filename) assert not api.errors
def test_reading_default_location(self, config_tmpdir): (config_tmpdir / 'config.py').write_text( 'c.colors.hints.bg = "red"', 'utf-8') configfiles.read_config_py() assert config.instance._values['colors.hints.bg'] == 'red'
def test_reading_missing_default_location(self, config_tmpdir): assert not (config_tmpdir / 'config.py').exists() configfiles.read_config_py() # Should not crash
def read(self, error=False): """Read the config.py via configfiles and check for errors.""" api = configfiles.read_config_py(self.filename, raising=not error) assert len(api.errors) == (1 if error else 0) return api
def test_reading_default_location(self, config_tmpdir, data_tmpdir): (config_tmpdir / 'config.py').write_text('c.colors.hints.bg = "red"', 'utf-8') configfiles.read_config_py() assert config.instance._values['colors.hints.bg'] == 'red'
def test_reading_missing_default_location(self, config_tmpdir, data_tmpdir): assert not (config_tmpdir / 'config.py').exists() configfiles.read_config_py() # Should not crash