Пример #1
0
def whitelist_generator():
    """Generator which yields lines to add to a vulture whitelist."""
    # qutebrowser commands
    for cmd in cmdutils.cmd_dict.values():
        yield utils.qualname(cmd.handler)

    # pyPEG2 classes
    for name, member in inspect.getmembers(rfc6266, inspect.isclass):
        for attr in ('grammar', 'regex'):
            if hasattr(member, attr):
                yield 'qutebrowser.browser.rfc6266.{}.{}'.format(name, attr)

    # PyQt properties
    for attr in ('prompt_active', 'command_active', 'insert_active',
                 'caret_mode'):
        yield 'qutebrowser.mainwindow.statusbar.bar.StatusBar.' + attr
    yield 'qutebrowser.mainwindow.statusbar.url.UrlText.urltype'

    # Not used yet, but soon (or when debugging)
    yield 'qutebrowser.config.configtypes.Regex'
    yield 'qutebrowser.utils.debug.log_events'
    yield 'qutebrowser.utils.debug.log_signals'
    yield 'qutebrowser.utils.debug.qflags_key'
    yield 'qutebrowser.utils.qtutils.QtOSError.qt_errno'
    yield 'qutebrowser.utils.usertypes.NeighborList.firstitem'
    yield 'scripts.utils.bg_colors'
    yield 'scripts.utils.print_subtitle'

    # Qt attributes
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().baseUrl'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().content'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().encoding'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().fileNames'
    yield 'PyQt5.QtGui.QAbstractTextDocumentLayout.PaintContext().clip'
    yield 'PyQt5.QtWidgets.QStyleOptionViewItem.backgroundColor'

    # Globals
    # https://bitbucket.org/jendrikseipp/vulture/issues/10/
    yield 'qutebrowser.misc.utilcmds.pyeval_output'
    yield 'utils.use_color'

    # Other false-positives
    yield ('qutebrowser.completion.models.sortfilter.CompletionFilterModel().'
           'lessThan')
    yield 'qutebrowser.utils.jinja.Loader.get_source'
    yield 'qutebrowser.utils.log.VDEBUG'
    yield 'qutebrowser.utils.log.QtWarningFilter.filter'
    yield 'logging.LogRecord.log_color'

    for attr in ('fileno', 'truncate', 'closed', 'readable'):
        yield 'qutebrowser.utils.qtutils.PyQIODevice.' + attr

    for attr in ('priority', 'visit_callfunc'):
        yield 'scripts.dev.pylint_checkers.config.' + attr

    yield 'scripts.dev.pylint_checkers.modeline.process_module'

    for attr in ('_get_default_metavar_for_optional',
                 '_get_default_metavar_for_positional', '_metavar_formatter'):
        yield 'scripts.dev.src2asciidoc.UsageFormatter.' + attr
Пример #2
0
def _get_name(exc):
    """Get a suitable exception name as a string."""
    prefixes = ['qutebrowser', 'builtins']
    name = utils.qualname(exc.__class__)
    for prefix in prefixes:
        if name.startswith(prefix):
            name = name[len(prefix) + 1:]
            break
    return name
Пример #3
0
    def _handle_keypress(self,
                         event: QKeyEvent,
                         *,
                         dry_run: bool = False) -> bool:
        """Handle filtering of KeyPress events.

        Args:
            event: The KeyPress to examine.
            dry_run: Don't actually handle the key, only filter it.

        Return:
            True if event should be filtered, False otherwise.
        """
        curmode = self.mode
        parser = self.parsers[curmode]
        if curmode != usertypes.KeyMode.insert:
            log.modes.debug(
                "got keypress in mode {} - delegating to {}".format(
                    utils.pyenum_str(curmode), utils.qualname(parser)))
        match = parser.handle(event, dry_run=dry_run)

        has_modifier = event.modifiers() not in [
            Qt.NoModifier,
            Qt.ShiftModifier,
        ]  # type: ignore[comparison-overlap]
        is_non_alnum = has_modifier or not event.text().strip()

        forward_unbound_keys = config.cache['input.forward_unbound_keys']

        if match:
            filter_this = True
        elif (parser.passthrough or forward_unbound_keys == 'all'
              or (forward_unbound_keys == 'auto' and is_non_alnum)):
            filter_this = False
        else:
            filter_this = True

        if not filter_this and not dry_run:
            self._releaseevents_to_pass.add(KeyEvent.from_event(event))

        if curmode != usertypes.KeyMode.insert:
            focus_widget = objects.qapp.focusWidget()
            log.modes.debug("match: {}, forward_unbound_keys: {}, "
                            "passthrough: {}, is_non_alnum: {}, dry_run: {} "
                            "--> filter: {} (focused: {!r})".format(
                                match, forward_unbound_keys,
                                parser.passthrough, is_non_alnum, dry_run,
                                filter_this, focus_widget))
        return filter_this
Пример #4
0
def format_call(func, args=None, kwargs=None, full=True):
    """Get a string representation of a function calls with the given args.

    Args:
        func: The callable to print.
        args: A list of positional arguments.
        kwargs: A dict of named arguments.
        full: Whether to print the full name

    Return:
        A string with the function call.
    """
    if full:
        name = utils.qualname(func)
    else:
        name = func.__name__
    return '{}({})'.format(name, format_args(args, kwargs))
Пример #5
0
def format_call(func, args=None, kwargs=None, full=True):
    """Get a string representation of a function calls with the given args.

    Args:
        func: The callable to print.
        args: A list of positional arguments.
        kwargs: A dict of named arguments.
        full: Whether to print the full name

    Return:
        A string with the function call.
    """
    if full:
        name = utils.qualname(func)
    else:
        name = func.__name__
    return '{}({})'.format(name, format_args(args, kwargs))
