From 81d67f8a2c618a3cf84ec70703c5379f20a91217 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 14 Nov 2016 08:31:06 +0100 Subject: [PATCH] Remove support for an empty data/config/cachedir See #2115 --- doc/qutebrowser.1.asciidoc | 6 +- qutebrowser/browser/adblock.py | 21 ++----- qutebrowser/browser/history.py | 8 --- qutebrowser/browser/urlmarks.py | 13 +--- qutebrowser/browser/webkit/cache.py | 16 +---- qutebrowser/browser/webkit/webkitsettings.py | 17 +++--- qutebrowser/commands/userscripts.py | 14 ++--- qutebrowser/config/config.py | 59 ++++++++---------- qutebrowser/config/configtypes.py | 20 +----- qutebrowser/config/parsers/ini.py | 7 +-- qutebrowser/config/parsers/keyconf.py | 10 +-- qutebrowser/misc/crashsignal.py | 10 +-- qutebrowser/misc/lineparser.py | 9 +-- qutebrowser/misc/sessions.py | 23 ++----- qutebrowser/qutebrowser.py | 16 +++-- qutebrowser/utils/standarddir.py | 32 +++++----- tests/end2end/test_invocations.py | 18 ------ tests/unit/browser/test_adblock.py | 27 --------- tests/unit/browser/webkit/test_cache.py | 10 --- tests/unit/browser/webkit/test_history.py | 7 --- tests/unit/config/test_config.py | 64 +++----------------- tests/unit/config/test_configtypes.py | 16 +---- tests/unit/misc/test_lineparser.py | 26 -------- tests/unit/misc/test_sessions.py | 31 +--------- tests/unit/utils/test_standarddir.py | 22 ++----- 25 files changed, 110 insertions(+), 392 deletions(-) diff --git a/doc/qutebrowser.1.asciidoc b/doc/qutebrowser.1.asciidoc index c0d2b577a..8b856ccb3 100644 --- a/doc/qutebrowser.1.asciidoc +++ b/doc/qutebrowser.1.asciidoc @@ -39,13 +39,13 @@ show it. show this help message and exit *-c* 'CONFDIR', *--confdir* 'CONFDIR':: - Set config directory (empty for no config storage). + Set config directory *--datadir* 'DATADIR':: - Set data directory (empty for no data storage). + Set data directory *--cachedir* 'CACHEDIR':: - Set cache directory (empty for no cache storage). + Set cache directory *--basedir* 'BASEDIR':: Base directory for all storage. Other --*dir arguments are ignored if this is given. diff --git a/qutebrowser/browser/adblock.py b/qutebrowser/browser/adblock.py index 84d630ab6..06d0cabe8 100644 --- a/qutebrowser/browser/adblock.py +++ b/qutebrowser/browser/adblock.py @@ -29,7 +29,7 @@ import fnmatch from qutebrowser.browser import downloads from qutebrowser.config import config from qutebrowser.utils import objreg, standarddir, log, message -from qutebrowser.commands import cmdutils, cmdexc +from qutebrowser.commands import cmdutils def guess_zip_filename(zf): @@ -113,17 +113,11 @@ class HostBlocker: self._done_count = 0 data_dir = standarddir.data() - if data_dir is None: - self._local_hosts_file = None - else: - self._local_hosts_file = os.path.join(data_dir, 'blocked-hosts') + self._local_hosts_file = os.path.join(data_dir, 'blocked-hosts') self.on_config_changed() config_dir = standarddir.config() - if config_dir is None: - self._config_hosts_file = None - else: - self._config_hosts_file = os.path.join(config_dir, 'blocked-hosts') + self._config_hosts_file = os.path.join(config_dir, 'blocked-hosts') objreg.get('config').changed.connect(self.on_config_changed) @@ -146,7 +140,7 @@ class HostBlocker: Return: True if a read was attempted, False otherwise """ - if filename is None or not os.path.exists(filename): + if not os.path.exists(filename): return False try: @@ -162,9 +156,6 @@ class HostBlocker: """Read hosts from the existing blocked-hosts file.""" self._blocked_hosts = set() - if self._local_hosts_file is None: - return - self._read_hosts_file(self._config_hosts_file, self._config_blocked_hosts) @@ -186,8 +177,6 @@ class HostBlocker: """ self._read_hosts_file(self._config_hosts_file, self._config_blocked_hosts) - if self._local_hosts_file is None: - raise cmdexc.CommandError("No data storage is configured!") self._blocked_hosts = set() self._done_count = 0 urls = config.get('content', 'host-block-lists') @@ -275,7 +264,7 @@ class HostBlocker: def on_config_changed(self): """Update files when the config changed.""" urls = config.get('content', 'host-block-lists') - if urls is None and self._local_hosts_file is not None: + if urls is None: try: os.remove(self._local_hosts_file) except FileNotFoundError: diff --git a/qutebrowser/browser/history.py b/qutebrowser/browser/history.py index 4e2e126f6..c9008548a 100644 --- a/qutebrowser/browser/history.py +++ b/qutebrowser/browser/history.py @@ -129,7 +129,6 @@ class WebHistory(QObject): Attributes: history_dict: An OrderedDict of URLs read from the on-disk history. - _hist_dir: The directory to store the history in _lineparser: The AppendLineParser used to save the history. _new_history: A list of Entry items of the current session. _saved_count: How many HistoryEntries have been written to disk. @@ -157,7 +156,6 @@ class WebHistory(QObject): super().__init__(parent) self._initial_read_started = False self._initial_read_done = False - self._hist_dir = hist_dir self._lineparser = lineparser.AppendLineParser(hist_dir, hist_name, parent=self) self.history_dict = collections.OrderedDict() @@ -183,12 +181,6 @@ class WebHistory(QObject): return self._initial_read_started = True - if self._hist_dir is None: - self._initial_read_done = True - self.async_read_done.emit() - assert not self._temp_history - return - with self._lineparser.open(): for line in self._lineparser: yield diff --git a/qutebrowser/browser/urlmarks.py b/qutebrowser/browser/urlmarks.py index fc727a284..991ba7fc5 100644 --- a/qutebrowser/browser/urlmarks.py +++ b/qutebrowser/browser/urlmarks.py @@ -73,8 +73,7 @@ class UrlMarkManager(QObject): Attributes: marks: An OrderedDict of all quickmarks/bookmarks. - _lineparser: The LineParser used for the marks, or None - (when qutebrowser is started with -c ''). + _lineparser: The LineParser used for the marks Signals: changed: Emitted when anything changed. @@ -91,10 +90,6 @@ class UrlMarkManager(QObject): super().__init__(parent) self.marks = collections.OrderedDict() - self._lineparser = None - - if standarddir.config() is None: - return self._init_lineparser() for line in self._lineparser: @@ -115,10 +110,8 @@ class UrlMarkManager(QObject): def save(self): """Save the marks to disk.""" - if self._lineparser is not None: - self._lineparser.data = [' '.join(tpl) - for tpl in self.marks.items()] - self._lineparser.save() + self._lineparser.data = [' '.join(tpl) for tpl in self.marks.items()] + self._lineparser.save() def delete(self, key): """Delete a quickmark/bookmark. diff --git a/qutebrowser/browser/webkit/cache.py b/qutebrowser/browser/webkit/cache.py index 1270498e4..bc774c250 100644 --- a/qutebrowser/browser/webkit/cache.py +++ b/qutebrowser/browser/webkit/cache.py @@ -32,23 +32,14 @@ class DiskCache(QNetworkDiskCache): """Disk cache which sets correct cache dir and size. - If the cache is deactivated via the command line argument --cachedir="", - both attributes _cache_dir and _http_cache_dir are set to None. - Attributes: _activated: Whether the cache should be used. - _cache_dir: The base directory for cache files (standarddir.cache()) or - None. - _http_cache_dir: the HTTP subfolder in _cache_dir or None. + _cache_dir: The base directory for cache files (standarddir.cache()) """ def __init__(self, cache_dir, parent=None): super().__init__(parent) self._cache_dir = cache_dir - if cache_dir is None: - self._http_cache_dir = None - else: - self._http_cache_dir = os.path.join(cache_dir, 'http') self._maybe_activate() objreg.get('config').changed.connect(self.on_config_changed) @@ -59,12 +50,11 @@ class DiskCache(QNetworkDiskCache): def _maybe_activate(self): """Activate/deactivate the cache based on the config.""" - if (config.get('general', 'private-browsing') or - self._cache_dir is None): + if config.get('general', 'private-browsing'): self._activated = False else: self._activated = True - self.setCacheDirectory(self._http_cache_dir) + self.setCacheDirectory(os.path.join(self._cache_dir, 'http')) self.setMaximumCacheSize(config.get('storage', 'cache-size')) @pyqtSlot(str, str) diff --git a/qutebrowser/browser/webkit/webkitsettings.py b/qutebrowser/browser/webkit/webkitsettings.py index ffb394872..86505162f 100644 --- a/qutebrowser/browser/webkit/webkitsettings.py +++ b/qutebrowser/browser/webkit/webkitsettings.py @@ -95,18 +95,17 @@ def init(): """Initialize the global QWebSettings.""" cache_path = standarddir.cache() data_path = standarddir.data() - if config.get('general', 'private-browsing') or cache_path is None: + if config.get('general', 'private-browsing'): QWebSettings.setIconDatabasePath('') else: QWebSettings.setIconDatabasePath(cache_path) - if cache_path is not None: - QWebSettings.setOfflineWebApplicationCachePath( - os.path.join(cache_path, 'application-cache')) - if data_path is not None: - QWebSettings.globalSettings().setLocalStoragePath( - os.path.join(data_path, 'local-storage')) - QWebSettings.setOfflineStoragePath( - os.path.join(data_path, 'offline-storage')) + + QWebSettings.setOfflineWebApplicationCachePath( + os.path.join(cache_path, 'application-cache')) + QWebSettings.globalSettings().setLocalStoragePath( + os.path.join(data_path, 'local-storage')) + QWebSettings.setOfflineStoragePath( + os.path.join(data_path, 'offline-storage')) websettings.init_mappings(MAPPINGS) objreg.get('config').changed.connect(update_settings) diff --git a/qutebrowser/commands/userscripts.py b/qutebrowser/commands/userscripts.py index d939d6928..3c1d4d89e 100644 --- a/qutebrowser/commands/userscripts.py +++ b/qutebrowser/commands/userscripts.py @@ -408,15 +408,11 @@ def run_async(tab, cmd, *args, win_id, env, verbose=False): user_agent = config.get('network', 'user-agent') if user_agent is not None: env['QUTE_USER_AGENT'] = user_agent - config_dir = standarddir.config() - if config_dir is not None: - env['QUTE_CONFIG_DIR'] = config_dir - data_dir = standarddir.data() - if data_dir is not None: - env['QUTE_DATA_DIR'] = data_dir - download_dir = downloads.download_dir() - if download_dir is not None: - env['QUTE_DOWNLOAD_DIR'] = download_dir + + env['QUTE_CONFIG_DIR'] = standarddir.config() + env['QUTE_DATA_DIR'] = standarddir.data() + env['QUTE_DOWNLOAD_DIR'] = downloads.download_dir() + cmd_path = os.path.expanduser(cmd) # if cmd is not given as an absolute path, look it up diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 2cfea1510..38d8aa6eb 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -160,19 +160,18 @@ def _init_main_config(parent=None): sys.exit(usertypes.Exit.err_config) else: objreg.register('config', config_obj) - if standarddir.config() is not None: - filename = os.path.join(standarddir.config(), 'qutebrowser.conf') - save_manager = objreg.get('save-manager') - save_manager.add_saveable( - 'config', config_obj.save, config_obj.changed, - config_opt=('general', 'auto-save-config'), filename=filename) - for sect in config_obj.sections.values(): - for opt in sect.values.values(): - if opt.values['conf'] is None: - # Option added to built-in defaults but not in user's - # config yet - save_manager.save('config', explicit=True, force=True) - return + filename = os.path.join(standarddir.config(), 'qutebrowser.conf') + save_manager = objreg.get('save-manager') + save_manager.add_saveable( + 'config', config_obj.save, config_obj.changed, + config_opt=('general', 'auto-save-config'), filename=filename) + for sect in config_obj.sections.values(): + for opt in sect.values.values(): + if opt.values['conf'] is None: + # Option added to built-in defaults but not in user's + # config yet + save_manager.save('config', explicit=True, force=True) + return def _init_key_config(parent): @@ -197,13 +196,12 @@ def _init_key_config(parent): sys.exit(usertypes.Exit.err_key_config) else: objreg.register('key-config', key_config) - if standarddir.config() is not None: - save_manager = objreg.get('save-manager') - filename = os.path.join(standarddir.config(), 'keys.conf') - save_manager.add_saveable( - 'key-config', key_config.save, key_config.config_dirty, - config_opt=('general', 'auto-save-config'), filename=filename, - dirty=key_config.is_dirty) + save_manager = objreg.get('save-manager') + filename = os.path.join(standarddir.config(), 'keys.conf') + save_manager.add_saveable( + 'key-config', key_config.save, key_config.config_dirty, + config_opt=('general', 'auto-save-config'), filename=filename, + dirty=key_config.is_dirty) def _init_misc(): @@ -237,10 +235,7 @@ def _init_misc(): # This fixes one of the corruption issues here: # https://github.com/The-Compiler/qutebrowser/issues/515 - if standarddir.config() is None: - path = os.devnull - else: - path = os.path.join(standarddir.config(), 'qsettings') + path = os.path.join(standarddir.config(), 'qsettings') for fmt in [QSettings.NativeFormat, QSettings.IniFormat]: QSettings.setPath(fmt, QSettings.UserScope, path) @@ -659,15 +654,11 @@ class ConfigManager(QObject): def read(self, configdir, fname, relaxed=False): """Read the config from the given directory/file.""" self._fname = fname - if configdir is None: - self._configdir = None - self._initialized = True - else: - self._configdir = configdir - parser = ini.ReadConfigParser(configdir, fname) - self._from_cp(parser, relaxed) - self._initialized = True - self._validate_all() + self._configdir = configdir + parser = ini.ReadConfigParser(configdir, fname) + self._from_cp(parser, relaxed) + self._initialized = True + self._validate_all() def items(self, sectname, raw=True): """Get a list of (optname, value) tuples for a section. @@ -884,8 +875,6 @@ class ConfigManager(QObject): def save(self): """Save the config file.""" - if self._configdir is None: - return configfile = os.path.join(self._configdir, self._fname) log.destroy.debug("Saving config to {}".format(configfile)) with qtutils.savefile_open(configfile) as f: diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 346b5a8d7..0642b79e8 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -859,9 +859,7 @@ class File(BaseType): value = os.path.expanduser(value) value = os.path.expandvars(value) if not os.path.isabs(value): - cfgdir = standarddir.config() - assert cfgdir is not None - value = os.path.join(cfgdir, value) + value = os.path.join(standarddir.config(), value) return value def validate(self, value): @@ -872,12 +870,7 @@ class File(BaseType): value = os.path.expandvars(value) try: if not os.path.isabs(value): - cfgdir = standarddir.config() - if cfgdir is None: - raise configexc.ValidationError( - value, "must be an absolute path when not using a " - "config directory!") - value = os.path.join(cfgdir, value) + value = os.path.join(standarddir.config(), value) not_isfile_message = ("must be a valid path relative to the " "config directory!") else: @@ -1180,14 +1173,7 @@ class UserStyleSheet(File): if not value: return None - if standarddir.config() is None: - # We can't call super().transform() here as this counts on the - # validation previously ensuring that we don't have a relative path - # when starting with -c "". - path = None - else: - path = super().transform(value) - + path = super().transform(value) if path is not None and os.path.exists(path): return QUrl.fromLocalFile(path) else: diff --git a/qutebrowser/config/parsers/ini.py b/qutebrowser/config/parsers/ini.py index 90ca27c50..56640e299 100644 --- a/qutebrowser/config/parsers/ini.py +++ b/qutebrowser/config/parsers/ini.py @@ -47,15 +47,12 @@ class ReadConfigParser(configparser.ConfigParser): self.optionxform = lambda opt: opt # be case-insensitive self._configdir = configdir self._fname = fname - if self._configdir is None: - self._configfile = None - return self._configfile = os.path.join(self._configdir, fname) + if not os.path.isfile(self._configfile): return log.init.debug("Reading config from {}".format(self._configfile)) - if self._configfile is not None: - self.read(self._configfile, encoding='utf-8') + self.read(self._configfile, encoding='utf-8') def __repr__(self): return utils.get_repr(self, constructor=True, diff --git a/qutebrowser/config/parsers/keyconf.py b/qutebrowser/config/parsers/keyconf.py index aa1600ae1..e602c33d5 100644 --- a/qutebrowser/config/parsers/keyconf.py +++ b/qutebrowser/config/parsers/keyconf.py @@ -89,11 +89,9 @@ class KeyConfigParser(QObject): self._cur_command = None # Mapping of section name(s) to key binding -> command dicts. self.keybindings = collections.OrderedDict() - if configdir is None: - self._configfile = None - else: - self._configfile = os.path.join(configdir, fname) - if self._configfile is None or not os.path.exists(self._configfile): + self._configfile = os.path.join(configdir, fname) + + if not os.path.exists(self._configfile): self._load_default() else: self._read(relaxed) @@ -143,8 +141,6 @@ class KeyConfigParser(QObject): def save(self): """Save the key config file.""" - if self._configfile is None: - return log.destroy.debug("Saving key config to {}".format(self._configfile)) with qtutils.savefile_open(self._configfile, encoding='utf-8') as f: data = str(self) diff --git a/qutebrowser/misc/crashsignal.py b/qutebrowser/misc/crashsignal.py index b970e467b..35c39bf2e 100644 --- a/qutebrowser/misc/crashsignal.py +++ b/qutebrowser/misc/crashsignal.py @@ -72,10 +72,7 @@ class CrashHandler(QObject): def handle_segfault(self): """Handle a segfault from a previous run.""" - data_dir = standarddir.data() - if data_dir is None: - return - logname = os.path.join(data_dir, 'crash.log') + logname = os.path.join(standarddir.data(), 'crash.log') try: # First check if an old logfile exists. if os.path.exists(logname): @@ -131,10 +128,7 @@ class CrashHandler(QObject): def _init_crashlogfile(self): """Start a new logfile and redirect faulthandler to it.""" assert not self._args.no_err_windows - data_dir = standarddir.data() - if data_dir is None: - return - logname = os.path.join(data_dir, 'crash.log') + logname = os.path.join(standarddir.data(), 'crash.log') try: self._crash_log_file = open(logname, 'w', encoding='ascii') except OSError: diff --git a/qutebrowser/misc/lineparser.py b/qutebrowser/misc/lineparser.py index 4999c2e22..55bae7142 100644 --- a/qutebrowser/misc/lineparser.py +++ b/qutebrowser/misc/lineparser.py @@ -57,10 +57,7 @@ class BaseLineParser(QObject): """ super().__init__(parent) self._configdir = configdir - if self._configdir is None: - self._configfile = None - else: - self._configfile = os.path.join(self._configdir, fname) + self._configfile = os.path.join(self._configdir, fname) self._fname = fname self._binary = binary self._opened = False @@ -76,8 +73,6 @@ class BaseLineParser(QObject): Return: True if the file should be saved, False otherwise. """ - if self._configdir is None: - return False if not os.path.exists(self._configdir): os.makedirs(self._configdir, 0o755) return True @@ -222,7 +217,7 @@ class LineParser(BaseLineParser): binary: Whether to open the file in binary mode. """ super().__init__(configdir, fname, binary=binary, parent=parent) - if configdir is None or not os.path.isfile(self._configfile): + if not os.path.isfile(self._configfile): self.data = [] else: log.init.debug("Reading {}".format(self._configfile)) diff --git a/qutebrowser/misc/sessions.py b/qutebrowser/misc/sessions.py index c3a3a8e34..9a544c738 100644 --- a/qutebrowser/misc/sessions.py +++ b/qutebrowser/misc/sessions.py @@ -47,15 +47,11 @@ def init(parent=None): Args: parent: The parent to use for the SessionManager. """ - data_dir = standarddir.data() - if data_dir is None: - base_path = None - else: - base_path = os.path.join(standarddir.data(), 'sessions') - try: - os.mkdir(base_path) - except FileExistsError: - pass + base_path = os.path.join(standarddir.data(), 'sessions') + try: + os.mkdir(base_path) + except FileExistsError: + pass session_manager = SessionManager(base_path, parent) objreg.register('session-manager', session_manager) @@ -137,11 +133,6 @@ class SessionManager(QObject): if os.path.isabs(path) and ((not check_exists) or os.path.exists(path)): return path - elif self._base_path is None: - if check_exists: - raise SessionNotFoundError(name) - else: - return None else: path = os.path.join(self._base_path, name + '.yml') if check_exists and not os.path.exists(path): @@ -279,8 +270,6 @@ class SessionManager(QObject): """ name = self._get_session_name(name) path = self._get_session_path(name) - if path is None: - raise SessionError("No data storage configured.") log.sessions.debug("Saving session {} to {}...".format(name, path)) if last_window: @@ -392,8 +381,6 @@ class SessionManager(QObject): def list_sessions(self): """Get a list of all session names.""" sessions = [] - if self._base_path is None: - return sessions for filename in os.listdir(self._base_path): base, ext = os.path.splitext(filename) if ext == '.yml': diff --git a/qutebrowser/qutebrowser.py b/qutebrowser/qutebrowser.py index 5a6d7e259..de80b972b 100644 --- a/qutebrowser/qutebrowser.py +++ b/qutebrowser/qutebrowser.py @@ -47,12 +47,11 @@ def get_argparser(): """Get the argparse parser.""" parser = argparse.ArgumentParser(prog='qutebrowser', description=qutebrowser.__description__) - parser.add_argument('-c', '--confdir', help="Set config directory (empty " - "for no config storage).") - parser.add_argument('--datadir', help="Set data directory (empty for " - "no data storage).") - parser.add_argument('--cachedir', help="Set cache directory (empty for " - "no cache storage).") + parser.add_argument('-c', '--confdir', help="Set config directory", + type=directory) + parser.add_argument('--datadir', help="Set data directory", type=directory) + parser.add_argument('--cachedir', help="Set cache directory", + type=directory) parser.add_argument('--basedir', help="Base directory for all storage. " "Other --*dir arguments are ignored if this is given.") parser.add_argument('-V', '--version', help="Show version and quit.", @@ -124,6 +123,11 @@ def get_argparser(): return parser +def directory(arg): + if not arg: + raise argparse.ArgumentTypeError("Invalid empty value") + + def logfilter_error(logfilter: str): """Validate logger names passed to --logfilter. diff --git a/qutebrowser/utils/standarddir.py b/qutebrowser/utils/standarddir.py index 10929f251..cbfa2555c 100644 --- a/qutebrowser/utils/standarddir.py +++ b/qutebrowser/utils/standarddir.py @@ -43,7 +43,7 @@ def config(): # WORKAROUND - see # https://bugreports.qt.io/browse/QTBUG-38872 path = os.path.join(path, appname) - _maybe_create(path) + _create(path) return path @@ -61,7 +61,7 @@ def data(): QStandardPaths.ConfigLocation) if data_path == config_path: path = os.path.join(path, 'data') - _maybe_create(path) + _create(path) return path @@ -82,7 +82,7 @@ def cache(): overridden, path = _from_args(typ, _args) if not overridden: path = _writable_location(typ) - _maybe_create(path) + _create(path) return path @@ -92,7 +92,7 @@ def download(): overridden, path = _from_args(typ, _args) if not overridden: path = _writable_location(typ) - _maybe_create(path) + _create(path) return path @@ -116,7 +116,7 @@ def runtime(): # maximum length of 104 chars), so we don't add the username here... appname = QCoreApplication.instance().applicationName() path = os.path.join(path, appname) - _maybe_create(path) + _create(path) return path @@ -175,16 +175,16 @@ def _from_args(typ, args): except KeyError: return (False, None) arg_value = getattr(args, argname) + + assert arg_value != '', argname if arg_value is None: return (False, None) - elif arg_value == '': - return (True, None) else: return (True, arg_value) -def _maybe_create(path): - """Create the `path` directory if path is not None. +def _create(path): + """Create the `path` directory. From the XDG basedir spec: If, when attempting to write a file, the destination directory is @@ -192,11 +192,10 @@ def _maybe_create(path): 0700. If the destination directory exists already the permissions should not be changed. """ - if path is not None: - try: - os.makedirs(path, 0o700) - except FileExistsError: - pass + try: + os.makedirs(path, 0o700) + except FileExistsError: + pass def init(args): @@ -214,10 +213,7 @@ def _init_cachedir_tag(): See http://www.brynosaurus.com/cachedir/spec.html """ - cache_dir = cache() - if cache_dir is None: - return - cachedir_tag = os.path.join(cache_dir, 'CACHEDIR.TAG') + cachedir_tag = os.path.join(cache(), 'CACHEDIR.TAG') if not os.path.exists(cachedir_tag): try: with open(cachedir_tag, 'w', encoding='utf-8') as f: diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py index fd414db12..d85e2a467 100644 --- a/tests/end2end/test_invocations.py +++ b/tests/end2end/test_invocations.py @@ -68,24 +68,6 @@ def temp_basedir_env(tmpdir, short_tmpdir): return env -@pytest.mark.linux -def test_no_config(request, temp_basedir_env, quteproc_new): - """Test starting with -c "".""" - args = ['-c', ''] + _base_args(request.config) - quteproc_new.start(args, env=temp_basedir_env) - quteproc_new.send_cmd(':quit') - quteproc_new.wait_for_quit() - - -@pytest.mark.linux -def test_no_cache(request, temp_basedir_env, quteproc_new): - """Test starting with --cachedir="".""" - args = ['--cachedir='] + _base_args(request.config) - quteproc_new.start(args, env=temp_basedir_env) - quteproc_new.send_cmd(':quit') - quteproc_new.wait_for_quit() - - @pytest.mark.linux def test_ascii_locale(request, httpbin, tmpdir, quteproc_new): """Test downloads with LC_ALL=C set. diff --git a/tests/unit/browser/test_adblock.py b/tests/unit/browser/test_adblock.py index b0285a8f5..3caf6e526 100644 --- a/tests/unit/browser/test_adblock.py +++ b/tests/unit/browser/test_adblock.py @@ -29,7 +29,6 @@ from PyQt5.QtCore import pyqtSignal, QUrl, QObject from qutebrowser.browser import adblock from qutebrowser.utils import objreg -from qutebrowser.commands import cmdexc pytestmark = pytest.mark.usefixtures('qapp', 'config_tmpdir') @@ -225,32 +224,6 @@ def generic_blocklists(directory): return [blocklist1, blocklist2, blocklist3, blocklist4, blocklist5] -def test_without_datadir(config_stub, tmpdir, monkeypatch, win_registry): - """No directory for data configured so no hosts file exists. - - Ensure CommandError is raised and no URL is blocked. - """ - config_stub.data = { - 'content': { - 'host-block-lists': generic_blocklists(tmpdir), - 'host-blocking-enabled': True, - } - } - monkeypatch.setattr('qutebrowser.utils.standarddir.data', lambda: None) - host_blocker = adblock.HostBlocker() - - with pytest.raises(cmdexc.CommandError) as excinfo: - host_blocker.adblock_update() - assert str(excinfo.value) == "No data storage is configured!" - - host_blocker.read_hosts() - for str_url in URLS_TO_CHECK: - assert not host_blocker.is_blocked(QUrl(str_url)) - - # To test on_config_changed - config_stub.set('content', 'host-block-lists', None) - - def test_disabled_blocking_update(basedir, config_stub, download_stub, data_tmpdir, tmpdir, win_registry, caplog): """Ensure no URL is blocked when host blocking is disabled.""" diff --git a/tests/unit/browser/webkit/test_cache.py b/tests/unit/browser/webkit/test_cache.py index 1d9b8a684..c716b9b82 100644 --- a/tests/unit/browser/webkit/test_cache.py +++ b/tests/unit/browser/webkit/test_cache.py @@ -111,16 +111,6 @@ def test_cache_size_deactivated(config_stub, tmpdir): assert disk_cache.cacheSize() == 0 -def test_cache_no_cache_dir(config_stub): - """Confirm that the cache is deactivated when cache_dir is None.""" - config_stub.data = { - 'storage': {'cache-size': 1024}, - 'general': {'private-browsing': False}, - } - disk_cache = cache.DiskCache(None) - assert disk_cache.cacheSize() == 0 - - def test_cache_existing_metadata_file(config_stub, tmpdir): """Test querying existing meta data file from activated cache.""" config_stub.data = { diff --git a/tests/unit/browser/webkit/test_history.py b/tests/unit/browser/webkit/test_history.py index c99adbb5a..7b2b6f53a 100644 --- a/tests/unit/browser/webkit/test_history.py +++ b/tests/unit/browser/webkit/test_history.py @@ -65,13 +65,6 @@ def test_async_read_twice(monkeypatch, qtbot, tmpdir, caplog): assert caplog.records[0].msg == expected -def test_async_read_no_datadir(qtbot, config_stub, fake_save_manager): - config_stub.data = {'general': {'private-browsing': False}} - hist = history.WebHistory(hist_dir=None, hist_name='history') - with qtbot.waitSignal(hist.async_read_done): - list(hist.async_read()) - - @pytest.mark.parametrize('redirect', [True, False]) def test_adding_item_during_async_read(qtbot, hist, redirect): """Check what happens when adding URL while reading the history.""" diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py index 1253b6a0a..3b6f21f7d 100644 --- a/tests/unit/config/test_config.py +++ b/tests/unit/config/test_config.py @@ -23,9 +23,7 @@ import os.path import configparser import collections import shutil -from unittest import mock -from PyQt5.QtCore import QObject from PyQt5.QtGui import QColor import pytest @@ -33,7 +31,6 @@ import qutebrowser from qutebrowser.config import config, configexc, configdata from qutebrowser.config.parsers import keyconf from qutebrowser.commands import runners -from qutebrowser.utils import objreg, standarddir class TestConfigParser: @@ -43,12 +40,12 @@ class TestConfigParser: Objects = collections.namedtuple('Objects', ['cp', 'cfg']) @pytest.fixture - def objects(self): + def objects(self, tmpdir): cp = configparser.ConfigParser(interpolation=None, comment_prefixes='#') cp.optionxform = lambda opt: opt # be case-insensitive cfg = config.ConfigManager() - cfg.read(None, None) + cfg.read(str(tmpdir), 'qutebrowser.conf') return self.Objects(cp=cp, cfg=cfg) @pytest.mark.parametrize('config, section, option, value', [ @@ -247,7 +244,7 @@ class TestKeyConfigParser: """Test config.parsers.keyconf.KeyConfigParser.""" - def test_cmd_binding(self, cmdline_test, config_stub): + def test_cmd_binding(self, cmdline_test, config_stub, tmpdir): """Test various command bindings. See https://github.com/The-Compiler/qutebrowser/issues/615 @@ -256,7 +253,7 @@ class TestKeyConfigParser: cmdline_test: A pytest fixture which provides testcases. """ config_stub.data = {'aliases': []} - kcp = keyconf.KeyConfigParser(None, None) + kcp = keyconf.KeyConfigParser(str(tmpdir), 'keys.conf') kcp._cur_section = 'normal' if cmdline_test.valid: kcp._read_command(cmdline_test.cmd) @@ -379,17 +376,17 @@ class TestDefaultConfig: """Test validating of the default config.""" @pytest.mark.usefixtures('qapp') - def test_default_config(self): + def test_default_config(self, tmpdir): """Test validating of the default config.""" conf = config.ConfigManager() - conf.read(None, None) + conf.read(str(tmpdir), 'qutebrowser.conf') conf._validate_all() - def test_default_key_config(self): + def test_default_key_config(self, tmpdir): """Test validating of the default key config.""" # We import qutebrowser.app so the cmdutils.register decorators run. import qutebrowser.app # pylint: disable=unused-variable - conf = keyconf.KeyConfigParser(None, None) + conf = keyconf.KeyConfigParser(str(tmpdir), 'keys.conf') runner = runners.CommandRunner(win_id=0) for sectname in configdata.KEY_DATA: for cmd in conf.get_bindings_for(sectname).values(): @@ -418,48 +415,3 @@ class TestDefaultConfig: shutil.copy(full_path, str(tmpdir / 'qutebrowser.conf')) conf = config.ConfigManager() conf.read(str(tmpdir), 'qutebrowser.conf') - - -@pytest.mark.integration -class TestConfigInit: - - """Test initializing of the config.""" - - @pytest.fixture(autouse=True) - def patch(self, fake_args): - objreg.register('app', QObject()) - objreg.register('save-manager', mock.MagicMock()) - fake_args.relaxed_config = False - old_standarddir_args = standarddir._args - yield - objreg.delete('app') - objreg.delete('save-manager') - # registered by config.init() - objreg.delete('config') - objreg.delete('key-config') - objreg.delete('state-config') - standarddir._args = old_standarddir_args - - @pytest.fixture - def env(self, tmpdir): - conf_path = (tmpdir / 'config').ensure(dir=1) - data_path = (tmpdir / 'data').ensure(dir=1) - cache_path = (tmpdir / 'cache').ensure(dir=1) - env = { - 'XDG_CONFIG_HOME': str(conf_path), - 'XDG_DATA_HOME': str(data_path), - 'XDG_CACHE_HOME': str(cache_path), - } - return env - - def test_config_none(self, monkeypatch, env, fake_args): - """Test initializing with config path set to None.""" - fake_args.confdir = '' - fake_args.datadir = '' - fake_args.cachedir = '' - fake_args.basedir = None - for k, v in env.items(): - monkeypatch.setenv(k, v) - standarddir.init(fake_args) - config.init() - assert not os.listdir(env['XDG_CONFIG_HOME']) diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index 3a87ac999..2133cedd0 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -1284,14 +1284,6 @@ class TestFileAndUserStyleSheet: os_mock.path.join.assert_called_once_with( '/home/foo/.config/', 'foobar') - def test_validate_rel_config_none_file(self, os_mock, monkeypatch): - """Test with a relative path and standarddir.config returning None.""" - monkeypatch.setattr( - 'qutebrowser.config.configtypes.standarddir.config', lambda: None) - os_mock.path.isabs.return_value = False - with pytest.raises(configexc.ValidationError): - configtypes.File().validate('foobar') - @pytest.mark.parametrize('configtype, value, raises', [ (configtypes.File(), 'foobar', True), (configtypes.UserStyleSheet(), 'foobar', False), @@ -1355,14 +1347,8 @@ class TestFileAndUserStyleSheet: expected = self._expected(klass, '/configdir/foo') assert klass().transform('foo') == expected - @pytest.mark.parametrize('no_config', [False, True]) - def test_transform_userstylesheet_base64(self, monkeypatch, no_config): + def test_transform_userstylesheet_base64(self, monkeypatch): """Test transform with a data string.""" - if no_config: - monkeypatch.setattr( - 'qutebrowser.config.configtypes.standarddir.config', - lambda: None) - b64 = base64.b64encode(b"test").decode('ascii') url = QUrl("data:text/css;charset=utf-8;base64,{}".format(b64)) assert configtypes.UserStyleSheet().transform("test") == url diff --git a/tests/unit/misc/test_lineparser.py b/tests/unit/misc/test_lineparser.py index f5fbb2f4d..546d53cf9 100644 --- a/tests/unit/misc/test_lineparser.py +++ b/tests/unit/misc/test_lineparser.py @@ -52,15 +52,6 @@ class TestBaseLineParser: lineparser._prepare_save() os_mock.makedirs.assert_called_with(self.CONFDIR, 0o755) - def test_prepare_save_no_config(self, mocker): - """Test if _prepare_save doesn't create a None config dir.""" - os_mock = mocker.patch('qutebrowser.misc.lineparser.os') - os_mock.path.exists.return_value = True - - lineparser = lineparsermod.BaseLineParser(None, self.FILENAME) - assert not lineparser._prepare_save() - assert not os_mock.makedirs.called - def test_double_open(self, mocker, lineparser): """Test if _open refuses reentry.""" mocker.patch('builtins.open', mock.mock_open()) @@ -158,15 +149,6 @@ class TestAppendLineParser: lineparser.save() assert (tmpdir / 'file').read() == self._get_expected(new_data) - def test_save_without_configdir(self, tmpdir, lineparser): - """Test save() failing because no configdir was set.""" - new_data = ['new data 1', 'new data 2'] - lineparser.new_data = new_data - lineparser._configdir = None - assert not lineparser.save() - # make sure new data is still there - assert lineparser.new_data == new_data - def test_clear(self, tmpdir, lineparser): """Check if calling clear() empties both pending and persisted data.""" lineparser.new_data = ['one', 'two'] @@ -179,14 +161,6 @@ class TestAppendLineParser: assert not lineparser.new_data assert (tmpdir / 'file').read() == "" - def test_clear_without_configdir(self, tmpdir, lineparser): - """Test clear() failing because no configdir was set.""" - new_data = ['new data 1', 'new data 2'] - lineparser.new_data = new_data - lineparser._configdir = None - assert not lineparser.clear() - assert lineparser.new_data == new_data - def test_iter_without_open(self, lineparser): """Test __iter__ without having called open().""" with pytest.raises(ValueError): diff --git a/tests/unit/misc/test_sessions.py b/tests/unit/misc/test_sessions.py index 557ed7b2f..f1810c203 100644 --- a/tests/unit/misc/test_sessions.py +++ b/tests/unit/misc/test_sessions.py @@ -40,9 +40,9 @@ webengine_refactoring_xfail = pytest.mark.xfail( @pytest.fixture -def sess_man(): - """Fixture providing a SessionManager with no session dir.""" - return sessions.SessionManager(base_path=None) +def sess_man(tmpdir): + """Fixture providing a SessionManager.""" + return sessions.SessionManager(base_path=str(tmpdir)) class TestInit: @@ -52,13 +52,6 @@ class TestInit: yield objreg.delete('session-manager') - def test_no_standarddir(self, monkeypatch): - monkeypatch.setattr('qutebrowser.misc.sessions.standarddir.data', - lambda: None) - sessions.init() - manager = objreg.get('session-manager') - assert manager._base_path is None - @pytest.mark.parametrize('create_dir', [True, False]) def test_with_standarddir(self, tmpdir, monkeypatch, create_dir): monkeypatch.setattr('qutebrowser.misc.sessions.standarddir.data', @@ -110,16 +103,6 @@ class TestExists: assert not man.exists(name) - @pytest.mark.parametrize('absolute', [True, False]) - def test_no_datadir(self, sess_man, tmpdir, absolute): - abs_session = tmpdir / 'foo.yml' - abs_session.ensure() - - if absolute: - assert sess_man.exists(str(abs_session)) - else: - assert not sess_man.exists('foo') - @webengine_refactoring_xfail class TestSaveTab: @@ -247,11 +230,6 @@ class TestSave: objreg.delete('main-window', scope='window', window=0) objreg.delete('tabbed-browser', scope='window', window=0) - def test_no_config_storage(self, sess_man): - with pytest.raises(sessions.SessionError) as excinfo: - sess_man.save('foo') - assert str(excinfo.value) == "No data storage configured." - def test_update_completion_signal(self, sess_man, tmpdir, qtbot): session_path = tmpdir / 'foo.yml' with qtbot.waitSignal(sess_man.update_completion): @@ -415,9 +393,6 @@ def test_delete_update_completion_signal(sess_man, qtbot, tmpdir): class TestListSessions: - def test_no_base_path(self, sess_man): - assert not sess_man.list_sessions() - def test_no_sessions(self, tmpdir): sess_man = sessions.SessionManager(str(tmpdir)) assert not sess_man.list_sessions() diff --git a/tests/unit/utils/test_standarddir.py b/tests/unit/utils/test_standarddir.py index a40adb748..96a121b3f 100644 --- a/tests/unit/utils/test_standarddir.py +++ b/tests/unit/utils/test_standarddir.py @@ -165,15 +165,12 @@ class TestArguments: """Tests with confdir/cachedir/datadir arguments.""" - @pytest.fixture(params=[DirArgTest('', None), DirArgTest('foo', 'foo')]) + @pytest.fixture(params=[DirArgTest('foo', 'foo')]) def testcase(self, request, tmpdir): """Fixture providing testcases.""" - if request.param.expected is None: - return request.param - else: - # prepend tmpdir to both - arg = str(tmpdir / request.param.arg) - return DirArgTest(arg, arg) + # prepend tmpdir to both + arg = str(tmpdir / request.param.arg) + return DirArgTest(arg, arg) def test_confdir(self, testcase): """Test --confdir.""" @@ -210,8 +207,8 @@ class TestArguments: monkeypatch.setattr( 'qutebrowser.utils.standarddir.QStandardPaths.writableLocation', lambda _typ: str(tmpdir)) - args = types.SimpleNamespace(confdir=None, cachedir=None, datadir=None, - basedir=None) + args = types.SimpleNamespace(confdir=None, cachedir=None, + datadir=None, basedir=None) standarddir.init(args) assert standarddir.runtime() == str(tmpdir / 'qute_test') @@ -239,13 +236,6 @@ class TestInitCacheDirTag: """Tests for _init_cachedir_tag.""" - def test_no_cache_dir(self, mocker, monkeypatch): - """Smoke test with cache() returning None.""" - monkeypatch.setattr('qutebrowser.utils.standarddir.cache', - lambda: None) - mocker.patch('builtins.open', side_effect=AssertionError) - standarddir._init_cachedir_tag() - def test_existent_cache_dir_tag(self, tmpdir, mocker, monkeypatch): """Test with an existent CACHEDIR.TAG.""" monkeypatch.setattr('qutebrowser.utils.standarddir.cache',