diff options
author | nfnty <git@nfnty.se> | 2017-01-20 16:09:19 +0100 |
---|---|---|
committer | nfnty <git@nfnty.se> | 2017-01-21 23:09:24 +0100 |
commit | 1687e0f41f172cef6923f75f4c6f1038f19671dc (patch) | |
tree | 6b9fcb40ed3637cf13a8a9be9975504aadb5e90b | |
parent | e53369588ee44a9fc4ec75228dc041448aa778d4 (diff) | |
download | ranger-1687e0f41f172cef6923f75f4c6f1038f19671dc.tar.gz |
linting: pylint: Enable `broad-except`, Improve logging
Handle exceptions explicitly to prevent unexpected errors from causing problems. Improve exception and notification logging.
43 files changed, 306 insertions, 324 deletions
diff --git a/doc/tools/print_colors.py b/doc/tools/print_colors.py index 65625cb5..762ac3e3 100755 --- a/doc/tools/print_colors.py +++ b/doc/tools/print_colors.py @@ -15,14 +15,14 @@ def main(win): for color in range(-1, curses.COLORS): try: curses.init_pair(color, color, 0) - except Exception: + except curses.error: pass else: win.addstr(str(color) + ' ', curses.color_pair(color) | attr) curses.start_color() try: curses.use_default_colors() - except Exception: + except curses.error: pass win.addstr("available colors: %d\n\n" % curses.COLORS) print_all_colors(0) diff --git a/examples/plugin_pmount.py b/examples/plugin_pmount.py index d7c88349..38c4a17c 100644 --- a/examples/plugin_pmount.py +++ b/examples/plugin_pmount.py @@ -22,22 +22,19 @@ HOOK_INIT_OLD = ranger.api.hook_init def hook_init(fm): - try: - fm.execute_console("map {key} shell -p lsblk".format(key=LIST_MOUNTS_KEY)) - for disk in "abcdefgh": - fm.execute_console("map {key}{0} chain shell pmount sd{1}; cd /media/sd{1}".format( - disk.upper(), disk, key=MOUNT_KEY)) - fm.execute_console("map {key}{0} chain cd; chain shell pumount sd{1}".format( - disk.upper(), disk, key=UMOUNT_KEY)) - for part in "123456789": - fm.execute_console( - "map {key}{0}{1} chain shell pmount sd{0}{1}; cd /media/sd{0}{1}".format( - disk, part, key=MOUNT_KEY) - ) - fm.execute_console("map {key}{0}{1} chain cd; shell pumount sd{0}{1}".format( - disk, part, key=UMOUNT_KEY)) - except Exception: - pass + fm.execute_console("map {key} shell -p lsblk".format(key=LIST_MOUNTS_KEY)) + for disk in "abcdefgh": + fm.execute_console("map {key}{0} chain shell pmount sd{1}; cd /media/sd{1}".format( + disk.upper(), disk, key=MOUNT_KEY)) + fm.execute_console("map {key}{0} chain cd; chain shell pumount sd{1}".format( + disk.upper(), disk, key=UMOUNT_KEY)) + for part in "123456789": + fm.execute_console( + "map {key}{0}{1} chain shell pmount sd{0}{1}; cd /media/sd{0}{1}".format( + disk, part, key=MOUNT_KEY) + ) + fm.execute_console("map {key}{0}{1} chain cd; shell pumount sd{0}{1}".format( + disk, part, key=UMOUNT_KEY)) return HOOK_INIT_OLD(fm) diff --git a/pylintrc b/pylintrc index d2729ce4..d108c93f 100644 --- a/pylintrc +++ b/pylintrc @@ -8,7 +8,7 @@ max-branches=16 [FORMAT] max-line-length = 99 -disable=locally-disabled,locally-enabled,missing-docstring,duplicate-code,fixme,broad-except,cyclic-import,redefined-variable-type +disable=locally-disabled,locally-enabled,missing-docstring,duplicate-code,fixme,cyclic-import,redefined-variable-type [TYPECHECK] ignored-classes=ranger.core.actions.Actions diff --git a/ranger/api/commands.py b/ranger/api/commands.py index 25353b5b..6b761de8 100644 --- a/ranger/api/commands.py +++ b/ranger/api/commands.py @@ -29,18 +29,14 @@ class CommandContainer(object): return self.commands[key] def alias(self, name, full_command): - try: - cmd = type(name, (AliasCommand, ), dict()) - # pylint: disable=protected-access - cmd._based_function = name - cmd._function_name = name - cmd._object_name = name - cmd._line = full_command - # pylint: enable=protected-access - self.commands[name] = cmd - - except Exception: - pass + cmd = type(name, (AliasCommand, ), dict()) + # pylint: disable=protected-access + cmd._based_function = name + cmd._function_name = name + cmd._object_name = name + cmd._line = full_command + # pylint: enable=protected-access + self.commands[name] = cmd def load_commands_from_module(self, module): for var in vars(module).values(): @@ -392,13 +388,13 @@ class FunctionCommand(Command): value = arg if (equal_sign is -1) else arg[equal_sign + 1:] try: value = int(value) - except Exception: + except ValueError: if value in ('True', 'False'): value = (value == 'True') else: try: value = float(value) - except Exception: + except ValueError: pass if equal_sign == -1: diff --git a/ranger/config/commands.py b/ranger/config/commands.py index bb20ddcb..eba94e19 100755 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -598,9 +598,10 @@ class console(Command): if self.arg(1)[0:2] == '-p': try: position = int(self.arg(1)[2:]) - self.shift() - except Exception: + except ValueError: pass + else: + self.shift() self.fm.open_console(self.rest(1), position=position) @@ -614,10 +615,10 @@ class load_copy_buffer(Command): def execute(self): from ranger.container.file import File from os.path import exists + fname = self.fm.confpath(self.copy_buffer_filename) try: - fname = self.fm.confpath(self.copy_buffer_filename) fobj = open(fname, 'r') - except Exception: + except OSError: return self.fm.notify( "Cannot open %s" % (fname or self.copy_buffer_filename), bad=True) self.fm.copy_buffer = set(File(g) @@ -635,10 +636,10 @@ class save_copy_buffer(Command): def execute(self): fname = None + fname = self.fm.confpath(self.copy_buffer_filename) try: - fname = self.fm.confpath(self.copy_buffer_filename) fobj = open(fname, 'w') - except Exception: + except OSError: return self.fm.notify("Cannot open %s" % (fname or self.copy_buffer_filename), bad=True) fobj.write("\n".join(fobj.path for fobj in self.fm.copy_buffer)) @@ -744,7 +745,7 @@ class eval_(Command): else: if result and not quiet: p(result) - except Exception as err: + except Exception as err: # pylint: disable=broad-except p(err) @@ -841,15 +842,12 @@ class chmod(Command): for fobj in self.fm.thistab.get_selection(): try: os.chmod(fobj.path, mode) - except Exception as ex: + except OSError as ex: self.fm.notify(ex) - try: - # reloading directory. maybe its better to reload the selected - # files only. - self.fm.thisdir.load_content() - except Exception: - pass + # reloading directory. maybe its better to reload the selected + # files only. + self.fm.thisdir.content_outdated = True class bulkrename(Command): @@ -1270,7 +1268,7 @@ class scout(Command): # pylint: enable=no-member try: self._regex = re.compile(regex, options) - except Exception: + except re.error: self._regex = re.compile("") return self._regex diff --git a/ranger/config/pylintrc b/ranger/config/pylintrc index adec41f1..7cac80d1 100644 --- a/ranger/config/pylintrc +++ b/ranger/config/pylintrc @@ -5,4 +5,4 @@ class-rgx=[a-z][a-z0-9_]{1,30}$ [FORMAT] max-line-length = 99 max-module-lines=3000 -disable=locally-disabled,locally-enabled,missing-docstring,duplicate-code,fixme,broad-except +disable=locally-disabled,locally-enabled,missing-docstring,duplicate-code,fixme diff --git a/ranger/container/bookmarks.py b/ranger/container/bookmarks.py index edffa5ae..305ac4c2 100644 --- a/ranger/container/bookmarks.py +++ b/ranger/container/bookmarks.py @@ -155,12 +155,8 @@ class Bookmarks(object): if os.access(self.path, os.W_OK): fobj = open(self.path + ".new", 'w') for key, value in self.dct.items(): - if isinstance(key, str)\ - and key in ALLOWED_KEYS: - try: - fobj.write("{0}:{1}\n".format(str(key), str(value))) - except Exception: - pass + if isinstance(key, str) and key in ALLOWED_KEYS: + fobj.write("{0}:{1}\n".format(str(key), str(value))) fobj.close() old_perms = os.stat(self.path) @@ -181,8 +177,8 @@ class Bookmarks(object): if not os.path.exists(self.path): try: fobj = open(self.path, 'w') - except Exception: - raise OSError('Cannot read the given path') + except OSError: + raise fobj.close() if os.access(self.path, os.R_OK): diff --git a/ranger/container/directory.py b/ranger/container/directory.py index 4fbc2e29..22901006 100644 --- a/ranger/container/directory.py +++ b/ranger/container/directory.py @@ -331,25 +331,25 @@ class Directory( # pylint: disable=too-many-instance-attributes,too-many-public file_stat = os_stat(name) else: file_stat = file_lstat + except OSError: + file_lstat = None + file_stat = None + if file_lstat and file_stat: stats = (file_stat, file_lstat) is_a_dir = file_stat.st_mode & 0o170000 == 0o040000 - except Exception: + else: stats = None is_a_dir = False + if is_a_dir: - try: - item = self.fm.get_directory(name) - item.load_if_outdated() - except Exception: - item = Directory(name, preload=stats, path_is_abs=True, - basename_is_rel_to=basename_is_rel_to) - item.load() + item = self.fm.get_directory(name, preload=stats, path_is_abs=True, + basename_is_rel_to=basename_is_rel_to) + item.load_if_outdated() + if self.flat: + item.relative_path = os.path.relpath(item.path, self.path) else: - if self.flat: - item.relative_path = os.path.relpath(item.path, self.path) - else: - item.relative_path = item.basename - item.relative_path_lower = item.relative_path.lower() + item.relative_path = item.basename + item.relative_path_lower = item.relative_path.lower() if item.vcs and item.vcs.track: if item.vcs.is_root_pointer: has_vcschild = True @@ -454,7 +454,7 @@ class Directory( # pylint: disable=too-many-instance-attributes,too-many-public try: sort_func = self.sort_dict[self.settings.sort] - except Exception: + except KeyError: sort_func = sort_by_basename if self.settings.sort_case_insensitive and \ @@ -494,9 +494,9 @@ class Directory( # pylint: disable=too-many-instance-attributes,too-many-public stat = os_stat(realpath(dirpath + "/" + fname)) else: stat = os_stat(dirpath + "/" + fname) - cum += stat.st_size - except Exception: - pass + except OSError: + continue + cum += stat.st_size return cum def look_up_cumulative_size(self): @@ -548,7 +548,7 @@ class Directory( # pylint: disable=too-many-instance-attributes,too-many-public def move_to_obj(self, arg, attr=None): try: arg = arg.path - except Exception: + except AttributeError: pass self.load_content_once(schedule=False) if self.empty(): @@ -594,11 +594,11 @@ class Directory( # pylint: disable=too-many-instance-attributes,too-many-public """Make sure the pointer is in the valid range""" Accumulator.correct_pointer(self) - try: - if self == self.fm.thisdir: + if self == self.fm.thisdir: + try: self.fm.thisfile = self.pointed_obj - except Exception: - pass + except AttributeError: + pass def load_content_once(self, *a, **k): """Load the contents of the directory if not done yet""" diff --git a/ranger/container/file.py b/ranger/container/file.py index e1284c1f..e0b9922c 100644 --- a/ranger/container/file.py +++ b/ranger/container/file.py @@ -54,14 +54,11 @@ class File(FileSystemObject): def firstbytes(self): if self._firstbytes is None: try: - fobj = open(self.path, 'r') - self._firstbytes = fobj.read(N_FIRST_BYTES) - fobj.close() - return self._firstbytes - except Exception: - pass - else: - return self._firstbytes + with open(self.path, 'r') as fobj: + self._firstbytes = fobj.read(N_FIRST_BYTES) + except OSError: + return None + return self._firstbytes def is_binary(self): if self.firstbytes and control_characters & set(self.firstbytes): diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py index fbb75e6c..0447d5a6 100644 --- a/ranger/container/fsobject.py +++ b/ranger/container/fsobject.py @@ -18,6 +18,7 @@ from ranger.ext import spawn from ranger.ext.lazy_property import lazy_property from ranger.ext.human_readable import human_readable +# Python 2 compatibility if hasattr(str, 'maketrans'): maketrans = str.maketrans # pylint: disable=invalid-name,no-member else: @@ -164,14 +165,14 @@ class FileSystemObject( # pylint: disable=too-many-instance-attributes def user(self): try: return getpwuid(self.stat.st_uid)[0] - except Exception: + except KeyError: return str(self.stat.st_uid) @lazy_property def group(self): try: return getgrgid(self.stat.st_gid)[0] - except Exception: + except KeyError: return str(self.stat.st_gid) for attr in ('video', 'audio', 'image', 'media', 'document', 'container'): @@ -220,7 +221,7 @@ class FileSystemObject( # pylint: disable=too-many-instance-attributes def mimetype(self): try: return self._mimetype - except Exception: + except AttributeError: self.set_mimetype() return self._mimetype @@ -228,7 +229,7 @@ class FileSystemObject( # pylint: disable=too-many-instance-attributes def mimetype_tuple(self): try: return self._mimetype_tuple - except Exception: + except AttributeError: self.set_mimetype() return self._mimetype_tuple @@ -245,7 +246,7 @@ class FileSystemObject( # pylint: disable=too-many-instance-attributes if self.is_link: try: return realpath(self.path) - except Exception: + except OSError: return None # it is impossible to get the link destination return self.path @@ -279,7 +280,7 @@ class FileSystemObject( # pylint: disable=too-many-instance-attributes if self.is_link: new_stat = stat(path) self.exists = True - except Exception: + except OSError: self.exists = False # Set some attributes diff --git a/ranger/container/history.py b/ranger/container/history.py index 31830b55..b3a1943e 100644 --- a/ranger/container/history.py +++ b/ranger/container/history.py @@ -35,7 +35,7 @@ class History(object): if self.unique: try: self._history.remove(item) - except Exception: + except ValueError: pass else: if self._history and self._history[-1] == item: @@ -51,9 +51,10 @@ class History(object): if self._history and unique: try: self._history.remove(item) - self._index -= 1 - except Exception: + except ValueError: pass + else: + self._index -= 1 try: self._history[self._index] = item except IndexError: @@ -101,13 +102,13 @@ class History(object): try: return self._history[-1] except IndexError: - raise HistoryEmptyException() + raise HistoryEmptyException def bottom(self): try: return self._history[0] except IndexError: - raise HistoryEmptyException() + raise HistoryEmptyException def back(self): self._index -= 1 diff --git a/ranger/container/settings.py b/ranger/container/settings.py index c42f50f2..012b5a2c 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -166,7 +166,7 @@ class Settings(SignalDispatcher, FileManagerAware): else: try: localpath = self.fm.thisdir.path - except Exception: + except AttributeError: localpath = path if localpath: @@ -236,8 +236,7 @@ class Settings(SignalDispatcher, FileManagerAware): if path not in self._localsettings: try: regex = re.compile(path) - except Exception: - # Bad regular expression + except re.error: # Bad regular expression return self._localregexes[path] = regex self._localsettings[path] = dict() diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 5e840058..baf98563 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -33,6 +33,7 @@ from ranger.container.file import File from ranger.core.loader import CommandLoader, CopyLoader from ranger.container.settings import ALLOWED_SETTINGS, ALLOWED_VALUES + MACRO_FAIL = "<\x01\x01MACRO_HAS_NO_VALUE\x01\01>" LOG = getLogger(__name__) @@ -57,7 +58,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m Exit the program. """ - raise SystemExit() + raise SystemExit def reset(self): """:reset @@ -143,25 +144,35 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m """ try: cwd = self.thisdir - except Exception: + except AttributeError: pass else: cwd.unload() cwd.load_content() - def notify(self, text, duration=4, bad=False): + def notify(self, obj, duration=4, bad=False, exception=None): """:notify <text> Display the text in the statusbar. """ - if isinstance(text, Exception): + if isinstance(obj, Exception): if ranger.args.debug: - raise text + raise obj + exception = obj bad = True - elif bad is True and ranger.args.debug: - raise Exception(str(text)) - text = str(text) - LOG.debug("Command notify invoked: [Bad: %s, Text: '%s']", bad, text) + elif bad and ranger.args.debug: + raise Exception(str(obj)) + + text = str(obj) + + text_log = 'Notification: {0}'.format(text) + if bad: + LOG.error(text_log) + else: + LOG.info(text_log) + if exception: + LOG.exception(exception) + if self.ui and self.ui.is_on: self.ui.status.notify(" ".join(text.split("\n")), duration=duration, bad=bad) @@ -175,7 +186,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m """ try: item = self.loader.queue[0] - except Exception: + except IndexError: self.notify("Type Q or :quit<Enter> to exit ranger") else: self.notify("Aborting: " + item.get_description()) @@ -230,7 +241,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m return self.notify(ex) try: cmd_class(string, quantifier=quantifier).execute() - except Exception as ex: + except Exception as ex: # pylint: disable=broad-except if ranger.args.debug: raise else: @@ -296,7 +307,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m for i in range(1, 10): try: tab = self.fm.tabs[i] - except Exception: + except KeyError: continue tabdir = tab.thisdir if not tabdir: @@ -365,7 +376,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m continue try: self.execute_console(line) - except Exception as ex: + except Exception as ex: # pylint: disable=broad-except if ranger.args.debug: raise else: @@ -396,7 +407,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m fobj.path + "\n" for fobj in self.fm.thistab.get_selection())) if ranger.args.choosefile or ranger.args.choosefiles: - raise SystemExit() + raise SystemExit if isinstance(files, set): files = list(files) @@ -440,10 +451,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m steps = direction.left() if narg is not None: steps *= narg - try: - directory = os.path.join(*(['..'] * steps)) - except Exception: - return + directory = os.path.join(*(['..'] * steps)) self.thistab.enter_dir(directory) self.change_mode('normal') if cwd and cwd.accessible and cwd.content_loaded: @@ -468,7 +476,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m if self.mode == 'visual': try: startpos = cwd.index(self._visual_start) - except Exception: + except ValueError: self._visual_start = None startpos = min(self._visual_start_pos, len(cwd)) # The files between here and _visual_start_pos @@ -703,7 +711,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m if isinstance(text, str) and regexp: try: text = re.compile(text, re.UNICODE | re.IGNORECASE) # pylint: disable=no-member - except Exception: + except re.error: return False self.thistab.last_search = text self.search_next(order='search', offset=offset) @@ -839,7 +847,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m def draw_possible_programs(self): try: target = self.thistab.get_selection()[0] - except Exception: + except IndexError: self.ui.browser.draw_info = [] return programs = [program for program in self.rifle.list_commands([target.path], None)] @@ -860,7 +868,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m def display_command_help(self, console_widget): try: command = console_widget._get_cmd_class() # pylint: disable=protected-access - except Exception: + except KeyError: self.notify("Feature not available!", bad=True) return @@ -912,9 +920,10 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m def update_preview(self, path): try: del self.previews[path] - self.ui.need_redraw = True - except Exception: + except KeyError: return False + self.ui.need_redraw = True + return True @staticmethod def sha1_encode(path): @@ -941,7 +950,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m # PDF file. try: data = self.previews[path] - except Exception: + except KeyError: data = self.previews[path] = {'loading': False} else: if data['loading']: @@ -959,7 +968,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m if found is False: try: stat_ = os.stat(self.settings.preview_script) - except Exception: + except OSError: self.fm.notify( "Preview Script `%s' doesn't exist!" % self.settings.preview_script, bad=True, @@ -1047,7 +1056,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m def on_destroy(signal): # pylint: disable=unused-argument try: del self.previews[path] - except Exception: + except KeyError: pass loadable.signal_bind('after', on_after) loadable.signal_bind('destroy', on_destroy) @@ -1058,7 +1067,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m else: try: return codecs.open(path, 'r', errors='ignore') - except Exception: + except OSError: return None # -------------------------- @@ -1317,31 +1326,34 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m def paste_symlink(self, relative=False): copied_files = self.copy_buffer for fobj in copied_files: - self.notify(next_available_filename(fobj.basename)) + new_name = next_available_filename(fobj.basename) + self.notify(new_name) try: - new_name = next_available_filename(fobj.basename) if relative: relative_symlink(fobj.path, join(getcwd(), new_name)) else: symlink(fobj.path, join(getcwd(), new_name)) - except Exception as ex: - self.notify(ex) + except OSError as ex: + self.notify('Failed to paste symlink: View log for more info', + bad=True, exception=ex) def paste_hardlink(self): for fobj in self.copy_buffer: + new_name = next_available_filename(fobj.basename) try: - new_name = next_available_filename(fobj.basename) link(fobj.path, join(getcwd(), new_name)) - except Exception as ex: - self.notify(ex) + except OSError as ex: + self.notify('Failed to paste hardlink: View log for more info', + bad=True, exception=ex) def paste_hardlinked_subtree(self): for fobj in self.copy_buffer: try: target_path = join(getcwd(), fobj.basename) self._recurse_hardlinked_tree(fobj.path, target_path) - except Exception as ex: - self.notify(ex) + except OSError as ex: + self.notify('Failed to paste hardlinked subtree: View log for more info', + bad=True, exception=ex) def _recurse_hardlinked_tree(self, source_path, target_path): if isdir(source_path): diff --git a/ranger/core/fm.py b/ranger/core/fm.py index 87c8b9f1..f524bbc4 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -7,7 +7,6 @@ from __future__ import (absolute_import, division, print_function) from time import time from collections import deque -import logging import mimetypes import os.path import pwd @@ -33,9 +32,6 @@ from ranger.core.loader import Loader from ranger.ext import logutils -LOG = logging.getLogger(__name__) - - class FM(Actions, # pylint: disable=too-many-instance-attributes SignalDispatcher): input_blocked = False @@ -74,7 +70,7 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes try: self.username = pwd.getpwuid(os.geteuid()).pw_name - except Exception: + except KeyError: self.username = 'uid:' + str(os.geteuid()) self.hostname = socket.gethostname() self.home_path = os.path.expanduser('~') @@ -195,13 +191,13 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes if self.ui: try: self.ui.destroy() - except Exception: + except Exception: # pylint: disable=broad-except if debug: raise if self.loader: try: self.loader.destroy() - except Exception: + except Exception: # pylint: disable=broad-except if debug: raise @@ -209,10 +205,10 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes def get_log(): """Return the current log - The log is returned as a list of string + The log is returned as a generator over its entries' lines """ - for log in logutils.log_queue: - for line in log.split('\n'): + for entry in logutils.QUEUE: + for line in entry.splitlines(): yield line def _get_image_displayer(self): @@ -270,10 +266,10 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes print(ranger.args.confdir) print("To run ranger without the need for configuration") print("files, use the --clean option.") - raise SystemExit() + raise SystemExit try: shutil.copy(self.relpath(src), self.confpath(dest)) - except Exception as ex: + except OSError as ex: sys.stderr.write(" ERROR: %s\n" % str(ex)) if which == 'rifle' or which == 'all': copy('config/rifle.conf', 'rifle.conf') @@ -313,13 +309,13 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes """returns the path relative to rangers library directory""" return os.path.join(ranger.RANGERDIR, *paths) - def get_directory(self, path): + def get_directory(self, path, **dir_kwargs): """Get the directory object at the given path""" path = os.path.abspath(path) try: return self.directories[path] except KeyError: - obj = Directory(path) + obj = Directory(path, **dir_kwargs) self.directories[path] = obj return obj diff --git a/ranger/core/loader.py b/ranger/core/loader.py index 022dfe6b..59ce7391 100644 --- a/ranger/core/loader.py +++ b/ranger/core/loader.py @@ -18,7 +18,7 @@ from ranger.ext.human_readable import human_readable try: import chardet # pylint: disable=import-error HAVE_CHARDET = True -except Exception: +except ImportError: HAVE_CHARDET = False @@ -40,7 +40,7 @@ class Loadable(object): def unpause(self): try: del self.paused - except Exception: + except AttributeError: pass def destroy(self): @@ -74,7 +74,7 @@ class CopyLoader(Loadable, FileManagerAware): # pylint: disable=too-many-instan else: try: fstat = os.stat(fname) - except Exception: + except OSError: continue size += max(step, math.ceil(fstat.st_size / step) * step) return size @@ -239,7 +239,7 @@ class CommandLoader( # pylint: disable=too-many-instance-attributes return try: self.process.send_signal(20) - except Exception: + except OSError: pass Loadable.pause(self) self.signal_emit('pause', process=self.process, loader=self) @@ -248,7 +248,7 @@ class CommandLoader( # pylint: disable=too-many-instance-attributes if not self.finished and self.paused: try: self.process.send_signal(18) - except Exception: + except OSError: pass Loadable.unpause(self) self.signal_emit('unpause', process=self.process, loader=self) @@ -409,9 +409,6 @@ class Loader(FileManagerAware): self.fm.ui.status.request_redraw() except StopIteration: self._remove_current_process(item) - except Exception as err: - self.fm.notify(err) - self._remove_current_process(item) def _remove_current_process(self, item): item.load_generator = None diff --git a/ranger/core/main.py b/ranger/core/main.py index bd837aa1..23debc76 100644 --- a/ranger/core/main.py +++ b/ranger/core/main.py @@ -39,7 +39,7 @@ def main( try: locale.setlocale(locale.LC_ALL, '') - except Exception: + except locale.Error: print("Warning: Unable to set locale. Expect encoding problems.") # so that programs can know that ranger spawned them: @@ -66,7 +66,7 @@ def main( fobj = open(fm.confpath('tagged'), 'r', errors='replace') else: fobj = open(fm.confpath('tagged'), 'r') - except Exception: + except OSError: pass else: for line in fobj.readlines(): @@ -164,7 +164,7 @@ def main( profile = pstats.Stats(tempfile.gettempdir() + '/ranger_profile', stream=sys.stderr) else: fm.loop() - except Exception: + except Exception: # pylint: disable=broad-except import traceback crash_traceback = traceback.format_exc() except SystemExit as error: @@ -173,7 +173,7 @@ def main( if crash_traceback: try: filepath = fm.thisfile.path if fm.thisfile else "None" - except Exception: + except AttributeError: filepath = "None" try: fm.ui.destroy() @@ -187,7 +187,7 @@ def main( print("Locale: %s" % '.'.join(str(s) for s in locale.getlocale())) try: print("Current file: %s" % filepath) - except Exception: + except NameError: pass print(crash_traceback) print("ranger crashed. " @@ -318,13 +318,14 @@ def load_settings( # pylint: disable=too-many-locals,too-many-branches,too-many allow_access_to_confdir(ranger.args.confdir, True) # XXX Load plugins (experimental) + plugindir = fm.confpath('plugins') try: - plugindir = fm.confpath('plugins') - plugins = [p[:-3] for p in os.listdir(plugindir) - if p.endswith('.py') and not p.startswith('_')] - except Exception: - pass + plugin_files = os.listdir(plugindir) + except OSError: + LOG.debug('Unable to access plugin directory: %s', plugindir) else: + plugins = [p[:-3] for p in plugin_files + if p.endswith('.py') and not p.startswith('_')] if not os.path.exists(fm.confpath('plugins', '__init__.py')): LOG.debug("Creating missing '__init__.py' file in plugin folder") fobj = open(fm.confpath('plugins', '__init__.py'), 'w') @@ -344,7 +345,7 @@ def load_settings( # pylint: disable=too-many-locals,too-many-branches,too-many module = importlib.import_module('plugins.' + plugin) fm.commands.load_commands_from_module(module) LOG.debug("Loaded plugin '%s'", plugin) - except Exception as ex: + except Exception as ex: # pylint: disable=broad-except ex_msg = "Error while loading plugin '{0}'".format(plugin) LOG.error(ex_msg) LOG.exception(ex) @@ -389,7 +390,7 @@ def allow_access_to_confdir(confdir, allow): print(confdir) print("To run ranger without the need for configuration") print("files, use the --clean option.") - raise SystemExit() + raise SystemExit else: LOG.debug("Created config directory '%s'", confdir) if confdir not in sys.path: diff --git a/ranger/core/runner.py b/ranger/core/runner.py index 6fc7b60d..8c3e3162 100644 --- a/ranger/core/runner.py +++ b/ranger/core/runner.py @@ -24,6 +24,7 @@ t: run application in a new terminal window from __future__ import (absolute_import, division, print_function) +import logging import os import sys from subprocess import Popen, PIPE @@ -31,6 +32,9 @@ from ranger.ext.get_executables import get_executables, get_term from ranger.ext.popen_forked import Popen_forked +LOG = logging.getLogger(__name__) + + # TODO: Remove unused parts of runner.py # ALLOWED_FLAGS = 'sdpwcrtSDPWCRT' ALLOWED_FLAGS = 'cfrtCFRT' @@ -81,7 +85,7 @@ class Context(object): # pylint: disable=too-many-instance-attributes def filepaths(self): try: return [f.path for f in self.files] - except Exception: + except AttributeError: return [] def __iter__(self): @@ -117,13 +121,15 @@ class Runner(object): # pylint: disable=too-few-public-methods if boolean: try: self.ui.initialize() - except Exception: + except Exception as ex: # pylint: disable=broad-except self._log("Failed to initialize UI") + LOG.exception(ex) else: try: self.ui.suspend() - except Exception: + except Exception as ex: # pylint: disable=broad-except self._log("Failed to suspend UI") + LOG.exception(ex) def __call__( # pylint: disable=too-many-branches,too-many-statements @@ -235,7 +241,7 @@ class Runner(object): # pylint: disable=too-few-public-methods Popen_forked(**popen_kws) else: process = Popen(**popen_kws) - except Exception as ex: + except OSError as ex: error = ex self._log("Failed to run: %s\n%s" % (str(action), str(ex))) else: diff --git a/ranger/core/tab.py b/ranger/core/tab.py index 26f634da..160f590f 100644 --- a/ranger/core/tab.py +++ b/ranger/core/tab.py @@ -130,7 +130,7 @@ class Tab(FileManagerAware, SettingsAware): # pylint: disable=too-many-instance try: os.chdir(path) - except Exception: + except OSError: return True self.path = path self.thisdir = new_thisdir diff --git a/ranger/ext/cached_function.py b/ranger/ext/cached_function.py index 643b6304..4255443c 100644 --- a/ranger/ext/cached_function.py +++ b/ranger/ext/cached_function.py @@ -10,7 +10,7 @@ def cached_function(fnc): def inner_cached_function(*args): try: return cache[args] - except Exception: + except KeyError: value = fnc(*args) cache[args] = value return value diff --git a/ranger/ext/direction.py b/ranger/ext/direction.py index ecde944a..7268d5d6 100644 --- a/ranger/ext/direction.py +++ b/ranger/ext/direction.py @@ -38,19 +38,19 @@ class Direction(dict): def _get_bool(self, first, second, fallback=None): try: return self[first] - except Exception: + except KeyError: try: return not self[second] - except Exception: + except KeyError: return fallback def _get_direction(self, first, second, fallback=0): try: return self[first] - except Exception: + except KeyError: try: return -self[second] - except Exception: + except KeyError: return fallback def up(self): # pylint: disable=invalid-name @@ -98,7 +98,7 @@ class Direction(dict): for key in ('up', 'right', 'down', 'left'): try: self[key] *= n - except Exception: + except KeyError: pass def set(self, n): diff --git a/ranger/ext/get_executables.py b/ranger/ext/get_executables.py index 86296a2a..1646cb56 100644 --- a/ranger/ext/get_executables.py +++ b/ranger/ext/get_executables.py @@ -37,13 +37,13 @@ def get_executables_uncached(*paths): for path in paths: try: content = listdir(path) - except Exception: + except OSError: continue for item in content: abspath = path + '/' + item try: filestat = stat(abspath) - except Exception: + except OSError: continue if filestat.st_mode & (S_IXOTH | S_IFREG): executables.add(item) diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index 1b20cc7b..b4deaa39 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -35,6 +35,10 @@ W3MIMGDISPLAY_PATHS = [ ] +class ImageDisplayError(Exception): + pass + + class ImgDisplayUnsupportedException(Exception): pass @@ -83,9 +87,9 @@ class W3MImageDisplayer(ImageDisplayer): for path in paths: if path is not None and os.path.exists(path): return path - raise RuntimeError("No w3mimgdisplay executable found. Please set " - "the path manually by setting the %s environment variable. (see " - "man page)" % W3MIMGDISPLAY_ENV) + raise ImageDisplayError("No w3mimgdisplay executable found. Please set " + "the path manually by setting the %s environment variable. (see " + "man page)" % W3MIMGDISPLAY_ENV) def _get_font_dimensions(self): # Get the height and width of a character displayed in the terminal in @@ -110,7 +114,11 @@ class W3MImageDisplayer(ImageDisplayer): def draw(self, path, start_x, start_y, width, height): if not self.is_initialized or self.process.poll() is not None: self.initialize() - self.process.stdin.write(self._generate_w3m_input(path, start_x, start_y, width, height)) + try: + input_gen = self._generate_w3m_input(path, start_x, start_y, width, height) + except ImageDisplayError: + raise + self.process.stdin.write(input_gen) self.process.stdin.flush() self.process.stdout.readline() @@ -146,7 +154,7 @@ class W3MImageDisplayer(ImageDisplayer): """ fontw, fonth = self._get_font_dimensions() if fontw == 0 or fonth == 0: - raise ImgDisplayUnsupportedException() + raise ImgDisplayUnsupportedException max_width_pixels = max_width * fontw max_height_pixels = max_height * fonth - 2 @@ -161,7 +169,7 @@ class W3MImageDisplayer(ImageDisplayer): output = self.process.stdout.readline().split() if len(output) != 2: - raise Exception('Failed to execute w3mimgdisplay', output) + raise ImageDisplayError('Failed to execute w3mimgdisplay', output) width = int(output[0]) height = int(output[1]) @@ -257,13 +265,8 @@ class ITerm2ImageDisplayer(ImageDisplayer, FileManagerAware): @staticmethod def _encode_image_content(path): """Read and encode the contents of path""" - fobj = open(path, 'rb') - try: + with open(path, 'rb') as fobj: return base64.b64encode(fobj.read()) - except Exception: - return "" - finally: - fobj.close() @staticmethod def _get_image_dimensions(path): @@ -296,7 +299,7 @@ class ITerm2ImageDisplayer(ImageDisplayer, FileManagerAware): size = struct.unpack('>H', file_handle.read(2))[0] - 2 file_handle.seek(1, 1) height, width = struct.unpack('>HH', file_handle.read(4)) - except Exception: + except OSError: file_handle.close() return 0, 0 else: diff --git a/ranger/ext/keybinding_parser.py b/ranger/ext/keybinding_parser.py index 34282767..e5fb6a86 100644 --- a/ranger/ext/keybinding_parser.py +++ b/ranger/ext/keybinding_parser.py @@ -153,8 +153,11 @@ def _unbind_traverse(pointer, keys, pos=0): elif len(keys) == pos + 1: try: del pointer[keys[pos]] + except KeyError: + pass + try: keys.pop() - except Exception: + except IndexError: pass @@ -174,7 +177,7 @@ class KeyMaps(dict): def _clean_input(self, context, keys): try: pointer = self[context] - except Exception: + except KeyError: self[context] = pointer = dict() if PY3: keys = keys.encode('utf-8').decode('latin-1') @@ -191,7 +194,7 @@ class KeyMaps(dict): pointer = pointer[key] else: pointer[key] = pointer = dict() - except Exception: + except KeyError: pointer[key] = pointer = dict() pointer[last_key] = leaf @@ -202,7 +205,7 @@ class KeyMaps(dict): for key in clean_source: try: pointer = pointer[key] - except Exception: + except KeyError: raise KeyError("Tried to copy the keybinding `%s'," " but it was not found." % source) self.bind(context, target, copy.deepcopy(pointer)) diff --git a/ranger/ext/logutils.py b/ranger/ext/logutils.py index b00aa605..38fc7cda 100644 --- a/ranger/ext/logutils.py +++ b/ranger/ext/logutils.py @@ -3,10 +3,6 @@ from __future__ import (absolute_import, division, print_function) import logging from collections import deque -LOG_FORMAT = "[%(levelname)s] %(message)s" -LOG_FORMAT_EXT = "%(asctime)s,%(msecs)d [%(name)s] |%(levelname)s| %(message)s" -LOG_DATA_FORMAT = "%H:%M:%S" - class QueueHandler(logging.Handler): """ @@ -30,11 +26,11 @@ class QueueHandler(logging.Handler): self.enqueue(self.format(record)) -# pylint: disable=invalid-name -log_queue = deque(maxlen=1000) -concise_formatter = logging.Formatter(fmt=LOG_FORMAT, datefmt=LOG_DATA_FORMAT) -extended_formatter = logging.Formatter(fmt=LOG_FORMAT_EXT, datefmt=LOG_DATA_FORMAT) -# pylint: enable=invalid-name +QUEUE = deque(maxlen=1000) +FMT_NORMAL = logging.Formatter( + fmt='%(asctime)s %(levelname).4s %(message)s', datefmt='%H:%M:%S') +FMT_DEBUG = logging.Formatter( + fmt='%(asctime)s.%(msecs)03d %(levelname).4s [%(name)s] %(message)s', datefmt='%H:%M:%S') def setup_logging(debug=True, logfile=None): @@ -57,17 +53,14 @@ def setup_logging(debug=True, logfile=None): root_logger = logging.getLogger() if debug: - # print all logging in extended format log_level = logging.DEBUG - formatter = extended_formatter + formatter = FMT_DEBUG else: - # print only warning and critical message - # in a concise format log_level = logging.INFO - formatter = concise_formatter + formatter = FMT_NORMAL handlers = [] - handlers.append(QueueHandler(log_queue)) + handlers.append(QueueHandler(QUEUE)) if logfile: if logfile == '-': handlers.append(logging.StreamHandler()) diff --git a/ranger/ext/rifle.py b/ranger/ext/rifle.py index 551dd288..c6b96f73 100755 --- a/ranger/ext/rifle.py +++ b/ranger/ext/rifle.py @@ -94,7 +94,7 @@ def _is_terminal(): os.ttyname(0) os.ttyname(1) os.ttyname(2) - except Exception: + except OSError: return False return True @@ -168,17 +168,13 @@ class Rifle(object): # pylint: disable=too-many-instance-attributes line = line.strip() if line.startswith('#') or line == '': continue - try: - if self.delimiter1 not in line: - raise Exception("Line without delimiter") - tests, command = line.split(self.delimiter1, 1) - tests = tests.split(self.delimiter2) - tests = tuple(tuple(f.strip().split(None, 1)) for f in tests) - command = command.strip() - self.rules.append((command, tests)) - except Exception as ex: - self.hook_logger( - "Syntax error in %s line %d (%s)" % (config_file, lineno, str(ex))) + if self.delimiter1 not in line: + raise ValueError("Line without delimiter") + tests, command = line.split(self.delimiter1, 1) + tests = tests.split(self.delimiter2) + tests = tuple(tuple(f.strip().split(None, 1)) for f in tests) + command = command.strip() + self.rules.append((command, tests)) fobj.close() def _eval_condition(self, condition, files, label): diff --git a/ranger/ext/shutil_generatorized.py b/ranger/ext/shutil_generatorized.py index 338ed5b8..f1cf5a46 100644 --- a/ranger/ext/shutil_generatorized.py +++ b/ranger/ext/shutil_generatorized.py @@ -95,17 +95,17 @@ def copystat(src, dst): if hasattr(os, 'utime'): try: os.utime(dst, (fstat.st_atime, fstat.st_mtime)) - except Exception: + except OSError: pass if hasattr(os, 'chmod'): try: os.chmod(dst, mode) - except Exception: + except OSError: pass if hasattr(os, 'chflags') and hasattr(fstat, 'st_flags'): try: os.chflags(dst, fstat.st_flags) # pylint: disable=no-member - except Exception: + except OSError: pass @@ -182,7 +182,7 @@ def copytree(src, dst, # pylint: disable=too-many-locals,too-many-branches errors = [] try: os.makedirs(dst) - except Exception as err: + except OSError: if not overwrite: dst = get_safe_path(dst) os.makedirs(dst) @@ -212,10 +212,10 @@ def copytree(src, dst, # pylint: disable=too-many-locals,too-many-branches done += n # catch the Error from the recursive copytree so that we can # continue with other files - except Error as err: - errors.extend(err.args[0]) - except EnvironmentError as why: - errors.append((srcname, dstname, str(why))) + except Error as ex: + errors.extend(ex.args[0]) + except EnvironmentError as ex: + errors.append((srcname, dstname, str(ex))) try: copystat(src, dst) except OSError as why: diff --git a/ranger/ext/signals.py b/ranger/ext/signals.py index 4d2ee25e..50141565 100644 --- a/ranger/ext/signals.py +++ b/ranger/ext/signals.py @@ -137,7 +137,7 @@ class SignalDispatcher(object): assert isinstance(weak, bool) try: handlers = self._signals[signal_name] - except Exception: + except KeyError: handlers = self._signals[signal_name] = [] nargs = function.__code__.co_argcount @@ -180,13 +180,13 @@ class SignalDispatcher(object): try: handlers = self._signals[ signal_handler._signal_name] # pylint: disable=protected-access - except Exception: + except KeyError: pass else: + signal_handler._function = None # pylint: disable=protected-access try: - signal_handler._function = None # pylint: disable=protected-access handlers.remove(signal_handler) - except Exception: + except IndexError: pass def signal_garbage_collect(self): diff --git a/ranger/ext/vcs/vcs.py b/ranger/ext/vcs/vcs.py index 8b13badd..00f51152 100644 --- a/ranger/ext/vcs/vcs.py +++ b/ranger/ext/vcs/vcs.py @@ -9,22 +9,14 @@ import os import subprocess import threading import time -from logging import getLogger from ranger.ext import spawn -# Python2 compatibility +# Python 2 compatibility try: import queue except ImportError: import Queue as queue # pylint: disable=import-error -try: - FileNotFoundError -except NameError: - FileNotFoundError = OSError # pylint: disable=redefined-builtin - - -LOG = getLogger(__name__) class VcsError(Exception): @@ -133,7 +125,7 @@ class Vcs(object): # pylint: disable=too-many-instance-attributes else: with open(os.devnull, mode='w') as fd_devnull: subprocess.check_call(cmd, cwd=path, stdout=fd_devnull, stderr=fd_devnull) - except (subprocess.CalledProcessError, FileNotFoundError): + except (subprocess.CalledProcessError, OSError): raise VcsError('{0:s}: {1:s}'.format(str(cmd), path)) def _get_repotype(self, path): @@ -238,9 +230,8 @@ class VcsRoot(Vcs): # pylint: disable=abstract-method self.branch = self.data_branch() self.obj.vcsremotestatus = self.data_status_remote() self.obj.vcsstatus = self.data_status_root() - except VcsError as error: - LOG.exception(error) - self.obj.fm.notify('VCS Exception: View log for more info', bad=True) + except VcsError as ex: + self.obj.fm.notify('VCS Exception: View log for more info', bad=True, exception=ex) return False self.rootinit = True return True @@ -253,9 +244,8 @@ class VcsRoot(Vcs): # pylint: disable=abstract-method self.status_subpaths = self.data_status_subpaths() self.obj.vcsremotestatus = self.data_status_remote() self.obj.vcsstatus = self._status_root() - except VcsError as error: - LOG.exception(error) - self.obj.fm.notify('VCS Exception: View log for more info', bad=True) + except VcsError as ex: + self.obj.fm.notify('VCS Exception: View log for more info', bad=True, exception=ex) return False self.rootinit = True self.updatetime = time.time() @@ -479,9 +469,8 @@ class VcsThread(threading.Thread): # pylint: disable=too-many-instance-attribut column.need_redraw = True self.ui.status.need_redraw = True self.ui.redraw() - except Exception as error: # pylint: disable=broad-except - LOG.exception(error) - self.ui.fm.notify('VCS Exception: View log for more info', bad=True) + except Exception as ex: # pylint: disable=broad-except + self.ui.fm.notify('VCS Exception: View log for more info', bad=True, exception=ex) def pause(self): """Pause thread""" diff --git a/ranger/ext/widestring.py b/ranger/ext/widestring.py index 23e3d050..ed66f3c7 100644 --- a/ranger/ext/widestring.py +++ b/ranger/ext/widestring.py @@ -62,10 +62,7 @@ class WideString(object): # pylint: disable=too-few-public-methods except UnicodeEncodeError: # Here I assume that string is a "unicode" object, because why else # would str(string) raise a UnicodeEncodeError? - try: - self.string = string.encode('latin-1', 'ignore') - except Exception: - self.string = "" + self.string = string.encode('latin-1', 'ignore') if chars is None: self.chars = string_to_charlist(string) else: diff --git a/ranger/gui/ansi.py b/ranger/gui/ansi.py index 4bfaa0a0..5cb2ab90 100644 --- a/ranger/gui/ansi.py +++ b/ranger/gui/ansi.py @@ -51,7 +51,7 @@ def text_with_fg_bg_attr(ansi_text): # pylint: disable=too-many-branches,too-ma n = int(arg) else: # empty code means reset n = 0 - except Exception: + except ValueError: continue if n == 0: # reset colors and attributes diff --git a/ranger/gui/color.py b/ranger/gui/color.py index 7f2b73af..45f983e8 100644 --- a/ranger/gui/color.py +++ b/ranger/gui/color.py @@ -30,7 +30,7 @@ def get_color(fg, bg): size = len(COLOR_PAIRS) try: curses.init_pair(size, fg, bg) - except Exception: + except curses.error: # If curses.use_default_colors() failed during the initialization # of curses, then using -1 as fg or bg will fail as well, which # we need to handle with fallback-defaults: @@ -41,7 +41,7 @@ def get_color(fg, bg): try: curses.init_pair(size, fg, bg) - except Exception: + except curses.error: # If this fails too, colors are probably not supported pass COLOR_PAIRS[key] = size diff --git a/ranger/gui/colorscheme.py b/ranger/gui/colorscheme.py index c5aa0e31..75a82146 100644 --- a/ranger/gui/colorscheme.py +++ b/ranger/gui/colorscheme.py @@ -37,6 +37,10 @@ from ranger.ext.cached_function import cached_function from ranger.ext.iter_tools import flatten +class ColorSchemeError(Exception): + pass + + class ColorScheme(object): """This is the class that colorschemes must inherit from. @@ -96,7 +100,7 @@ def _colorscheme_name_to_class(signal): # pylint: disable=too-many-branches def is_scheme(cls): try: return issubclass(cls, ColorScheme) - except Exception: + except TypeError: return False # create ~/.config/ranger/colorschemes/__init__.py if it doesn't exist @@ -120,7 +124,7 @@ def _colorscheme_name_to_class(signal): # pylint: disable=too-many-branches signal.value = signal.previous else: signal.value = ColorScheme() - raise Exception("Cannot locate colorscheme `%s'" % scheme_name) + raise ColorSchemeError("Cannot locate colorscheme `%s'" % scheme_name) else: if usecustom: allow_access_to_confdir(ranger.args.confdir, True) @@ -137,7 +141,7 @@ def _colorscheme_name_to_class(signal): # pylint: disable=too-many-branches signal.value = var() break else: - raise Exception("The module contains no valid colorscheme!") + raise ColorSchemeError("The module contains no valid colorscheme!") def get_all_colorschemes(): diff --git a/ranger/gui/curses_shortcuts.py b/ranger/gui/curses_shortcuts.py index 2c411058..648292c5 100644 --- a/ranger/gui/curses_shortcuts.py +++ b/ranger/gui/curses_shortcuts.py @@ -36,13 +36,13 @@ class CursesShortcuts(SettingsAware): try: self.win.addstr(*args) - except Exception: + except curses.error: if len(args) > 1: self.win.move(y, x) try: self.win.addstr(*_fix_surrogates(args)) - except Exception: + except curses.error: pass def addnstr(self, *args): @@ -50,13 +50,13 @@ class CursesShortcuts(SettingsAware): try: self.win.addnstr(*args) - except Exception: + except curses.error: if len(args) > 2: self.win.move(y, x) try: self.win.addnstr(*_fix_surrogates(args)) - except Exception: + except curses.error: pass def addch(self, *args): @@ -64,7 +64,7 @@ class CursesShortcuts(SettingsAware): args = [args[1], args[0]] + list(args[2:]) try: self.win.addch(*args) - except Exception: + except curses.error: pass def color(self, *keys): diff --git a/ranger/gui/displayable.py b/ranger/gui/displayable.py index 2ce23165..926fd857 100644 --- a/ranger/gui/displayable.py +++ b/ranger/gui/displayable.py @@ -3,6 +3,8 @@ from __future__ import (absolute_import, division, print_function) +import curses + from ranger.core.shared import FileManagerAware from ranger.gui.curses_shortcuts import CursesShortcuts @@ -176,13 +178,13 @@ class Displayable( # pylint: disable=too-many-instance-attributes window_is_cleared = True try: self.win.resize(hei, wid) - except Exception: + except curses.error: # Not enough space for resizing... try: self.win.mvderwin(0, 0) do_move = True self.win.resize(hei, wid) - except Exception: + except curses.error: pass # raise ValueError("Resizing Failed!") @@ -195,7 +197,7 @@ class Displayable( # pylint: disable=too-many-instance-attributes # log("moving " + str(self)) try: self.win.mvderwin(y, x) - except Exception: + except curses.error: pass self.paryx = self.win.getparyx() diff --git a/ranger/gui/mouse_event.py b/ranger/gui/mouse_event.py index 160351d3..0eccbf57 100644 --- a/ranger/gui/mouse_event.py +++ b/ranger/gui/mouse_event.py @@ -32,7 +32,7 @@ class MouseEvent(object): """Returns whether the mouse key n is pressed""" try: return (self.bstate & MouseEvent.PRESSED[n]) != 0 - except Exception: + except IndexError: return False def mouse_wheel_direction(self): diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py index 6c84580b..20e01536 100644 --- a/ranger/gui/ui.py +++ b/ranger/gui/ui.py @@ -91,12 +91,12 @@ class UI( # pylint: disable=too-many-instance-attributes,too-many-public-method curses.halfdelay(20) try: curses.curs_set(int(bool(self.settings.show_cursor))) - except Exception: + except curses.error: pass curses.start_color() try: curses.use_default_colors() - except Exception: + except curses.error: pass self.settings.signal_bind('setopt.mouse_enabled', _setup_mouse) @@ -130,7 +130,7 @@ class UI( # pylint: disable=too-many-instance-attributes,too-many-public-method curses.echo() try: curses.curs_set(1) - except Exception: + except curses.error: pass if self.settings.mouse_enabled: _setup_mouse(dict(value=False)) @@ -346,14 +346,16 @@ class UI( # pylint: disable=too-many-instance-attributes,too-many-public-method try: fixed_cwd = cwd.encode('utf-8', 'surrogateescape'). \ decode('utf-8', 'replace') - sys.stdout.write("%sranger:%s%s" % ( + fmt_tup = ( curses.tigetstr('tsl').decode('latin-1'), fixed_cwd, curses.tigetstr('fsl').decode('latin-1'), - )) - sys.stdout.flush() - except Exception: + ) + except UnicodeError: pass + else: + sys.stdout.write("%sranger:%s%s" % fmt_tup) + sys.stdout.flush() self.win.refresh() diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 6f890dab..b0435785 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -5,6 +5,7 @@ from __future__ import (absolute_import, division, print_function) +import curses import stat from time import time from os.path import splitext @@ -76,13 +77,14 @@ class BrowserColumn(Pager): # pylint: disable=too-many-instance-attributes elif event.pressed(3): try: clicked_file = self.target.files[index] + except IndexError: + pass + else: if clicked_file.is_directory: self.fm.enter_dir(clicked_file.path) elif self.level == 0: self.fm.thisdir.move_to_obj(clicked_file) self.fm.execute_file(clicked_file) - except Exception: - pass else: if self.level > 0 and not direction: @@ -102,7 +104,7 @@ class BrowserColumn(Pager): # pylint: disable=too-many-instance-attributes """ try: self.win.move(line, 0) - except Exception: + except curses.error: return for entry in commands: text, attr = entry @@ -363,11 +365,10 @@ class BrowserColumn(Pager): # pylint: disable=too-many-instance-attributes predisplay_left += textstring space -= textstringlen + assert space >= 0, "Error: there is not enough space to write the text. " \ + "I have computed spaces wrong." if space > 0: predisplay_left.append([' ' * space, []]) - elif space < 0: - raise Exception("Error: there is not enough space to write " - "the text. I have computed spaces wrong.") # Computing display data. Now we compute the display_data list # ready to display in curses. It is a list of lists [string, attr] diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py index 0fa941d4..a2e058ad 100644 --- a/ranger/gui/widgets/console.py +++ b/ranger/gui/widgets/console.py @@ -42,8 +42,8 @@ class Console(Widget): # pylint: disable=too-many-instance-attributes,too-many- self.historypath = self.fm.confpath('history') try: fobj = open(self.historypath, 'r') - except Exception: - pass + except OSError as ex: + self.fm.notify('Unable to read history file', bad=True, exception=ex) else: for line in fobj: self.history.add(line[:-1]) @@ -70,8 +70,8 @@ class Console(Widget): # pylint: disable=too-many-instance-attributes,too-many- if self.historypath: try: fobj = open(self.historypath, 'w') - except Exception: - pass + except OSError as ex: + self.fm.notify('Unable to write history file', bad=True, exception=ex) else: for entry in self.history_backup: try: @@ -102,13 +102,13 @@ class Console(Widget): # pylint: disable=too-many-instance-attributes,too-many- if self.question_queue: try: move(self.y, len(self.question_queue[0][0])) - except Exception: + except curses.error: pass else: try: pos = uwid(self.line[0:self.pos]) + len(self.prompt) move(self.y, self.x + min(self.wid - 1, pos)) - except Exception: + except curses.error: pass def open(self, string='', prompt=None, position=None): @@ -121,7 +121,7 @@ class Console(Widget): # pylint: disable=too-many-instance-attributes,too-many- if self.last_cursor_mode is None: try: self.last_cursor_mode = curses.curs_set(1) - except Exception: + except curses.error: pass self.allow_close = False self.tab_deque = None @@ -150,14 +150,11 @@ class Console(Widget): # pylint: disable=too-many-instance-attributes,too-many- if trigger_cancel_function: cmd = self._get_cmd(quiet=True) if cmd: - try: - cmd.cancel() - except Exception as error: - self.fm.notify(error) + cmd.cancel() if self.last_cursor_mode is not None: try: curses.curs_set(self.last_cursor_mode) - except Exception: + except curses.error: pass self.last_cursor_mode = None self.fm.hide_console_info() @@ -446,8 +443,6 @@ class Console(Widget): # pylint: disable=too-many-instance-attributes,too-many- if not quiet: error = "Command not found: `%s'" % self.line.split()[0] self.fm.notify(error, bad=True) - except Exception: - return None else: return command_class(self.line) diff --git a/ranger/gui/widgets/pager.py b/ranger/gui/widgets/pager.py index 2ecf65c0..bf7ca5f4 100644 --- a/ranger/gui/widgets/pager.py +++ b/ranger/gui/widgets/pager.py @@ -5,6 +5,8 @@ from __future__ import (absolute_import, division, print_function) +import curses + from ranger.gui import ansi from ranger.ext.direction import Direction from ranger.ext.img_display import ImgDisplayUnsupportedException @@ -99,7 +101,7 @@ class Pager(Widget): # pylint: disable=too-many-instance-attributes self.wid, self.hei) except ImgDisplayUnsupportedException: self.fm.settings.preview_images = False - except Exception as ex: + except Exception as ex: # pylint: disable=broad-except self.fm.notify(ex, bad=True) else: self.image_drawn = True @@ -110,7 +112,7 @@ class Pager(Widget): # pylint: disable=too-many-instance-attributes elif self.markup == 'ansi': try: self.win.move(i, 0) - except Exception: + except curses.error: pass else: for chunk in ansi.text_with_fg_bg_attr(line): diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py index c9133415..8e9e259e 100644 --- a/ranger/gui/widgets/statusbar.py +++ b/ranger/gui/widgets/statusbar.py @@ -10,6 +10,7 @@ such as the space used by all the files in this directory. from __future__ import (absolute_import, division, print_function) +import curses import os from os import getuid, readlink from pwd import getpwuid @@ -77,7 +78,7 @@ class StatusBar(Widget): # pylint: disable=too-many-instance-attributes self.fm.thisfile.load_if_outdated() try: ctime = self.fm.thisfile.stat.st_ctime - except Exception: + except AttributeError: ctime = -1 else: ctime = -1 @@ -131,7 +132,7 @@ class StatusBar(Widget): # pylint: disable=too-many-instance-attributes try: self.addnstr(0, starting_point, string, space_left) - except Exception: + except curses.error: break space_left -= len(string) starting_point += len(string) @@ -150,7 +151,7 @@ class StatusBar(Widget): # pylint: disable=too-many-instance-attributes return try: stat = target.stat - except Exception: + except AttributeError: return if stat is None: return @@ -172,7 +173,7 @@ class StatusBar(Widget): # pylint: disable=too-many-instance-attributes how = 'good' if target.exists else 'bad' try: dest = readlink(target.path) - except Exception: + except OSError: dest = '?' left.add(' -> ' + dest, 'link', how) else: diff --git a/ranger/gui/widgets/titlebar.py b/ranger/gui/widgets/titlebar.py index 425dd64c..a2c54516 100644 --- a/ranger/gui/widgets/titlebar.py +++ b/ranger/gui/widgets/titlebar.py @@ -74,10 +74,7 @@ class TitleBar(Widget): elif i == 2: self.fm.enter_dir("/") else: - try: - self.fm.enter_dir(part.directory) - except Exception: - pass + self.fm.enter_dir(part.directory) return True return False diff --git a/ranger/gui/widgets/view_base.py b/ranger/gui/widgets/view_base.py index 8807628b..5cdb2615 100644 --- a/ranger/gui/widgets/view_base.py +++ b/ranger/gui/widgets/view_base.py @@ -52,15 +52,15 @@ class ViewBase(Widget, DisplayableContainer): # pylint: disable=too-many-instan if self.pager is not None and self.pager.visible: try: self.fm.ui.win.move(self.main_column.y, self.main_column.x) - except Exception: + except curses.error: pass else: + col_x = self.main_column.x + col_y = self.main_column.y + self.main_column.target.pointer \ + - self.main_column.scroll_begin try: - col_x = self.main_column.x - col_y = self.main_column.y + self.main_column.target.pointer \ - - self.main_column.scroll_begin self.fm.ui.win.move(col_y, col_x) - except Exception: + except curses.error: pass def _draw_bookmarks(self): @@ -127,7 +127,7 @@ class ViewBase(Widget, DisplayableContainer): # pylint: disable=too-many-instan self.addnstr(ystart - 1, 0, "key command".ljust(self.wid), self.wid) try: self.win.chgat(ystart - 1, 0, curses.A_UNDERLINE) - except Exception: + except curses.error: pass whitespace = " " * self.wid i = ystart diff --git a/ranger/gui/widgets/view_miller.py b/ranger/gui/widgets/view_miller.py index 569b93fa..e79ade79 100644 --- a/ranger/gui/widgets/view_miller.py +++ b/ranger/gui/widgets/view_miller.py @@ -155,7 +155,7 @@ class ViewMiller(ViewBase): # pylint: disable=too-many-ancestors,too-many-insta self.addch(0, x, curses.ACS_TTEE, 0) self.addch(y, x, curses.ACS_BTEE, 0) # pylint: enable=no-member - except Exception: + except curses.error: # in case it's off the boundaries pass @@ -186,7 +186,7 @@ class ViewMiller(ViewBase): # pylint: disable=too-many-ancestors,too-many-insta self.fm.settings.use_preview_script: try: result = not self.fm.previews[target.realpath]['foundpreview'] - except Exception: + except KeyError: return self.old_collapse self.old_collapse = result |