Пример #6
0
    def __init__(self, func: typing.Callable) -> None:
        """Constructor.

        Args:
            func: The function to parse the docstring for.
        """
        self._state = self.State.short
        self._cur_arg_name = None  # type: typing.Optional[str]
        self._short_desc_parts = []  # type: typing.List[str]
        self._long_desc_parts = []  # type: typing.List[str]
        self.arg_descs = collections.OrderedDict(
        )  # type: typing.Dict[str, typing.Union[str, typing.List[str]]]
        doc = inspect.getdoc(func)
        handlers = {
            self.State.short: self._parse_short,
            self.State.desc: self._parse_desc,
            self.State.desc_hidden: self._skip,
            self.State.arg_start: self._parse_arg_start,
            self.State.arg_inside: self._parse_arg_inside,
            self.State.misc: self._skip,
        }
        if doc is None:
            if sys.flags.optimize < 2:
                log.commands.warning(
                    "Function {}() from {} has no docstring".format(
                        utils.qualname(func),
                        # https://github.com/python/typeshed/pull/3295
                        inspect.getsourcefile(func)))  # type: ignore
            self.long_desc = ""
            self.short_desc = ""
            return
        for line in doc.splitlines():
            handler = handlers[self._state]
            stop = handler(line)
            if stop:
                break
        for k, v in self.arg_descs.items():
            desc = ' '.join(v)
            desc = re.sub(r', or None($|\.)', r'\1', desc)
            desc = re.sub(r', or None', r', or not given', desc)
            self.arg_descs[k] = desc
        self.long_desc = ' '.join(self._long_desc_parts)
        self.short_desc = ' '.join(self._short_desc_parts)
Пример #7
0
    def _handle_keypress(self, event, *, dry_run=False):
        """Handle filtering of KeyPress events.

        Args:
            event: The KeyPress to examine.
            dry_run: Don't actually handle the key, only filter it.

        Return:
            True if event should be filtered, False otherwise.
        """
        curmode = self.mode
        parser = self._parsers[curmode]
        if curmode != usertypes.KeyMode.insert:
            log.modes.debug("got keypress in mode {} - delegating to "
                            "{}".format(curmode, utils.qualname(parser)))
        match = parser.handle(event, dry_run=dry_run)

        is_non_alnum = (event.modifiers()
                        not in [Qt.NoModifier, Qt.ShiftModifier]
                        or not event.text().strip())

        forward_unbound_keys = config.val.input.forward_unbound_keys

        if match:
            filter_this = True
        elif (parser.passthrough or forward_unbound_keys == 'all'
              or (forward_unbound_keys == 'auto' and is_non_alnum)):
            filter_this = False
        else:
            filter_this = True

        if not filter_this and not dry_run:
            self._releaseevents_to_pass.add(KeyEvent.from_event(event))

        if curmode != usertypes.KeyMode.insert:
            focus_widget = QApplication.instance().focusWidget()
            log.modes.debug("match: {}, forward_unbound_keys: {}, "
                            "passthrough: {}, is_non_alnum: {}, dry_run: {} "
                            "--> filter: {} (focused: {!r})".format(
                                match, forward_unbound_keys,
                                parser.passthrough, is_non_alnum, dry_run,
                                filter_this, focus_widget))
        return filter_this
Пример #8
0
    def _handle_keypress(self, event, *, dry_run=False):
        """Handle filtering of KeyPress events.

        Args:
            event: The KeyPress to examine.
            dry_run: Don't actually handle the key, only filter it.

        Return:
            True if event should be filtered, False otherwise.
        """
        curmode = self.mode
        parser = self._parsers[curmode]
        if curmode != usertypes.KeyMode.insert:
            log.modes.debug("got keypress in mode {} - delegating to "
                            "{}".format(curmode, utils.qualname(parser)))
        match = parser.handle(event, dry_run=dry_run)

        is_non_alnum = (
            event.modifiers() not in [Qt.NoModifier, Qt.ShiftModifier] or
            not event.text().strip())

        forward_unbound_keys = config.val.input.forward_unbound_keys

        if match:
            filter_this = True
        elif (parser.passthrough or forward_unbound_keys == 'all' or
              (forward_unbound_keys == 'auto' and is_non_alnum)):
            filter_this = False
        else:
            filter_this = True

        if not filter_this and not dry_run:
            self._releaseevents_to_pass.add(KeyEvent.from_event(event))

        if curmode != usertypes.KeyMode.insert:
            focus_widget = QApplication.instance().focusWidget()
            log.modes.debug("match: {}, forward_unbound_keys: {}, "
                            "passthrough: {}, is_non_alnum: {}, dry_run: {} "
                            "--> filter: {} (focused: {!r})".format(
                                match, forward_unbound_keys,
                                parser.passthrough, is_non_alnum, dry_run,
                                filter_this, focus_widget))
        return filter_this
Пример #9
0
    def _eventFilter_keypress(self, event):
        """Handle filtering of KeyPress events.

        Args:
            event: The KeyPress to examine.

        Return:
            True if event should be filtered, False otherwise.
        """
        curmode = self.mode
        parser = self._parsers[curmode]
        if curmode != usertypes.KeyMode.insert:
            log.modes.debug("got keypress in mode {} - delegating to "
                            "{}".format(curmode, utils.qualname(parser)))
        handled = parser.handle(event)

        is_non_alnum = (event.modifiers()
                        not in (Qt.NoModifier, Qt.ShiftModifier)
                        or not event.text().strip())
        focus_widget = QApplication.instance().focusWidget()
        is_tab = event.key() in (Qt.Key_Tab, Qt.Key_Backtab)

        if handled:
            filter_this = True
        elif is_tab and not isinstance(focus_widget, QWebView):
            filter_this = True
        elif (parser.passthrough or self._forward_unbound_keys == 'all'
              or (self._forward_unbound_keys == 'auto' and is_non_alnum)):
            filter_this = False
        else:
            filter_this = True

        if not filter_this:
            self._releaseevents_to_pass.add(KeyEvent(event))

        if curmode != usertypes.KeyMode.insert:
            log.modes.debug("handled: {}, forward-unbound-keys: {}, "
                            "passthrough: {}, is_non_alnum: {}, is_tab {} --> "
                            "filter: {} (focused: {!r})".format(
                                handled, self._forward_unbound_keys,
                                parser.passthrough, is_non_alnum, is_tab,
                                filter_this, focus_widget))
        return filter_this
