From 7494d238ce6248a217ab958753777ed093d9411e Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 3 Dec 2018 13:17:23 +0100 Subject: [PATCH] Revert "Add types for most of qutebrowser.config" It breaks 'tsh' because of the *values annotation. This reverts commit 208d3db475cf5e5fd50840dd80bfef0fc85e98f5. --- mypy.ini | 36 ------ qutebrowser/config/config.py | 184 ++++++++++----------------- qutebrowser/config/configcommands.py | 97 ++++++-------- qutebrowser/config/configdata.py | 59 +++------ qutebrowser/config/configdiff.py | 7 +- qutebrowser/config/configexc.py | 35 ++--- qutebrowser/config/configfiles.py | 114 +++++++---------- qutebrowser/config/configinit.py | 20 ++- qutebrowser/config/configutils.py | 47 +++---- 9 files changed, 215 insertions(+), 384 deletions(-) diff --git a/mypy.ini b/mypy.ini index be5424327..288cc6515 100644 --- a/mypy.ini +++ b/mypy.ini @@ -61,39 +61,3 @@ disallow_incomplete_defs = True [mypy-qutebrowser.commands.cmdutils] disallow_untyped_defs = True disallow_incomplete_defs = True - -[mypy-qutebrowser.config.config] -disallow_untyped_defs = True -disallow_incomplete_defs = True - -[mypy-qutebrowser.config.configcache] -disallow_untyped_defs = True -disallow_incomplete_defs = True - -[mypy-qutebrowser.config.configcommands] -disallow_untyped_defs = True -disallow_incomplete_defs = True - -[mypy-qutebrowser.config.configdata] -disallow_untyped_defs = True -disallow_incomplete_defs = True - -[mypy-qutebrowser.config.configdiff] -disallow_untyped_defs = True -disallow_incomplete_defs = True - -[mypy-qutebrowser.config.configexc] -disallow_untyped_defs = True -disallow_incomplete_defs = True - -[mypy-qutebrowser.config.configfiles] -disallow_untyped_defs = True -disallow_incomplete_defs = True - -[mypy-qutebrowser.config.configinit] -disallow_untyped_defs = True -disallow_incomplete_defs = True - -[mypy-qutebrowser.config.configutils] -disallow_untyped_defs = True -disallow_incomplete_defs = True diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 44bf3ca77..1d7e34345 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -23,21 +23,18 @@ import copy import contextlib import functools import typing -from typing import Any -from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl +from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject from qutebrowser.config import configdata, configexc, configutils -from qutebrowser.utils import utils, log, jinja, urlmatch +from qutebrowser.utils import utils, log, jinja from qutebrowser.misc import objects from qutebrowser.keyinput import keyutils MYPY = False -if MYPY: # pragma: no cover - # pylint: disable=unused-import,useless-suppression - from typing import Tuple, MutableMapping - from qutebrowser.config import configcache, configfiles - from qutebrowser.misc import savemanager +if MYPY: + # pylint: disable=unused-import + from qutebrowser.config import configcache # pragma: no cover # An easy way to access the config from other code via config.val.foo val = typing.cast('ConfigContainer', None) @@ -64,7 +61,7 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name _function: Whether a function rather than a method is decorated. """ - def __init__(self, option: str, function: bool = False) -> None: + def __init__(self, option, function=False): """Save decorator arguments. Gets called on parse-time with the decorator arguments. @@ -77,7 +74,7 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name self._function = function change_filters.append(self) - def validate(self) -> None: + def validate(self): """Make sure the configured option or prefix exists. We can't do this in __init__ as configdata isn't ready yet. @@ -86,7 +83,7 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name not configdata.is_valid_prefix(self._option)): raise configexc.NoOptionError(self._option) - def _check_match(self, option: typing.Optional[str]) -> bool: + def _check_match(self, option): """Check if the given option matches the filter.""" if option is None: # Called directly, not from a config change event. @@ -99,7 +96,7 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name else: return False - def __call__(self, func: typing.Callable) -> typing.Callable: + def __call__(self, func): """Filter calls to the decorated function. Gets called when a function should be decorated. @@ -117,21 +114,20 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name """ if self._function: @functools.wraps(func) - def func_wrapper(option: str = None) -> typing.Any: + def wrapper(option=None): """Call the underlying function.""" if self._check_match(option): return func() return None - return func_wrapper else: @functools.wraps(func) - def meth_wrapper(wrapper_self: typing.Any, - option: str = None) -> typing.Any: + def wrapper(wrapper_self, option=None): """Call the underlying function.""" if self._check_match(option): return func(wrapper_self) return None - return meth_wrapper + + return wrapper class KeyConfig: @@ -144,22 +140,17 @@ class KeyConfig: _config: The Config object to be used. """ - _ReverseBindings = typing.Dict[str, typing.MutableSequence[str]] - - def __init__(self, config: 'Config') -> None: + def __init__(self, config): self._config = config - def _validate(self, key: keyutils.KeySequence, mode: str) -> None: + def _validate(self, key, mode): """Validate the given key and mode.""" # Catch old usage of this code assert isinstance(key, keyutils.KeySequence), key if mode not in configdata.DATA['bindings.default'].default: raise configexc.KeybindingError("Invalid mode {}!".format(mode)) - def get_bindings_for( - self, - mode: str - ) -> typing.Dict[keyutils.KeySequence, str]: + def get_bindings_for(self, mode): """Get the combined bindings for the given mode.""" bindings = dict(val.bindings.default[mode]) for key, binding in val.bindings.commands[mode].items(): @@ -169,9 +160,9 @@ class KeyConfig: bindings[key] = binding return bindings - def get_reverse_bindings_for(self, mode: str) -> '_ReverseBindings': + def get_reverse_bindings_for(self, mode): """Get a dict of commands to a list of bindings for the mode.""" - cmd_to_keys = {} # type: KeyConfig._ReverseBindings + cmd_to_keys = {} bindings = self.get_bindings_for(mode) for seq, full_cmd in sorted(bindings.items()): for cmd in full_cmd.split(';;'): @@ -184,10 +175,7 @@ class KeyConfig: cmd_to_keys[cmd].insert(0, str(seq)) return cmd_to_keys - def get_command(self, - key: keyutils.KeySequence, - mode: str, - default: bool = False) -> str: + def get_command(self, key, mode, default=False): """Get the command for a given key (or None).""" self._validate(key, mode) if default: @@ -196,11 +184,7 @@ class KeyConfig: bindings = self.get_bindings_for(mode) return bindings.get(key, None) - def bind(self, - key: keyutils.KeySequence, - command: str, *, - mode: str, - save_yaml: bool = False) -> None: + def bind(self, key, command, *, mode, save_yaml=False): """Add a new binding from key to command.""" if command is not None and not command.strip(): raise configexc.KeybindingError( @@ -208,8 +192,8 @@ class KeyConfig: 'mode'.format(key, mode)) self._validate(key, mode) - log.keyboard.vdebug( # type: ignore - "Adding binding {} -> {} in mode {}.".format(key, command, mode)) + log.keyboard.vdebug("Adding binding {} -> {} in mode {}.".format( + key, command, mode)) bindings = self._config.get_mutable_obj('bindings.commands') if mode not in bindings: @@ -217,10 +201,7 @@ class KeyConfig: bindings[mode][str(key)] = command self._config.update_mutables(save_yaml=save_yaml) - def bind_default(self, - key: keyutils.KeySequence, *, - mode: str = 'normal', - save_yaml: bool = False) -> None: + def bind_default(self, key, *, mode='normal', save_yaml=False): """Restore a default keybinding.""" self._validate(key, mode) @@ -232,10 +213,7 @@ class KeyConfig: "Can't find binding '{}' in {} mode".format(key, mode)) self._config.update_mutables(save_yaml=save_yaml) - def unbind(self, - key: keyutils.KeySequence, *, - mode: str = 'normal', - save_yaml: bool = False) -> None: + def unbind(self, key, *, mode='normal', save_yaml=False): """Unbind the given key in the given mode.""" self._validate(key, mode) @@ -276,27 +254,24 @@ class Config(QObject): MUTABLE_TYPES = (dict, list) changed = pyqtSignal(str) - def __init__(self, - yaml_config: 'configfiles.YamlConfig', - parent: QObject = None) -> None: + def __init__(self, yaml_config, parent=None): super().__init__(parent) self.changed.connect(_render_stylesheet.cache_clear) - self._mutables = {} # type: MutableMapping[str, Tuple[Any, Any]] + self._mutables = {} self._yaml = yaml_config self._init_values() - def _init_values(self) -> None: + def _init_values(self): """Populate the self._values dict.""" - self._values = {} # type: typing.Mapping + self._values = {} for name, opt in configdata.DATA.items(): self._values[name] = configutils.Values(opt) - def __iter__(self) -> typing.Iterator[configutils.Values]: + def __iter__(self): """Iterate over configutils.Values items.""" yield from self._values.values() - def init_save_manager(self, - save_manager: 'savemanager.SaveManager') -> None: + def init_save_manager(self, save_manager): """Make sure the config gets saved properly. We do this outside of __init__ because the config gets created before @@ -304,10 +279,7 @@ class Config(QObject): """ self._yaml.init_save_manager(save_manager) - def _set_value(self, - opt: 'configdata.Option', - value: Any, - pattern: urlmatch.UrlPattern = None) -> None: + def _set_value(self, opt, value, pattern=None): """Set the given option to the given value.""" if not isinstance(objects.backend, objects.NoBackend): if objects.backend not in opt.backends: @@ -322,12 +294,12 @@ class Config(QObject): log.config.debug("Config option changed: {} = {}".format( opt.name, value)) - def _check_yaml(self, opt: 'configdata.Option', save_yaml: bool) -> None: + def _check_yaml(self, opt, save_yaml): """Make sure the given option may be set in autoconfig.yml.""" if save_yaml and opt.no_autoconfig: raise configexc.NoAutoconfigError(opt.name) - def read_yaml(self) -> None: + def read_yaml(self): """Read the YAML settings from self._yaml.""" self._yaml.load() for values in self._yaml: @@ -335,7 +307,7 @@ class Config(QObject): self._set_value(values.opt, scoped.value, pattern=scoped.pattern) - def get_opt(self, name: str) -> 'configdata.Option': + def get_opt(self, name): """Get a configdata.Option object for the given setting.""" try: return configdata.DATA[name] @@ -346,10 +318,7 @@ class Config(QObject): name, deleted=deleted, renamed=renamed) raise exception from None - def get(self, - name: str, - url: QUrl = None, *, - fallback: bool = True) -> Any: + def get(self, name, url=None, *, fallback=True): """Get the given setting converted for Python code. Args: @@ -359,7 +328,7 @@ class Config(QObject): obj = self.get_obj(name, url=url, fallback=fallback) return opt.typ.to_py(obj) - def _maybe_copy(self, value: Any) -> Any: + def _maybe_copy(self, value): """Copy the value if it could potentially be mutated.""" if isinstance(value, self.MUTABLE_TYPES): # For mutable objects, create a copy so we don't accidentally @@ -370,10 +339,7 @@ class Config(QObject): assert value.__hash__ is not None, value return value - def get_obj(self, - name: str, *, - url: QUrl = None, - fallback: bool = True) -> Any: + def get_obj(self, name, *, url=None, fallback=True): """Get the given setting as object (for YAML/config.py). Note that the returned values are not watched for mutation. @@ -383,10 +349,7 @@ class Config(QObject): value = self._values[name].get_for_url(url, fallback=fallback) return self._maybe_copy(value) - def get_obj_for_pattern( - self, name: str, *, - pattern: typing.Optional[urlmatch.UrlPattern] - ) -> Any: + def get_obj_for_pattern(self, name, *, pattern): """Get the given setting as object (for YAML/config.py). This gets the overridden value for a given pattern, or @@ -396,8 +359,7 @@ class Config(QObject): value = self._values[name].get_for_pattern(pattern, fallback=False) return self._maybe_copy(value) - def get_mutable_obj(self, name: str, *, - pattern: urlmatch.UrlPattern = None) -> Any: + def get_mutable_obj(self, name, *, pattern=None): """Get an object which can be mutated, e.g. in a config.py. If a pattern is given, return the value for that pattern. @@ -422,8 +384,7 @@ class Config(QObject): return copy_value - def get_str(self, name: str, *, - pattern: urlmatch.UrlPattern = None) -> str: + def get_str(self, name, *, pattern=None): """Get the given setting as string. If a pattern is given, get the setting for the given pattern or @@ -434,10 +395,7 @@ class Config(QObject): value = values.get_for_pattern(pattern) return opt.typ.to_str(value) - def set_obj(self, name: str, - value: Any, *, - pattern: urlmatch.UrlPattern = None, - save_yaml: bool = False) -> None: + def set_obj(self, name, value, *, pattern=None, save_yaml=False): """Set the given setting from a YAML/config.py object. If save_yaml=True is given, store the new value to YAML. @@ -448,10 +406,7 @@ class Config(QObject): if save_yaml: self._yaml.set_obj(name, value, pattern=pattern) - def set_str(self, name: str, - value: str, *, - pattern: urlmatch.UrlPattern = None, - save_yaml: bool = False) -> None: + def set_str(self, name, value, *, pattern=None, save_yaml=False): """Set the given setting from a string. If save_yaml=True is given, store the new value to YAML. @@ -466,9 +421,7 @@ class Config(QObject): if save_yaml: self._yaml.set_obj(name, converted, pattern=pattern) - def unset(self, name: str, *, - save_yaml: bool = False, - pattern: urlmatch.UrlPattern = None) -> None: + def unset(self, name, *, save_yaml=False, pattern=None): """Set the given setting back to its default.""" opt = self.get_opt(name) self._check_yaml(opt, save_yaml) @@ -479,7 +432,7 @@ class Config(QObject): if save_yaml: self._yaml.unset(name, pattern=pattern) - def clear(self, *, save_yaml: bool = False) -> None: + def clear(self, *, save_yaml=False): """Clear all settings in the config. If save_yaml=True is given, also remove all customization from the YAML @@ -493,7 +446,7 @@ class Config(QObject): if save_yaml: self._yaml.clear() - def update_mutables(self, *, save_yaml: bool = False) -> None: + def update_mutables(self, *, save_yaml=False): """Update mutable settings if they changed. Every time someone calls get_obj() on a mutable object, we save a @@ -508,7 +461,7 @@ class Config(QObject): self.set_obj(name, new_value, save_yaml=save_yaml) self._mutables = {} - def dump_userconfig(self) -> str: + def dump_userconfig(self): """Get the part of the config which was changed by the user. Return: @@ -537,10 +490,7 @@ class ConfigContainer: _pattern: The URL pattern to be used. """ - def __init__(self, config: Config, - configapi: 'configfiles.ConfigAPI' = None, - prefix: str = '', - pattern: urlmatch.UrlPattern = None) -> None: + def __init__(self, config, configapi=None, prefix='', pattern=None): self._config = config self._prefix = prefix self._configapi = configapi @@ -548,13 +498,13 @@ class ConfigContainer: if configapi is None and pattern is not None: raise TypeError("Can't use pattern without configapi!") - def __repr__(self) -> str: + def __repr__(self): return utils.get_repr(self, constructor=True, config=self._config, configapi=self._configapi, prefix=self._prefix, pattern=self._pattern) @contextlib.contextmanager - def _handle_error(self, action: str, name: str) -> typing.Iterator[None]: + def _handle_error(self, action, name): try: yield except configexc.Error as e: @@ -563,7 +513,7 @@ class ConfigContainer: text = "While {} '{}'".format(action, name) self._configapi.errors.append(configexc.ConfigErrorDesc(text, e)) - def __getattr__(self, attr: str) -> Any: + def __getattr__(self, attr): """Get an option or a new ConfigContainer with the added prefix. If we get an option which exists, we return the value for it. @@ -590,7 +540,7 @@ class ConfigContainer: return self._config.get_mutable_obj( name, pattern=self._pattern) - def __setattr__(self, attr: str, value: Any) -> None: + def __setattr__(self, attr, value): """Set the given option in the config.""" if attr.startswith('_'): super().__setattr__(attr, value) @@ -600,7 +550,7 @@ class ConfigContainer: with self._handle_error('setting', name): self._config.set_obj(name, value, pattern=self._pattern) - def _join(self, attr: str) -> str: + def _join(self, attr): """Get the prefix joined with the given attribute.""" if self._prefix: return '{}.{}'.format(self._prefix, attr) @@ -608,10 +558,8 @@ class ConfigContainer: return attr -def set_register_stylesheet(obj: QObject, *, - stylesheet: str = None, - update: bool = True) -> None: - """Set the stylesheet for an object. +def set_register_stylesheet(obj, *, stylesheet=None, update=True): + """Set the stylesheet for an object based on it's STYLESHEET attribute. Also, register an update when the config is changed. @@ -626,7 +574,7 @@ def set_register_stylesheet(obj: QObject, *, @functools.lru_cache() -def _render_stylesheet(stylesheet: str) -> str: +def _render_stylesheet(stylesheet): """Render the given stylesheet jinja template.""" with jinja.environment.no_autoescape(): template = jinja.environment.from_string(stylesheet) @@ -642,9 +590,7 @@ class StyleSheetObserver(QObject): _stylesheet: The stylesheet template to use. """ - def __init__(self, obj: QObject, - stylesheet: typing.Optional[str], - update: bool) -> None: + def __init__(self, obj, stylesheet, update): super().__init__() self._obj = obj self._update = update @@ -653,11 +599,11 @@ class StyleSheetObserver(QObject): if self._update: self.setParent(self._obj) if stylesheet is None: - self._stylesheet = obj.STYLESHEET # type: str + self._stylesheet = obj.STYLESHEET else: self._stylesheet = stylesheet - def _get_stylesheet(self) -> str: + def _get_stylesheet(self): """Format a stylesheet based on a template. Return: @@ -666,15 +612,19 @@ class StyleSheetObserver(QObject): return _render_stylesheet(self._stylesheet) @pyqtSlot() - def _update_stylesheet(self) -> None: + def _update_stylesheet(self): """Update the stylesheet for obj.""" self._obj.setStyleSheet(self._get_stylesheet()) - def register(self) -> None: - """Do a first update and listen for more.""" + def register(self): + """Do a first update and listen for more. + + Args: + update: if False, don't listen for future updates. + """ qss = self._get_stylesheet() - log.config.vdebug( # type: ignore - "stylesheet for {}: {}".format(self._obj.__class__.__name__, qss)) + log.config.vdebug("stylesheet for {}: {}".format( + self._obj.__class__.__name__, qss)) self._obj.setStyleSheet(qss) if self._update: instance.changed.connect(self._update_stylesheet) diff --git a/qutebrowser/config/configcommands.py b/qutebrowser/config/configcommands.py index 0ee77fcc9..574bc06af 100644 --- a/qutebrowser/config/configcommands.py +++ b/qutebrowser/config/configcommands.py @@ -19,7 +19,6 @@ """Commands related to the configuration.""" -import typing import os.path import contextlib @@ -32,34 +31,24 @@ from qutebrowser.config import configtypes, configexc, configfiles, configdata from qutebrowser.misc import editor from qutebrowser.keyinput import keyutils -MYPY = False -if MYPY: # pragma: no cover - # pylint: disable=unused-import,useless-suppression - from qutebrowser.config.config import Config, KeyConfig - class ConfigCommands: """qutebrowser commands related to the configuration.""" - def __init__(self, - config: 'Config', - keyconfig: 'KeyConfig') -> None: + def __init__(self, config, keyconfig): self._config = config self._keyconfig = keyconfig @contextlib.contextmanager - def _handle_config_error(self) -> typing.Iterator[None]: + def _handle_config_error(self): """Catch errors in set_command and raise CommandError.""" try: yield except configexc.Error as e: raise cmdutils.CommandError(str(e)) - def _parse_pattern( - self, - pattern: typing.Optional[str] - ) -> typing.Optional[urlmatch.UrlPattern]: + def _parse_pattern(self, pattern): """Parse a pattern string argument to a pattern.""" if pattern is None: return None @@ -70,15 +59,14 @@ class ConfigCommands: raise cmdutils.CommandError("Error while parsing {}: {}" .format(pattern, str(e))) - def _parse_key(self, key: str) -> keyutils.KeySequence: + def _parse_key(self, key): """Parse a key argument.""" try: return keyutils.KeySequence.parse(key) except keyutils.KeyParseError as e: raise cmdutils.CommandError(str(e)) - def _print_value(self, option: str, - pattern: typing.Optional[urlmatch.UrlPattern]) -> None: + def _print_value(self, option, pattern): """Print the value of the given option.""" with self._handle_config_error(): value = self._config.get_str(option, pattern=pattern) @@ -93,9 +81,8 @@ class ConfigCommands: @cmdutils.argument('value', completion=configmodel.value) @cmdutils.argument('win_id', value=cmdutils.Value.win_id) @cmdutils.argument('pattern', flag='u') - def set(self, win_id: int, option: str = None, value: str = None, - temp: bool = False, print_: bool = False, - *, pattern: str = None) -> None: + def set(self, win_id, option=None, value=None, temp=False, print_=False, + *, pattern=None): """Set an option. If the option name ends with '?' or no value is provided, the @@ -121,28 +108,28 @@ class ConfigCommands: raise cmdutils.CommandError("Toggling values was moved to the " ":config-cycle command") - parsed_pattern = self._parse_pattern(pattern) + pattern = self._parse_pattern(pattern) if option.endswith('?') and option != '?': - self._print_value(option[:-1], pattern=parsed_pattern) + self._print_value(option[:-1], pattern=pattern) return with self._handle_config_error(): if value is None: - self._print_value(option, pattern=parsed_pattern) + self._print_value(option, pattern=pattern) else: - self._config.set_str(option, value, pattern=parsed_pattern, + self._config.set_str(option, value, pattern=pattern, save_yaml=not temp) if print_: - self._print_value(option, pattern=parsed_pattern) + self._print_value(option, pattern=pattern) @cmdutils.register(instance='config-commands', maxsplit=1, no_cmd_split=True, no_replace_variables=True) @cmdutils.argument('command', completion=configmodel.bind) @cmdutils.argument('win_id', value=cmdutils.Value.win_id) - def bind(self, win_id: str, key: str = None, command: str = None, *, - mode: str = 'normal', default: bool = False) -> None: + def bind(self, win_id, key=None, command=None, *, mode='normal', + default=False): """Bind a key to a command. If no command is given, show the current binding for the given key. @@ -187,7 +174,7 @@ class ConfigCommands: self._keyconfig.bind(seq, command, mode=mode, save_yaml=True) @cmdutils.register(instance='config-commands') - def unbind(self, key: str, *, mode: str = 'normal') -> None: + def unbind(self, key, *, mode='normal'): """Unbind a keychain. Args: @@ -204,9 +191,8 @@ class ConfigCommands: @cmdutils.argument('option', completion=configmodel.option) @cmdutils.argument('values', completion=configmodel.value) @cmdutils.argument('pattern', flag='u') - def config_cycle(self, option: str, *values: str, - pattern: str = None, - temp: bool = False, print_: bool = False) -> None: + def config_cycle(self, option, *values, pattern=None, temp=False, + print_=False): """Cycle an option between multiple values. Args: @@ -216,15 +202,15 @@ class ConfigCommands: temp: Set value temporarily until qutebrowser is closed. print_: Print the value after setting. """ - parsed_pattern = self._parse_pattern(pattern) + pattern = self._parse_pattern(pattern) with self._handle_config_error(): opt = self._config.get_opt(option) - old_value = self._config.get_obj_for_pattern( - option, pattern=parsed_pattern) + old_value = self._config.get_obj_for_pattern(option, + pattern=pattern) if not values and isinstance(opt.typ, configtypes.Bool): - values = ('true', 'false') + values = ['true', 'false'] if len(values) < 2: raise cmdutils.CommandError("Need at least two values for " @@ -233,25 +219,25 @@ class ConfigCommands: # Use the next valid value from values, or the first if the current # value does not appear in the list with self._handle_config_error(): - cycle_values = [opt.typ.from_str(val) for val in values] + values = [opt.typ.from_str(val) for val in values] try: - idx = cycle_values.index(old_value) - idx = (idx + 1) % len(cycle_values) - value = cycle_values[idx] + idx = values.index(old_value) + idx = (idx + 1) % len(values) + value = values[idx] except ValueError: - value = cycle_values[0] + value = values[0] with self._handle_config_error(): - self._config.set_obj(option, value, pattern=parsed_pattern, + self._config.set_obj(option, value, pattern=pattern, save_yaml=not temp) if print_: - self._print_value(option, pattern=parsed_pattern) + self._print_value(option, pattern=pattern) @cmdutils.register(instance='config-commands') @cmdutils.argument('option', completion=configmodel.customized_option) - def config_unset(self, option: str, temp: bool = False) -> None: + def config_unset(self, option, temp=False): """Unset an option. This sets an option back to its default and removes it from @@ -266,8 +252,7 @@ class ConfigCommands: @cmdutils.register(instance='config-commands') @cmdutils.argument('option', completion=configmodel.list_option) - def config_list_add(self, option: str, value: str, - temp: bool = False) -> None: + def config_list_add(self, option, value, temp=False): """Append a value to a config option that is a list. Args: @@ -288,8 +273,7 @@ class ConfigCommands: @cmdutils.register(instance='config-commands') @cmdutils.argument('option', completion=configmodel.dict_option) - def config_dict_add(self, option: str, key: str, value: str, - temp: bool = False, replace: bool = False) -> None: + def config_dict_add(self, option, key, value, temp=False, replace=False): """Add a key/value pair to a dictionary option. Args: @@ -318,8 +302,7 @@ class ConfigCommands: @cmdutils.register(instance='config-commands') @cmdutils.argument('option', completion=configmodel.list_option) - def config_list_remove(self, option: str, value: str, - temp: bool = False) -> None: + def config_list_remove(self, option, value, temp=False): """Remove a value from a list. Args: @@ -346,8 +329,7 @@ class ConfigCommands: @cmdutils.register(instance='config-commands') @cmdutils.argument('option', completion=configmodel.dict_option) - def config_dict_remove(self, option: str, key: str, - temp: bool = False) -> None: + def config_dict_remove(self, option, key, temp=False): """Remove a key from a dict. Args: @@ -372,7 +354,7 @@ class ConfigCommands: self._config.update_mutables(save_yaml=not temp) @cmdutils.register(instance='config-commands') - def config_clear(self, save: bool = False) -> None: + def config_clear(self, save=False): """Set all settings back to their default. Args: @@ -382,7 +364,7 @@ class ConfigCommands: self._config.clear(save_yaml=save) @cmdutils.register(instance='config-commands') - def config_source(self, filename: str = None, clear: bool = False) -> None: + def config_source(self, filename=None, clear=False): """Read a config.py file. Args: @@ -404,13 +386,13 @@ class ConfigCommands: raise cmdutils.CommandError(e) @cmdutils.register(instance='config-commands') - def config_edit(self, no_source: bool = False) -> None: + def config_edit(self, no_source=False): """Open the config.py file in the editor. Args: no_source: Don't re-source the config file after editing. """ - def on_file_updated() -> None: + def on_file_updated(): """Source the new config when editing finished. This can't use cmdutils.CommandError as it's run async. @@ -428,8 +410,7 @@ class ConfigCommands: ed.edit_file(filename) @cmdutils.register(instance='config-commands') - def config_write_py(self, filename: str = None, - force: bool = False, defaults: bool = False) -> None: + def config_write_py(self, filename=None, force=False, defaults=False): """Write the current configuration to a config.py file. Args: @@ -448,13 +429,13 @@ class ConfigCommands: raise cmdutils.CommandError("{} already exists - use --force to " "overwrite!".format(filename)) - options = [] # type: typing.List if defaults: options = [(None, opt, opt.default) for _name, opt in sorted(configdata.DATA.items())] bindings = dict(configdata.DATA['bindings.default'].default) commented = True else: + options = [] for values in self._config: for scoped in values: options.append((scoped.pattern, values.opt, scoped.value)) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index c93032387..dace0772a 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -24,18 +24,14 @@ Module attributes: DATA: A dict of Option objects after init() has been called. """ -import typing -from typing import Optional # pylint: disable=unused-import import functools import attr from qutebrowser.config import configtypes from qutebrowser.utils import usertypes, qtutils, utils -DATA = typing.cast(typing.Mapping[str, 'Option'], None) -MIGRATIONS = typing.cast('Migrations', None) - -_BackendDict = typing.Mapping[str, typing.Union[str, bool]] +DATA = None +MIGRATIONS = None @attr.s @@ -46,15 +42,15 @@ class Option: Note that this is just an option which exists, with no value associated. """ - name = attr.ib() # type: str - typ = attr.ib() # type: configtypes.BaseType - default = attr.ib() # type: typing.Any - backends = attr.ib() # type: typing.Iterable[usertypes.Backend] - raw_backends = attr.ib() # type: Optional[typing.Mapping[str, bool]] - description = attr.ib() # type: str - supports_pattern = attr.ib(default=False) # type: bool - restart = attr.ib(default=False) # type: bool - no_autoconfig = attr.ib(default=False) # type: bool + name = attr.ib() + typ = attr.ib() + default = attr.ib() + backends = attr.ib() + raw_backends = attr.ib() + description = attr.ib() + supports_pattern = attr.ib(default=False) + restart = attr.ib(default=False) + no_autoconfig = attr.ib(default=False) @attr.s @@ -67,13 +63,11 @@ class Migrations: deleted: A list of option names which have been removed. """ - renamed = attr.ib( - default=attr.Factory(dict)) # type: typing.Dict[str, str] - deleted = attr.ib( - default=attr.Factory(list)) # type: typing.List[str] + renamed = attr.ib(default=attr.Factory(dict)) + deleted = attr.ib(default=attr.Factory(list)) -def _raise_invalid_node(name: str, what: str, node: typing.Any) -> None: +def _raise_invalid_node(name, what, node): """Raise an exception for an invalid configdata YAML node. Args: @@ -85,16 +79,13 @@ def _raise_invalid_node(name: str, what: str, node: typing.Any) -> None: name, what, node)) -def _parse_yaml_type( - name: str, - node: typing.Union[str, typing.Mapping[str, typing.Any]], -) -> configtypes.BaseType: +def _parse_yaml_type(name, node): if isinstance(node, str): # e.g: # type: Bool # -> create the type object without any arguments type_name = node - kwargs = {} # type: typing.MutableMapping[str, typing.Any] + kwargs = {} elif isinstance(node, dict): # e.g: # type: @@ -132,10 +123,7 @@ def _parse_yaml_type( type_name, node, e)) -def _parse_yaml_backends_dict( - name: str, - node: _BackendDict, -) -> typing.Sequence[usertypes.Backend]: +def _parse_yaml_backends_dict(name, node): """Parse a dict definition for backends. Example: @@ -172,10 +160,7 @@ def _parse_yaml_backends_dict( return backends -def _parse_yaml_backends( - name: str, - node: typing.Union[None, str, _BackendDict], -) -> typing.Sequence[usertypes.Backend]: +def _parse_yaml_backends(name, node): """Parse a backend node in the yaml. It can have one of those four forms: @@ -202,9 +187,7 @@ def _parse_yaml_backends( raise utils.Unreachable -def _read_yaml( - yaml_data: str, -) -> typing.Tuple[typing.Mapping[str, Option], Migrations]: +def _read_yaml(yaml_data): """Read config data from a YAML file. Args: @@ -266,12 +249,12 @@ def _read_yaml( @functools.lru_cache(maxsize=256) -def is_valid_prefix(prefix: str) -> bool: +def is_valid_prefix(prefix): """Check whether the given prefix is a valid prefix for some option.""" return any(key.startswith(prefix + '.') for key in DATA) -def init() -> None: +def init(): """Initialize configdata from the YAML file.""" global DATA, MIGRATIONS DATA, MIGRATIONS = _read_yaml(utils.read_file('config/configdata.yml')) diff --git a/qutebrowser/config/configdiff.py b/qutebrowser/config/configdiff.py index ba78f64b4..9f8b70a26 100644 --- a/qutebrowser/config/configdiff.py +++ b/qutebrowser/config/configdiff.py @@ -19,7 +19,6 @@ """Code to show a diff of the legacy config format.""" -import typing # pylint: disable=unused-import,useless-suppression import difflib import os.path @@ -728,10 +727,10 @@ scroll right """ -def get_diff() -> str: +def get_diff(): """Get a HTML diff for the old config files.""" - old_conf_lines = [] # type: typing.MutableSequence[str] - old_key_lines = [] # type: typing.MutableSequence[str] + old_conf_lines = [] + old_key_lines = [] for filename, dest in [('qutebrowser.conf', old_conf_lines), ('keys.conf', old_key_lines)]: diff --git a/qutebrowser/config/configexc.py b/qutebrowser/config/configexc.py index b1dc04e09..051ed971a 100644 --- a/qutebrowser/config/configexc.py +++ b/qutebrowser/config/configexc.py @@ -19,10 +19,9 @@ """Exceptions related to config parsing.""" -import typing import attr -from qutebrowser.utils import jinja, usertypes +from qutebrowser.utils import jinja class Error(Exception): @@ -34,7 +33,7 @@ class NoAutoconfigError(Error): """Raised when this option can't be set in autoconfig.yml.""" - def __init__(self, name: str) -> None: + def __init__(self, name): super().__init__("The {} setting can only be set in config.py!" .format(name)) @@ -43,11 +42,7 @@ class BackendError(Error): """Raised when this setting is unavailable with the current backend.""" - def __init__( - self, name: str, - backend: usertypes.Backend, - raw_backends: typing.Optional[typing.Mapping[str, bool]] - ) -> None: + def __init__(self, name, backend, raw_backends): if raw_backends is None or not raw_backends[backend.name]: msg = ("The {} setting is not available with the {} backend!" .format(name, backend.name)) @@ -62,7 +57,7 @@ class NoPatternError(Error): """Raised when the given setting does not support URL patterns.""" - def __init__(self, name: str) -> None: + def __init__(self, name): super().__init__("The {} setting does not support URL patterns!" .format(name)) @@ -76,7 +71,7 @@ class ValidationError(Error): msg: Additional error message. """ - def __init__(self, value: typing.Any, msg: str) -> None: + def __init__(self, value, msg): super().__init__("Invalid value '{}' - {}".format(value, msg)) self.option = None @@ -90,9 +85,7 @@ class NoOptionError(Error): """Raised when an option was not found.""" - def __init__(self, option: str, *, - deleted: bool = False, - renamed: str = None) -> None: + def __init__(self, option, *, deleted=False, renamed=None): if deleted: assert renamed is None suffix = ' (this option was removed from qutebrowser)' @@ -116,18 +109,18 @@ class ConfigErrorDesc: traceback: The formatted traceback of the exception. """ - text = attr.ib() # type: str - exception = attr.ib() # type: typing.Union[str, Exception] - traceback = attr.ib(None) # type: str + text = attr.ib() + exception = attr.ib() + traceback = attr.ib(None) - def __str__(self) -> str: + def __str__(self): if self.traceback: return '{} - {}: {}'.format(self.text, self.exception.__class__.__name__, self.exception) return '{}: {}'.format(self.text, self.exception) - def with_text(self, text: str) -> 'ConfigErrorDesc': + def with_text(self, text): """Get a new ConfigErrorDesc with the given text appended.""" return self.__class__(text='{} ({})'.format(self.text, text), exception=self.exception, @@ -138,15 +131,13 @@ class ConfigFileErrors(Error): """Raised when multiple errors occurred inside the config.""" - def __init__(self, - basename: str, - errors: typing.Sequence[ConfigErrorDesc]) -> None: + def __init__(self, basename, errors): super().__init__("Errors occurred while reading {}:\n{}".format( basename, '\n'.join(' {}'.format(e) for e in errors))) self.basename = basename self.errors = errors - def to_html(self) -> str: + def to_html(self): """Get the error texts as a HTML snippet.""" template = jinja.environment.from_string(""" Errors occurred while reading {{ basename }}: diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py index 54ca91488..b4c8ea4ec 100644 --- a/qutebrowser/config/configfiles.py +++ b/qutebrowser/config/configfiles.py @@ -27,7 +27,6 @@ import textwrap import traceback import configparser import contextlib -import typing import yaml from PyQt5.QtCore import pyqtSignal, QObject, QSettings @@ -37,21 +36,16 @@ from qutebrowser.config import configexc, config, configdata, configutils from qutebrowser.keyinput import keyutils from qutebrowser.utils import standarddir, utils, qtutils, log, urlmatch -MYPY = False -if MYPY: - # pylint: disable=unused-import, useless-suppression - from qutebrowser.misc import savemanager - # The StateConfig instance -state = typing.cast('StateConfig', None) +state = None class StateConfig(configparser.ConfigParser): """The "state" file saving various application state.""" - def __init__(self) -> None: + def __init__(self): super().__init__() self._filename = os.path.join(standarddir.data(), 'state') self.read(self._filename, encoding='utf-8') @@ -65,8 +59,7 @@ class StateConfig(configparser.ConfigParser): for key in deleted_keys: self['general'].pop(key, None) - def init_save_manager(self, - save_manager: 'savemanager.SaveManager') -> None: + def init_save_manager(self, save_manager): """Make sure the config gets saved properly. We do this outside of __init__ because the config gets created before @@ -74,7 +67,7 @@ class StateConfig(configparser.ConfigParser): """ save_manager.add_saveable('state-config', self._save) - def _save(self) -> None: + def _save(self): """Save the state file to the configured location.""" with open(self._filename, 'w', encoding='utf-8') as f: self.write(f) @@ -91,20 +84,17 @@ class YamlConfig(QObject): VERSION = 2 changed = pyqtSignal() - _SettingsType = typing.Dict[str, typing.Dict[str, typing.Any]] - - def __init__(self, parent: QObject = None) -> None: + def __init__(self, parent=None): super().__init__(parent) self._filename = os.path.join(standarddir.config(auto=True), 'autoconfig.yml') - self._dirty = False + self._dirty = None - self._values = {} # type: typing.Dict[str, configutils.Values] + self._values = {} for name, opt in configdata.DATA.items(): self._values[name] = configutils.Values(opt) - def init_save_manager(self, - save_manager: 'savemanager.SaveManager') -> None: + def init_save_manager(self, save_manager): """Make sure the config gets saved properly. We do this outside of __init__ because the config gets created before @@ -112,21 +102,21 @@ class YamlConfig(QObject): """ save_manager.add_saveable('yaml-config', self._save, self.changed) - def __iter__(self) -> typing.Iterator[configutils.Values]: + def __iter__(self): """Iterate over configutils.Values items.""" yield from self._values.values() - def _mark_changed(self) -> None: + def _mark_changed(self): """Mark the YAML config as changed.""" self._dirty = True self.changed.emit() - def _save(self) -> None: + def _save(self): """Save the settings to the YAML file if they've changed.""" if not self._dirty: return - settings = {} # type: YamlConfig._SettingsType + settings = {} for name, values in sorted(self._values.items()): if not values: continue @@ -145,10 +135,7 @@ class YamlConfig(QObject): """.lstrip('\n'))) utils.yaml_dump(data, f) - def _pop_object(self, - yaml_data: typing.Any, - key: str, - typ: type) -> typing.Any: + def _pop_object(self, yaml_data, key, typ): """Get a global object from the given data.""" if not isinstance(yaml_data, dict): desc = configexc.ConfigErrorDesc("While loading data", @@ -171,7 +158,7 @@ class YamlConfig(QObject): return data - def load(self) -> None: + def load(self): """Load configuration from the configured YAML file.""" try: with open(self._filename, 'r', encoding='utf-8') as f: @@ -202,19 +189,18 @@ class YamlConfig(QObject): self._validate(settings) self._build_values(settings) - def _load_settings_object(self, yaml_data: typing.Any) -> '_SettingsType': + def _load_settings_object(self, yaml_data): """Load the settings from the settings: key.""" return self._pop_object(yaml_data, 'settings', dict) - def _load_legacy_settings_object(self, - yaml_data: typing.Any) -> '_SettingsType': + def _load_legacy_settings_object(self, yaml_data): data = self._pop_object(yaml_data, 'global', dict) settings = {} for name, value in data.items(): settings[name] = {'global': value} return settings - def _build_values(self, settings: typing.Mapping) -> None: + def _build_values(self, settings): """Build up self._values from the values in the given dict.""" errors = [] for name, yaml_values in settings.items(): @@ -247,8 +233,7 @@ class YamlConfig(QObject): if errors: raise configexc.ConfigFileErrors('autoconfig.yml', errors) - def _migrate_bool(self, settings: _SettingsType, name: str, - true_value: str, false_value: str) -> None: + def _migrate_bool(self, settings, name, true_value, false_value): """Migrate a boolean in the settings.""" if name in settings: for scope, val in settings[name].items(): @@ -256,7 +241,7 @@ class YamlConfig(QObject): settings[name][scope] = true_value if val else false_value self._mark_changed() - def _handle_migrations(self, settings: _SettingsType) -> '_SettingsType': + def _handle_migrations(self, settings): """Migrate older configs to the newest format.""" # Simple renamed/deleted options for name in list(settings): @@ -314,7 +299,7 @@ class YamlConfig(QObject): return settings - def _validate(self, settings: _SettingsType) -> None: + def _validate(self, settings): """Make sure all settings exist.""" unknown = [] for name in settings: @@ -327,19 +312,18 @@ class YamlConfig(QObject): for e in sorted(unknown)] raise configexc.ConfigFileErrors('autoconfig.yml', errors) - def set_obj(self, name: str, value: typing.Any, *, - pattern: urlmatch.UrlPattern = None) -> None: + def set_obj(self, name, value, *, pattern=None): """Set the given setting to the given value.""" self._values[name].add(value, pattern) self._mark_changed() - def unset(self, name: str, *, pattern: urlmatch.UrlPattern = None) -> None: + def unset(self, name, *, pattern=None): """Remove the given option name if it's configured.""" changed = self._values[name].remove(pattern) if changed: self._mark_changed() - def clear(self) -> None: + def clear(self): """Clear all values from the YAML file.""" for values in self._values.values(): values.clear() @@ -362,15 +346,15 @@ class ConfigAPI: datadir: The qutebrowser data directory, as pathlib.Path. """ - def __init__(self, conf: config.Config, keyconfig: config.KeyConfig): + def __init__(self, conf, keyconfig): self._config = conf self._keyconfig = keyconfig - self.errors = [] # type: typing.List[configexc.ConfigErrorDesc] + self.errors = [] self.configdir = pathlib.Path(standarddir.config()) self.datadir = pathlib.Path(standarddir.data()) @contextlib.contextmanager - def _handle_error(self, action: str, name: str) -> typing.Iterator[None]: + def _handle_error(self, action, name): """Catch config-related exceptions and save them in self.errors.""" try: yield @@ -388,40 +372,40 @@ class ConfigAPI: text = "While {} '{}' and parsing key".format(action, name) self.errors.append(configexc.ConfigErrorDesc(text, e)) - def finalize(self) -> None: + def finalize(self): """Do work which needs to be done after reading config.py.""" self._config.update_mutables() - def load_autoconfig(self) -> None: + def load_autoconfig(self): """Load the autoconfig.yml file which is used for :set/:bind/etc.""" with self._handle_error('reading', 'autoconfig.yml'): read_autoconfig() - def get(self, name: str, pattern: str = None) -> typing.Any: + def get(self, name, pattern=None): """Get a setting value from the config, optionally with a pattern.""" with self._handle_error('getting', name): urlpattern = urlmatch.UrlPattern(pattern) if pattern else None return self._config.get_mutable_obj(name, pattern=urlpattern) - def set(self, name: str, value: typing.Any, pattern: str = None) -> None: + def set(self, name, value, pattern=None): """Set a setting value in the config, optionally with a pattern.""" with self._handle_error('setting', name): urlpattern = urlmatch.UrlPattern(pattern) if pattern else None self._config.set_obj(name, value, pattern=urlpattern) - def bind(self, key: str, command: str, mode: str = 'normal') -> None: + def bind(self, key, command, mode='normal'): """Bind a key to a command, with an optional key mode.""" with self._handle_error('binding', key): seq = keyutils.KeySequence.parse(key) self._keyconfig.bind(seq, command, mode=mode) - def unbind(self, key: str, mode: str = 'normal') -> None: + def unbind(self, key, mode='normal'): """Unbind a key from a command, with an optional key mode.""" with self._handle_error('unbinding', key): seq = keyutils.KeySequence.parse(key) self._keyconfig.unbind(seq, mode=mode) - def source(self, filename: str) -> None: + def source(self, filename): """Read the given config file from disk.""" if not os.path.isabs(filename): filename = str(self.configdir / filename) @@ -432,7 +416,7 @@ class ConfigAPI: self.errors += e.errors @contextlib.contextmanager - def pattern(self, pattern: str) -> typing.Iterator[config.ConfigContainer]: + def pattern(self, pattern): """Get a ConfigContainer for the given pattern.""" # We need to propagate the exception so we don't need to return # something. @@ -446,21 +430,17 @@ class ConfigPyWriter: """Writer for config.py files from given settings.""" - def __init__( - self, - options: typing.List, - bindings: typing.MutableMapping[str, typing.Mapping[str, str]], *, - commented: bool) -> None: + def __init__(self, options, bindings, *, commented): self._options = options self._bindings = bindings self._commented = commented - def write(self, filename: str) -> None: + def write(self, filename): """Write the config to the given file.""" with open(filename, 'w', encoding='utf-8') as f: f.write('\n'.join(self._gen_lines())) - def _line(self, line: str) -> str: + def _line(self, line): """Get an (optionally commented) line.""" if self._commented: if line.startswith('#'): @@ -470,7 +450,7 @@ class ConfigPyWriter: else: return line - def _gen_lines(self) -> typing.Iterator[str]: + def _gen_lines(self): """Generate a config.py with the given settings/bindings. Yields individual lines. @@ -479,7 +459,7 @@ class ConfigPyWriter: yield from self._gen_options() yield from self._gen_bindings() - def _gen_header(self) -> typing.Iterator[str]: + def _gen_header(self): """Generate the initial header of the config.""" yield self._line("# Autogenerated config.py") yield self._line("# Documentation:") @@ -501,7 +481,7 @@ class ConfigPyWriter: yield self._line("# config.load_autoconfig()") yield '' - def _gen_options(self) -> typing.Iterator[str]: + def _gen_options(self): """Generate the options part of the config.""" for pattern, opt, value in self._options: if opt.name in ['bindings.commands', 'bindings.default']: @@ -529,7 +509,7 @@ class ConfigPyWriter: opt.name, value, str(pattern))) yield '' - def _gen_bindings(self) -> typing.Iterator[str]: + def _gen_bindings(self): """Generate the bindings part of the config.""" normal_bindings = self._bindings.pop('normal', {}) if normal_bindings: @@ -547,7 +527,7 @@ class ConfigPyWriter: yield '' -def read_config_py(filename: str, raising: bool = False) -> None: +def read_config_py(filename, raising=False): """Read a config.py file. Arguments; @@ -563,8 +543,8 @@ def read_config_py(filename: str, raising: bool = False) -> None: basename = os.path.basename(filename) module = types.ModuleType('config') - module.config = api # type: ignore - module.c = container # type: ignore + module.config = api + module.c = container module.__file__ = filename try: @@ -609,7 +589,7 @@ def read_config_py(filename: str, raising: bool = False) -> None: raise configexc.ConfigFileErrors('config.py', api.errors) -def read_autoconfig() -> None: +def read_autoconfig(): """Read the autoconfig.yml file.""" try: config.instance.read_yaml() @@ -621,7 +601,7 @@ def read_autoconfig() -> None: @contextlib.contextmanager -def saved_sys_properties() -> typing.Iterator[None]: +def saved_sys_properties(): """Save various sys properties such as sys.path and sys.modules.""" old_path = sys.path.copy() old_modules = sys.modules.copy() @@ -634,7 +614,7 @@ def saved_sys_properties() -> typing.Iterator[None]: del sys.modules[module] -def init() -> None: +def init(): """Initialize config storage not related to the main config.""" global state state = StateConfig() diff --git a/qutebrowser/config/configinit.py b/qutebrowser/config/configinit.py index ff0fd0e41..de9651064 100644 --- a/qutebrowser/config/configinit.py +++ b/qutebrowser/config/configinit.py @@ -19,10 +19,8 @@ """Initialization of the configuration.""" -import argparse import os.path import sys -import typing from PyQt5.QtWidgets import QMessageBox @@ -32,14 +30,14 @@ from qutebrowser.config import (config, configdata, configfiles, configtypes, from qutebrowser.utils import (objreg, usertypes, log, standarddir, message, qtutils) from qutebrowser.config import configcache -from qutebrowser.misc import msgbox, objects, savemanager +from qutebrowser.misc import msgbox, objects # Error which happened during init, so we can show a message box. _init_errors = None -def early_init(args: argparse.Namespace) -> None: +def early_init(args): """Initialize the part of the config which works without a QApplication.""" configdata.init() @@ -87,7 +85,7 @@ def early_init(args: argparse.Namespace) -> None: _init_envvars() -def _init_envvars() -> None: +def _init_envvars(): """Initialize environment variables which need to be set early.""" if objects.backend == usertypes.Backend.QtWebEngine: software_rendering = config.val.qt.force_software_rendering @@ -109,7 +107,7 @@ def _init_envvars() -> None: @config.change_filter('fonts.monospace', function=True) -def _update_monospace_fonts() -> None: +def _update_monospace_fonts(): """Update all fonts if fonts.monospace was set.""" configtypes.Font.monospace_fonts = config.val.fonts.monospace for name, opt in configdata.DATA.items(): @@ -125,7 +123,7 @@ def _update_monospace_fonts() -> None: config.instance.changed.emit(name) -def get_backend(args: argparse.Namespace) -> usertypes.Backend: +def get_backend(args): """Find out what backend to use based on available libraries.""" str_to_backend = { 'webkit': usertypes.Backend.QtWebKit, @@ -138,7 +136,7 @@ def get_backend(args: argparse.Namespace) -> usertypes.Backend: return str_to_backend[config.val.backend] -def late_init(save_manager: savemanager.SaveManager) -> None: +def late_init(save_manager): """Initialize the rest of the config after the QApplication is created.""" global _init_errors if _init_errors is not None: @@ -154,7 +152,7 @@ def late_init(save_manager: savemanager.SaveManager) -> None: configfiles.state.init_save_manager(save_manager) -def qt_args(namespace: argparse.Namespace) -> typing.List[str]: +def qt_args(namespace): """Get the Qt QApplication arguments based on an argparse namespace. Args: @@ -180,7 +178,7 @@ def qt_args(namespace: argparse.Namespace) -> typing.List[str]: return argv -def _qtwebengine_args() -> typing.Iterator[str]: +def _qtwebengine_args(): """Get the QtWebEngine arguments to use based on the config.""" if not qtutils.version_check('5.11', compiled=False): # WORKAROUND equivalent to @@ -226,7 +224,7 @@ def _qtwebengine_args() -> typing.Iterator[str]: 'never': '--no-referrers', 'same-domain': '--reduced-referrer-granularity', } - } # type: typing.Dict[str, typing.Dict[typing.Any, typing.Optional[str]]] + } if not qtutils.version_check('5.11'): # On Qt 5.11, we can control this via QWebEngineSettings diff --git a/qutebrowser/config/configutils.py b/qutebrowser/config/configutils.py index 9d4dc94ef..96fc0f02d 100644 --- a/qutebrowser/config/configutils.py +++ b/qutebrowser/config/configutils.py @@ -21,19 +21,11 @@ """Utilities and data structures used by various config code.""" -import typing - import attr -from PyQt5.QtCore import QUrl -from qutebrowser.utils import utils, urlmatch +from qutebrowser.utils import utils from qutebrowser.config import configexc -MYPY = False -if MYPY: # pragma: no cover - # pylint: disable=unused-import,useless-suppression - from qutebrowser.config import configdata - class _UnsetObject: @@ -41,7 +33,7 @@ class _UnsetObject: __slots__ = () - def __repr__(self) -> str: + def __repr__(self): return '' @@ -58,8 +50,8 @@ class ScopedValue: pattern: The UrlPattern for the value, or None for global values. """ - value = attr.ib() # type: typing.Any - pattern = attr.ib() # type: typing.Optional[urlmatch.UrlPattern] + value = attr.ib() + pattern = attr.ib() class Values: @@ -81,17 +73,15 @@ class Values: opt: The Option being customized. """ - def __init__(self, - opt: 'configdata.Option', - values: typing.MutableSequence = None) -> None: + def __init__(self, opt, values=None): self.opt = opt self._values = values or [] - def __repr__(self) -> str: + def __repr__(self): return utils.get_repr(self, opt=self.opt, values=self._values, constructor=True) - def __str__(self) -> str: + def __str__(self): """Get the values as human-readable string.""" if not self: return '{}: '.format(self.opt.name) @@ -106,7 +96,7 @@ class Values: scoped.pattern, self.opt.name, str_value)) return '\n'.join(lines) - def __iter__(self) -> typing.Iterator['ScopedValue']: + def __iter__(self): """Yield ScopedValue elements. This yields in "normal" order, i.e. global and then first-set settings @@ -114,25 +104,23 @@ class Values: """ yield from self._values - def __bool__(self) -> bool: + def __bool__(self): """Check whether this value is customized.""" return bool(self._values) - def _check_pattern_support( - self, arg: typing.Optional[urlmatch.UrlPattern]) -> None: + def _check_pattern_support(self, arg): """Make sure patterns are supported if one was given.""" if arg is not None and not self.opt.supports_pattern: raise configexc.NoPatternError(self.opt.name) - def add(self, value: typing.Any, - pattern: urlmatch.UrlPattern = None) -> None: + def add(self, value, pattern=None): """Add a value with the given pattern to the list of values.""" self._check_pattern_support(pattern) self.remove(pattern) scoped = ScopedValue(value, pattern) self._values.append(scoped) - def remove(self, pattern: urlmatch.UrlPattern = None) -> bool: + def remove(self, pattern=None): """Remove the value with the given pattern. If a matching pattern was removed, True is returned. @@ -143,11 +131,11 @@ class Values: self._values = [v for v in self._values if v.pattern != pattern] return old_len != len(self._values) - def clear(self) -> None: + def clear(self): """Clear all customization for this value.""" self._values = [] - def _get_fallback(self, fallback: typing.Any) -> typing.Any: + def _get_fallback(self, fallback): """Get the fallback global/default value.""" for scoped in self._values: if scoped.pattern is None: @@ -158,8 +146,7 @@ class Values: else: return UNSET - def get_for_url(self, url: QUrl = None, *, - fallback: bool = True) -> typing.Any: + def get_for_url(self, url=None, *, fallback=True): """Get a config value, falling back when needed. This first tries to find a value matching the URL (if given). @@ -178,9 +165,7 @@ class Values: return self._get_fallback(fallback) - def get_for_pattern(self, - pattern: typing.Optional[urlmatch.UrlPattern], *, - fallback: bool = True) -> typing.Any: + def get_for_pattern(self, pattern, *, fallback=True): """Get a value only if it's been overridden for the given pattern. This is useful when showing values to the user.