Пример #10
0
    def _eventFilter_keypress(self, event):
        """Handle filtering of KeyPress events.

        Args:
            event: The KeyPress to examine.

        Return:
            True if event should be filtered, False otherwise.
        """
        curmode = self.mode
        handler = self._handlers[curmode]
        if curmode != usertypes.KeyMode.insert:
            log.modes.debug("got keypress in mode {} - calling handler "
                            "{}".format(curmode, utils.qualname(handler)))
        handled = handler(event) if handler is not None else False

        is_non_alnum = bool(event.modifiers()) or not event.text().strip()
        focus_widget = QApplication.instance().focusWidget()
        is_tab = event.key() in (Qt.Key_Tab, Qt.Key_Backtab)

        if handled:
            filter_this = True
        elif is_tab and not isinstance(focus_widget, QWebView):
            filter_this = True
        elif (curmode in self.passthrough or
                self._forward_unbound_keys == 'all' or
                (self._forward_unbound_keys == 'auto' and is_non_alnum)):
            filter_this = False
        else:
            filter_this = True

        if not filter_this:
            self._releaseevents_to_pass.add(KeyEvent(event))

        if curmode != usertypes.KeyMode.insert:
            log.modes.debug("handled: {}, forward-unbound-keys: {}, "
                            "passthrough: {}, is_non_alnum: {}, is_tab {} --> "
                            "filter: {} (focused: {!r})".format(
                                handled, self._forward_unbound_keys,
                                curmode in self.passthrough, is_non_alnum,
                                is_tab, filter_this, focus_widget))
        return filter_this
Пример #11
0
    def __init__(self, func: Callable[..., Any]) -> None:
        """Constructor.

        Args:
            func: The function to parse the docstring for.
        """
        self._state = self.State.short
        self._cur_arg_name: Optional[str] = None
        self._short_desc_parts: List[str] = []
        self._long_desc_parts: List[str] = []
        self.arg_descs: MutableMapping[
            str, Union[str, List[str]]] = collections.OrderedDict()
        doc = inspect.getdoc(func)
        handlers = {
            self.State.short: self._parse_short,
            self.State.desc: self._parse_desc,
            self.State.desc_hidden: self._skip,
            self.State.arg_start: self._parse_arg_start,
            self.State.arg_inside: self._parse_arg_inside,
            self.State.misc: self._skip,
        }
        if doc is None:
            if sys.flags.optimize < 2:
                log.commands.warning(
                    "Function {}() from {} has no docstring".format(
                        utils.qualname(func),
                        inspect.getsourcefile(func)))
            self.long_desc = ""
            self.short_desc = ""
            return
        for line in doc.splitlines():
            handler = handlers[self._state]
            stop = handler(line)
            if stop:
                break
        for k, v in self.arg_descs.items():
            desc = ' '.join(v)
            desc = re.sub(r', or None($|\.)', r'\1', desc)
            desc = re.sub(r', or None', r', or not given', desc)
            self.arg_descs[k] = desc
        self.long_desc = ' '.join(self._long_desc_parts)
        self.short_desc = ' '.join(self._short_desc_parts)
Пример #12
0
    def __init__(self, func):
        """Constructor.

        Args:
            func: The function to parse the docstring for.
        """
        self._state = self.State.short
        self._cur_arg_name = None
        self._short_desc_parts = []
        self._long_desc_parts = []
        self.arg_descs = collections.OrderedDict()
        doc = inspect.getdoc(func)
        handlers = {
            self.State.short: self._parse_short,
            self.State.desc: self._parse_desc,
            self.State.desc_hidden: self._skip,
            self.State.arg_start: self._parse_arg_start,
            self.State.arg_inside: self._parse_arg_inside,
            self.State.misc: self._skip,
        }
        if doc is None:
            if sys.flags.optimize < 2:
                log.commands.warning(
                    "Function {}() from {} has no docstring".format(
                        utils.qualname(func),
                        inspect.getsourcefile(func)))
            self.long_desc = ""
            self.short_desc = ""
            return
        for line in doc.splitlines():
            handler = handlers[self._state]
            stop = handler(line)
            if stop:
                break
        for k, v in self.arg_descs.items():
            desc = ' '.join(v)
            desc = re.sub(r', or None($|\.)', r'\1', desc)
            desc = re.sub(r', or None', r', or not given', desc)
            self.arg_descs[k] = desc
        self.long_desc = ' '.join(self._long_desc_parts)
        self.short_desc = ' '.join(self._short_desc_parts)
Пример #13
0
    def _eventFilter_keypress(self, event):
        """Handle filtering of KeyPress events.

        Args:
            event: The KeyPress to examine.

        Return:
            True if event should be filtered, False otherwise.
        """
        curmode = self.mode
        parser = self._parsers[curmode]
        if curmode != usertypes.KeyMode.insert:
            log.modes.debug("got keypress in mode {} - delegating to "
                            "{}".format(curmode, utils.qualname(parser)))
        handled = parser.handle(event)

        is_non_alnum = (
            event.modifiers() not in (Qt.NoModifier, Qt.ShiftModifier) or
            not event.text().strip())

        if handled:
            filter_this = True
        elif (parser.passthrough or
                self._forward_unbound_keys == 'all' or
                (self._forward_unbound_keys == 'auto' and is_non_alnum)):
            filter_this = False
        else:
            filter_this = True

        if not filter_this:
            self._releaseevents_to_pass.add(KeyEvent(event))

        if curmode != usertypes.KeyMode.insert:
            focus_widget = QApplication.instance().focusWidget()
            log.modes.debug("handled: {}, forward-unbound-keys: {}, "
                            "passthrough: {}, is_non_alnum: {} --> "
                            "filter: {} (focused: {!r})".format(
                                handled, self._forward_unbound_keys,
                                parser.passthrough, is_non_alnum,
                                filter_this, focus_widget))
        return filter_this
Пример #14
0
    def _eventFilter_keypress(self, event):
        """Handle filtering of KeyPress events.

        Args:
            event: The KeyPress to examine.

        Return:
            True if event should be filtered, False otherwise.
        """
        curmode = self.mode
        handler = self._handlers[curmode]
        if curmode != usertypes.KeyMode.insert:
            log.modes.debug("got keypress in mode {} - calling handler "
                            "{}".format(curmode, utils.qualname(handler)))
        handled = handler(event) if handler is not None else False

        is_non_alnum = bool(event.modifiers()) or not event.text().strip()

        if handled:
            filter_this = True
        elif (curmode in self.passthrough or
                self._forward_unbound_keys == 'all' or
                (self._forward_unbound_keys == 'auto' and is_non_alnum)):
            filter_this = False
        else:
            filter_this = True

        if not filter_this:
            self._releaseevents_to_pass.append(event)

        if curmode != usertypes.KeyMode.insert:
            log.modes.debug("handled: {}, forward-unbound-keys: {}, "
                            "passthrough: {}, is_non_alnum: {} --> filter: "
                            "{} (focused: {!r})".format(
                                handled, self._forward_unbound_keys,
                                curmode in self.passthrough,
                                is_non_alnum, filter_this,
                                QApplication.instance().focusWidget()))
        return filter_this
Пример #15
0
 def new_event(self: Any, e: QEvent) -> bool:
     """Wrapper for event() which logs events."""
     log.misc.debug("Event in {}: {}".format(utils.qualname(klass),
                                             qenum_key(QEvent, e.type())))
     return old_event(self, e)
Пример #16
0
 def _shutdown(self, status):  # noqa
     """Second stage of shutdown."""
     # pylint: disable=too-many-branches, too-many-statements
     # FIXME refactor this
     # https://github.com/The-Compiler/qutebrowser/issues/113
     log.destroy.debug("Stage 2 of shutting down...")
     # Remove eventfilter
     try:
         log.destroy.debug("Removing eventfilter...")
         self.removeEventFilter(self._event_filter)
     except AttributeError:
         pass
     # Close all windows
     QApplication.closeAllWindows()
     # Shut down IPC
     try:
         objreg.get('ipc-server').shutdown()
     except KeyError:
         pass
     # Save everything
     try:
         config_obj = objreg.get('config')
     except KeyError:
         log.destroy.debug("Config not initialized yet, so not saving "
                           "anything.")
     else:
         to_save = []
         if config.get('general', 'auto-save-config'):
             to_save.append(("config", config_obj.save))
             try:
                 key_config = objreg.get('key-config')
             except KeyError:
                 pass
             else:
                 to_save.append(("keyconfig", key_config.save))
         to_save += [("window geometry", self._save_geometry)]
         try:
             command_history = objreg.get('command-history')
         except KeyError:
             pass
         else:
             to_save.append(("command history", command_history.save))
         try:
             quickmark_manager = objreg.get('quickmark-manager')
         except KeyError:
             pass
         else:
             to_save.append(("command history", quickmark_manager.save))
         try:
             state_config = objreg.get('state-config')
         except KeyError:
             pass
         else:
             to_save.append(("window geometry", state_config.save))
         try:
             cookie_jar = objreg.get('cookie-jar')
         except KeyError:
             pass
         else:
             to_save.append(("cookies", cookie_jar.save))
         for what, handler in to_save:
             log.destroy.debug("Saving {} (handler: {})".format(
                 what, utils.qualname(handler)))
             try:
                 handler()
             except AttributeError as e:
                 log.destroy.warning("Could not save {}.".format(what))
                 log.destroy.debug(e)
     # Re-enable faulthandler to stdout, then remove crash log
     log.destroy.debug("Deactiving crash log...")
     self._destroy_crashlogfile()
     # If we don't kill our custom handler here we might get segfaults
     log.destroy.debug("Deactiving message handler...")
     qInstallMessageHandler(None)
     # Now we can hopefully quit without segfaults
     log.destroy.debug("Deferring QApplication::exit...")
     # We use a singleshot timer to exit here to minimize the likelyhood of
     # segfaults.
     QTimer.singleShot(0, functools.partial(self.exit, status))
Пример #17
0
def whitelist_generator():  # noqa: C901
    """Generator which yields lines to add to a vulture whitelist."""
    loader.load_components(skip_hooks=True)

    # qutebrowser commands
    for cmd in objects.commands.values():
        yield utils.qualname(cmd.handler)

    # PyQt properties
    yield 'qutebrowser.mainwindow.statusbar.bar.StatusBar.color_flags'
    yield 'qutebrowser.mainwindow.statusbar.url.UrlText.urltype'

    # Not used yet, but soon (or when debugging)
    yield 'qutebrowser.utils.debug.log_events'
    yield 'qutebrowser.utils.debug.log_signals'
    yield 'qutebrowser.utils.debug.qflags_key'
    yield 'qutebrowser.utils.qtutils.QtOSError.qt_errno'
    yield 'scripts.utils.bg_colors'
    yield 'qutebrowser.misc.sql.SqliteErrorCode.CONSTRAINT'
    yield 'qutebrowser.misc.throttle.Throttle.set_delay'

    # Qt attributes
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().baseUrl'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().content'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().encoding'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().fileNames'
    yield 'PyQt5.QtWidgets.QStyleOptionViewItem.backgroundColor'

    ## qute://... handlers
    for name in qutescheme._HANDLERS:  # pylint: disable=protected-access
        name = name.replace('-', '_')
        yield 'qutebrowser.browser.qutescheme.qute_' + name

    # Other false-positives
    yield 'qutebrowser.completion.models.listcategory.ListCategory().lessThan'
    yield 'qutebrowser.utils.jinja.Loader.get_source'
    yield 'qutebrowser.utils.log.QtWarningFilter.filter'
    yield 'qutebrowser.browser.pdfjs.is_available'
    yield 'qutebrowser.misc.guiprocess.spawn_output'
    yield 'qutebrowser.utils.usertypes.ExitStatus.reserved'
    yield 'QEvent.posted'
    yield 'log_stack'  # from message.py
    yield 'propagate'  # logging.getLogger('...).propagate = False
    # vulture doesn't notice the hasattr() and thus thinks netrc_used is unused
    # in NetworkManager.on_authentication_required
    yield 'PyQt5.QtNetwork.QNetworkReply.netrc_used'
    yield 'qutebrowser.browser.downloads.last_used_directory'
    yield 'PaintContext.clip'  # from completiondelegate.py
    yield 'logging.LogRecord.log_color'  # from logging.py
    yield 'scripts.utils.use_color'  # from asciidoc2html.py
    for attr in ['pyeval_output', 'log_clipboard', 'fake_clipboard']:
        yield 'qutebrowser.misc.utilcmds.' + attr

    for attr in ['fileno', 'truncate', 'closed', 'readable']:
        yield 'qutebrowser.utils.qtutils.PyQIODevice.' + attr

    for attr in ['msgs', 'priority', 'visit_attribute']:
        yield 'scripts.dev.pylint_checkers.config.' + attr
    for attr in ['visit_call', 'process_module']:
        yield 'scripts.dev.pylint_checkers.modeline.' + attr

    for name, _member in inspect.getmembers(configtypes, inspect.isclass):
        yield 'qutebrowser.config.configtypes.' + name
    yield 'qutebrowser.config.configexc.ConfigErrorDesc.traceback'
    yield 'qutebrowser.config.configfiles.ConfigAPI.load_autoconfig'
    yield 'types.ModuleType.c'  # configfiles:read_config_py
    for name in ['configdir', 'datadir']:
        yield 'qutebrowser.config.configfiles.ConfigAPI.' + name

    yield 'include_aliases'

    for attr in [
            '_get_default_metavar_for_optional',
            '_get_default_metavar_for_positional', '_metavar_formatter'
    ]:
        yield 'scripts.dev.src2asciidoc.UsageFormatter.' + attr

    for dist in version.Distribution:
        yield 'qutebrowser.utils.version.Distribution.{}'.format(dist.name)

    # attrs
    yield 'qutebrowser.browser.webkit.network.networkmanager.ProxyId.hostname'
    yield 'qutebrowser.command.command.ArgInfo._validate_exclusive'
    yield 'scripts.get_coredumpctl_traces.Line.uid'
    yield 'scripts.get_coredumpctl_traces.Line.gid'
    yield 'scripts.importer.import_moz_places.places.row_factory'

    # component hooks
    yield 'qutebrowser.components.hostblock.on_lists_changed'
    yield 'qutebrowser.components.braveadblock.on_lists_changed'
    yield 'qutebrowser.components.hostblock.on_method_changed'
    yield 'qutebrowser.components.braveadblock.on_method_changed'

    # used in type comments
    yield 'pending_download_type'
    yield 'world_id_type'
    yield 'ParserDictType'
    yield 'qutebrowser.config.configutils.Values._VmapKeyType'

    # ELF
    yield 'qutebrowser.misc.elf.Endianness.big'
    for name in ['phoff', 'ehsize', 'phentsize', 'phnum']:
        yield f'qutebrowser.misc.elf.Header.{name}'
    for name in ['addr', 'addralign', 'entsize']:
        yield f'qutebrowser.misc.elf.SectionHeader.{name}'
Пример #18
0
def whitelist_generator():
    """Generator which yields lines to add to a vulture whitelist."""
    # qutebrowser commands
    for cmd in cmdutils.cmd_dict.values():
        yield utils.qualname(cmd.handler)

    # pyPEG2 classes
    for name, member in inspect.getmembers(rfc6266, inspect.isclass):
        for attr in ['grammar', 'regex']:
            if hasattr(member, attr):
                yield 'qutebrowser.browser.webkit.rfc6266.{}.{}'.format(
                    name, attr)

    # PyQt properties
    for attr in [
            'prompt_active', 'command_active', 'insert_active', 'caret_mode'
    ]:
        yield 'qutebrowser.mainwindow.statusbar.bar.StatusBar.' + attr
    yield 'qutebrowser.mainwindow.statusbar.url.UrlText.urltype'

    # Not used yet, but soon (or when debugging)
    yield 'qutebrowser.utils.debug.log_events'
    yield 'qutebrowser.utils.debug.log_signals'
    yield 'qutebrowser.utils.debug.qflags_key'
    yield 'qutebrowser.utils.qtutils.QtOSError.qt_errno'
    yield 'scripts.utils.bg_colors'
    yield 'qutebrowser.browser.webelem.AbstractWebElement.style_property'
    yield 'qutebrowser.config.configtypes.Float'

    # Qt attributes
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().baseUrl'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().content'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().encoding'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().fileNames'
    yield 'PyQt5.QtWidgets.QStyleOptionViewItem.backgroundColor'

    # qute:... handlers
    for func in qutescheme.HANDLERS.values():
        yield 'qutebrowser.browser.webkit.network.qutescheme.' + func.__name__

    # Other false-positives
    yield ('qutebrowser.completion.models.sortfilter.CompletionFilterModel().'
           'lessThan')
    yield 'qutebrowser.utils.jinja.Loader.get_source'
    yield 'qutebrowser.utils.log.QtWarningFilter.filter'
    yield 'qutebrowser.browser.pdfjs.is_available'
    # vulture doesn't notice the hasattr() and thus thinks netrc_used is unused
    # in NetworkManager.on_authentication_required
    yield 'PyQt5.QtNetwork.QNetworkReply.netrc_used'

    for attr in ['fileno', 'truncate', 'closed', 'readable']:
        yield 'qutebrowser.utils.qtutils.PyQIODevice.' + attr

    for attr in ['priority', 'visit_call']:
        yield 'scripts.dev.pylint_checkers.config.' + attr

    yield 'scripts.dev.pylint_checkers.modeline.process_module'

    for attr in [
            '_get_default_metavar_for_optional',
            '_get_default_metavar_for_positional', '_metavar_formatter'
    ]:
        yield 'scripts.dev.src2asciidoc.UsageFormatter.' + attr
Пример #19
0
 def _shutdown(self, status):  # noqa
     """Second stage of shutdown."""
     # pylint: disable=too-many-branches, too-many-statements
     # FIXME refactor this
     # https://github.com/The-Compiler/qutebrowser/issues/113
     log.destroy.debug("Stage 2 of shutting down...")
     # Remove eventfilter
     try:
         log.destroy.debug("Removing eventfilter...")
         self.removeEventFilter(self._event_filter)
     except AttributeError:
         pass
     # Close all windows
     QApplication.closeAllWindows()
     # Shut down IPC
     try:
         objreg.get('ipc-server').shutdown()
     except KeyError:
         pass
     # Save everything
     try:
         config_obj = objreg.get('config')
     except KeyError:
         log.destroy.debug("Config not initialized yet, so not saving "
                           "anything.")
     else:
         to_save = []
         if config.get('general', 'auto-save-config'):
             to_save.append(("config", config_obj.save))
             try:
                 key_config = objreg.get('key-config')
             except KeyError:
                 pass
             else:
                 to_save.append(("keyconfig", key_config.save))
         to_save += [("window geometry", self._save_geometry)]
         try:
             command_history = objreg.get('command-history')
         except KeyError:
             pass
         else:
             to_save.append(("command history", command_history.save))
         try:
             quickmark_manager = objreg.get('quickmark-manager')
         except KeyError:
             pass
         else:
             to_save.append(("command history", quickmark_manager.save))
         try:
             state_config = objreg.get('state-config')
         except KeyError:
             pass
         else:
             to_save.append(("window geometry", state_config.save))
         try:
             cookie_jar = objreg.get('cookie-jar')
         except KeyError:
             pass
         else:
             to_save.append(("cookies", cookie_jar.save))
         for what, handler in to_save:
             log.destroy.debug("Saving {} (handler: {})".format(
                 what, utils.qualname(handler)))
             try:
                 handler()
             except AttributeError as e:
                 log.destroy.warning("Could not save {}.".format(what))
                 log.destroy.debug(e)
     # Re-enable faulthandler to stdout, then remove crash log
     log.destroy.debug("Deactiving crash log...")
     self._destroy_crashlogfile()
     # If we don't kill our custom handler here we might get segfaults
     log.destroy.debug("Deactiving message handler...")
     qInstallMessageHandler(None)
     # Now we can hopefully quit without segfaults
     log.destroy.debug("Deferring QApplication::exit...")
     # We use a singleshot timer to exit here to minimize the likelyhood of
     # segfaults.
     QTimer.singleShot(0, functools.partial(self.exit, status))
Пример #20
0
def whitelist_generator():
    """Generator which yields lines to add to a vulture whitelist."""
    # qutebrowser commands
    for cmd in cmdutils.cmd_dict.values():
        yield utils.qualname(cmd.handler)

    # pyPEG2 classes
    for name, member in inspect.getmembers(rfc6266, inspect.isclass):
        for attr in ('grammar', 'regex'):
            if hasattr(member, attr):
                yield 'qutebrowser.browser.webkit.rfc6266.{}.{}'.format(name, attr)

    # PyQt properties
    for attr in ('prompt_active', 'command_active', 'insert_active',
                 'caret_mode'):
        yield 'qutebrowser.mainwindow.statusbar.bar.StatusBar.' + attr
    yield 'qutebrowser.mainwindow.statusbar.url.UrlText.urltype'

    # Not used yet, but soon (or when debugging)
    yield 'qutebrowser.config.configtypes.Regex'
    yield 'qutebrowser.utils.debug.log_events'
    yield 'qutebrowser.utils.debug.log_signals'
    yield 'qutebrowser.utils.debug.qflags_key'
    yield 'qutebrowser.utils.qtutils.QtOSError.qt_errno'
    yield 'qutebrowser.utils.usertypes.NeighborList.firstitem'
    yield 'scripts.utils.bg_colors'
    yield 'scripts.utils.print_subtitle'

    # Qt attributes
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().baseUrl'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().content'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().encoding'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().fileNames'
    yield 'PyQt5.QtGui.QAbstractTextDocumentLayout.PaintContext().clip'
    yield 'PyQt5.QtWidgets.QStyleOptionViewItem.backgroundColor'

    # qute:... handlers
    for func in qutescheme.HANDLERS.values():
        yield 'qutebrowser.browser.webkit.network.qutescheme.' + func.__name__

    # Globals
    # https://bitbucket.org/jendrikseipp/vulture/issues/10/
    yield 'qutebrowser.misc.utilcmds.pyeval_output'
    yield 'utils.use_color'
    yield 'qutebrowser.browser.webkit.mhtml.last_used_directory'
    yield 'qutebrowser.utils.utils.fake_clipboard'
    yield 'qutebrowser.utils.utils.log_clipboard'

    # Other false-positives
    yield ('qutebrowser.completion.models.sortfilter.CompletionFilterModel().'
           'lessThan')
    yield 'qutebrowser.utils.jinja.Loader.get_source'
    yield 'qutebrowser.utils.log.VDEBUG'
    yield 'qutebrowser.utils.log.QtWarningFilter.filter'
    yield 'logging.LogRecord.log_color'
    yield 'qutebrowser.browser.pdfjs.is_available'
    # vulture doesn't notice the hasattr() and thus thinks netrc_used is unused
    # in NetworkManager.on_authentication_required
    yield 'PyQt5.QtNetwork.QNetworkReply.netrc_used'

    for attr in ('fileno', 'truncate', 'closed', 'readable'):
        yield 'qutebrowser.utils.qtutils.PyQIODevice.' + attr

    for attr in ('priority', 'visit_call'):
        yield 'scripts.dev.pylint_checkers.config.' + attr

    yield 'scripts.dev.pylint_checkers.modeline.process_module'

    for attr in ('_get_default_metavar_for_optional',
                 '_get_default_metavar_for_positional', '_metavar_formatter'):
        yield 'scripts.dev.src2asciidoc.UsageFormatter.' + attr
Пример #21
0
 def new_event(self, e, *args, **kwargs):
     """Wrapper for event() which logs events."""
     log.misc.debug("Event in {}: {}".format(utils.qualname(klass),
                                             qenum_key(QEvent, e.type())))
     return old_event(self, e, *args, **kwargs)
Пример #22
0
def whitelist_generator():
    """Generator which yields lines to add to a vulture whitelist."""
    # qutebrowser commands
    for cmd in cmdutils.cmd_dict.values():
        yield utils.qualname(cmd.handler)

    # pyPEG2 classes
    for name, member in inspect.getmembers(rfc6266, inspect.isclass):
        for attr in ['grammar', 'regex']:
            if hasattr(member, attr):
                yield 'qutebrowser.browser.webkit.rfc6266.{}.{}'.format(name,
                                                                        attr)

    # PyQt properties
    yield 'qutebrowser.mainwindow.statusbar.bar.StatusBar.color_flags'
    yield 'qutebrowser.mainwindow.statusbar.url.UrlText.urltype'

    # Not used yet, but soon (or when debugging)
    yield 'qutebrowser.utils.debug.log_events'
    yield 'qutebrowser.utils.debug.log_signals'
    yield 'qutebrowser.utils.debug.qflags_key'
    yield 'qutebrowser.utils.qtutils.QtOSError.qt_errno'
    yield 'scripts.utils.bg_colors'
    yield 'qutebrowser.config.configtypes.Float'

    # Qt attributes
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().baseUrl'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().content'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().encoding'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().fileNames'
    yield 'PyQt5.QtWidgets.QStyleOptionViewItem.backgroundColor'

    ## qute://... handlers
    for name in qutescheme._HANDLERS:  # pylint: disable=protected-access
        yield 'qutebrowser.browser.qutescheme.qute_' + name

    # Other false-positives
    yield ('qutebrowser.completion.models.sortfilter.CompletionFilterModel().'
           'lessThan')
    yield 'qutebrowser.utils.jinja.Loader.get_source'
    yield 'qutebrowser.utils.log.QtWarningFilter.filter'
    yield 'qutebrowser.browser.pdfjs.is_available'
    yield 'QEvent.posted'
    yield 'log_stack'  # from message.py
    yield 'propagate'  # logging.getLogger('...).propagate = False
    # vulture doesn't notice the hasattr() and thus thinks netrc_used is unused
    # in NetworkManager.on_authentication_required
    yield 'PyQt5.QtNetwork.QNetworkReply.netrc_used'

    for attr in ['fileno', 'truncate', 'closed', 'readable']:
        yield 'qutebrowser.utils.qtutils.PyQIODevice.' + attr

    for attr in ['priority', 'visit_call']:
        yield 'scripts.dev.pylint_checkers.config.' + attr

    yield 'scripts.dev.pylint_checkers.modeline.process_module'
    yield 'scripts.dev.pylint_checkers.qute_pylint.config.msgs'

    for attr in ['_get_default_metavar_for_optional',
                 '_get_default_metavar_for_positional', '_metavar_formatter']:
        yield 'scripts.dev.src2asciidoc.UsageFormatter.' + attr
Пример #23
0
 def new_event(self, e, *args, **kwargs):
     """Wrapper for event() which logs events."""
     log.misc.debug("Event in {}: {}".format(utils.qualname(klass),
                                             qenum_key(QEvent, e.type())))
     return old_event(self, e, *args, **kwargs)
Пример #24
0
def whitelist_generator():
    """Generator which yields lines to add to a vulture whitelist."""
    # qutebrowser commands
    for cmd in cmdutils.cmd_dict.values():
        yield utils.qualname(cmd.handler)

    # pyPEG2 classes
    for name, member in inspect.getmembers(rfc6266, inspect.isclass):
        for attr in ['grammar', 'regex']:
            if hasattr(member, attr):
                yield 'qutebrowser.browser.webkit.rfc6266.{}.{}'.format(
                    name, attr)

    # PyQt properties
    yield 'qutebrowser.mainwindow.statusbar.bar.StatusBar.color_flags'
    yield 'qutebrowser.mainwindow.statusbar.url.UrlText.urltype'

    # Not used yet, but soon (or when debugging)
    yield 'qutebrowser.utils.debug.log_events'
    yield 'qutebrowser.utils.debug.log_signals'
    yield 'qutebrowser.utils.debug.qflags_key'
    yield 'qutebrowser.utils.qtutils.QtOSError.qt_errno'
    yield 'scripts.utils.bg_colors'

    # Qt attributes
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().baseUrl'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().content'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().encoding'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().fileNames'
    yield 'PyQt5.QtWidgets.QStyleOptionViewItem.backgroundColor'

    ## qute://... handlers
    for name in qutescheme._HANDLERS:  # pylint: disable=protected-access
        name = name.replace('-', '_')
        yield 'qutebrowser.browser.qutescheme.qute_' + name

    # Other false-positives
    yield 'qutebrowser.completion.models.listcategory.ListCategory().lessThan'
    yield 'qutebrowser.utils.jinja.Loader.get_source'
    yield 'qutebrowser.utils.log.QtWarningFilter.filter'
    yield 'qutebrowser.browser.pdfjs.is_available'
    yield 'QEvent.posted'
    yield 'log_stack'  # from message.py
    yield 'propagate'  # logging.getLogger('...).propagate = False
    # vulture doesn't notice the hasattr() and thus thinks netrc_used is unused
    # in NetworkManager.on_authentication_required
    yield 'PyQt5.QtNetwork.QNetworkReply.netrc_used'
    yield 'qutebrowser.browser.downloads.last_used_directory'
    yield 'PaintContext.clip'  # from completiondelegate.py
    yield 'logging.LogRecord.log_color'  # from logging.py
    yield 'scripts.utils.use_color'  # from asciidoc2html.py
    for attr in ['pyeval_output', 'log_clipboard', 'fake_clipboard']:
        yield 'qutebrowser.misc.utilcmds.' + attr

    for attr in ['fileno', 'truncate', 'closed', 'readable']:
        yield 'qutebrowser.utils.qtutils.PyQIODevice.' + attr

    for attr in ['msgs', 'priority', 'visit_attribute']:
        yield 'scripts.dev.pylint_checkers.config.' + attr
    for attr in ['visit_call', 'process_module']:
        yield 'scripts.dev.pylint_checkers.modeline.' + attr

    for name, member in inspect.getmembers(configtypes, inspect.isclass):
        yield 'qutebrowser.config.configtypes.' + name
    yield 'qutebrowser.config.configexc.ConfigErrorDesc.traceback'
    yield 'qutebrowser.config.configfiles.ConfigAPI.load_autoconfig'
    yield 'types.ModuleType.c'  # configfiles:read_config_py

    yield 'include_aliases'

    for attr in [
            '_get_default_metavar_for_optional',
            '_get_default_metavar_for_positional', '_metavar_formatter'
    ]:
        yield 'scripts.dev.src2asciidoc.UsageFormatter.' + attr

    # attrs
    yield 'qutebrowser.browser.webkit.network.networkmanager.ProxyId.hostname'
    yield 'qutebrowser.command.command.ArgInfo._validate_exclusive'
    yield 'scripts.get_coredumpctl_traces.Line.uid'
    yield 'scripts.get_coredumpctl_traces.Line.gid'
Пример #25
0
def whitelist_generator():  # noqa
    """Generator which yields lines to add to a vulture whitelist."""
    # qutebrowser commands
    for cmd in cmdutils.cmd_dict.values():
        yield utils.qualname(cmd.handler)

    # pyPEG2 classes
    for name, member in inspect.getmembers(rfc6266, inspect.isclass):
        for attr in ['grammar', 'regex']:
            if hasattr(member, attr):
                yield 'qutebrowser.browser.webkit.rfc6266.{}.{}'.format(name,
                                                                        attr)

    # PyQt properties
    yield 'qutebrowser.mainwindow.statusbar.bar.StatusBar.color_flags'
    yield 'qutebrowser.mainwindow.statusbar.url.UrlText.urltype'

    # Not used yet, but soon (or when debugging)
    yield 'qutebrowser.utils.debug.log_events'
    yield 'qutebrowser.utils.debug.log_signals'
    yield 'qutebrowser.utils.debug.qflags_key'
    yield 'qutebrowser.utils.qtutils.QtOSError.qt_errno'
    yield 'scripts.utils.bg_colors'
    yield 'qutebrowser.misc.sql.SqliteErrorCode.CONSTRAINT'

    # Qt attributes
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().baseUrl'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().content'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().encoding'
    yield 'PyQt5.QtWebKit.QWebPage.ErrorPageExtensionReturn().fileNames'
    yield 'PyQt5.QtWidgets.QStyleOptionViewItem.backgroundColor'

    ## qute://... handlers
    for name in qutescheme._HANDLERS:  # pylint: disable=protected-access
        name = name.replace('-', '_')
        yield 'qutebrowser.browser.qutescheme.qute_' + name

    # Other false-positives
    yield 'qutebrowser.completion.models.listcategory.ListCategory().lessThan'
    yield 'qutebrowser.utils.jinja.Loader.get_source'
    yield 'qutebrowser.utils.log.QtWarningFilter.filter'
    yield 'qutebrowser.browser.pdfjs.is_available'
    yield 'qutebrowser.misc.guiprocess.spawn_output'
    yield 'QEvent.posted'
    yield 'log_stack'  # from message.py
    yield 'propagate'  # logging.getLogger('...).propagate = False
    # vulture doesn't notice the hasattr() and thus thinks netrc_used is unused
    # in NetworkManager.on_authentication_required
    yield 'PyQt5.QtNetwork.QNetworkReply.netrc_used'
    yield 'qutebrowser.browser.downloads.last_used_directory'
    yield 'PaintContext.clip'  # from completiondelegate.py
    yield 'logging.LogRecord.log_color'  # from logging.py
    yield 'scripts.utils.use_color'  # from asciidoc2html.py
    for attr in ['pyeval_output', 'log_clipboard', 'fake_clipboard']:
        yield 'qutebrowser.misc.utilcmds.' + attr

    for attr in ['fileno', 'truncate', 'closed', 'readable']:
        yield 'qutebrowser.utils.qtutils.PyQIODevice.' + attr

    for attr in ['msgs', 'priority', 'visit_attribute']:
        yield 'scripts.dev.pylint_checkers.config.' + attr
    for attr in ['visit_call', 'process_module']:
        yield 'scripts.dev.pylint_checkers.modeline.' + attr

    for name, _member in inspect.getmembers(configtypes, inspect.isclass):
        yield 'qutebrowser.config.configtypes.' + name
    yield 'qutebrowser.config.configexc.ConfigErrorDesc.traceback'
    yield 'qutebrowser.config.configfiles.ConfigAPI.load_autoconfig'
    yield 'types.ModuleType.c'  # configfiles:read_config_py
    for name in ['configdir', 'datadir']:
        yield 'qutebrowser.config.configfiles.ConfigAPI.' + name

    yield 'include_aliases'

    for attr in ['_get_default_metavar_for_optional',
                 '_get_default_metavar_for_positional', '_metavar_formatter']:
        yield 'scripts.dev.src2asciidoc.UsageFormatter.' + attr

    # attrs
    yield 'qutebrowser.browser.webkit.network.networkmanager.ProxyId.hostname'
    yield 'qutebrowser.command.command.ArgInfo._validate_exclusive'
    yield 'scripts.get_coredumpctl_traces.Line.uid'
    yield 'scripts.get_coredumpctl_traces.Line.gid'
    yield 'scripts.importer.import_moz_places.places.row_factory'