diff options
author | Florian Bruhin <me@the-compiler.org> | 2021-05-19 13:15:09 +0200 |
---|---|---|
committer | Florian Bruhin <me@the-compiler.org> | 2021-05-19 13:15:09 +0200 |
commit | c01b47f27b46a8568096977363b38b01d138749c (patch) | |
tree | d0b47c3e9bebc757638f57a17a20e2cbc0332d15 | |
parent | 06e49efd3d9f21058893a0c3751aa05caaf0e2f8 (diff) | |
download | qutebrowser-c01b47f27b46a8568096977363b38b01d138749c.tar.gz qutebrowser-c01b47f27b46a8568096977363b38b01d138749c.zip |
mypy: Set disallow_any_generics
See #6100
25 files changed, 125 insertions, 69 deletions
@@ -3,7 +3,7 @@ python_version = 3.6 ### --strict warn_unused_configs = True -# disallow_any_generics = True +disallow_any_generics = True disallow_subclassing_any = True # disallow_untyped_calls = True # disallow_untyped_defs = True @@ -83,6 +83,10 @@ disallow_untyped_defs = True [mypy-qutebrowser.config.*] disallow_untyped_defs = True +[mypy-qutebrowser.config.configtypes] +# Needs some major work to use specific generics +disallow_any_generics = False + [mypy-qutebrowser.api.*] disallow_untyped_defs = True diff --git a/qutebrowser/api/cmdutils.py b/qutebrowser/api/cmdutils.py index 85a700c43..73c6a1bc5 100644 --- a/qutebrowser/api/cmdutils.py +++ b/qutebrowser/api/cmdutils.py @@ -105,6 +105,9 @@ def check_exclusive(flags: Iterable[bool], names: Iterable[str]) -> None: raise CommandError("Only one of {} can be given!".format(argstr)) +_CmdHandlerType = Callable[..., Any] + + class register: # noqa: N801,N806 pylint: disable=invalid-name """Decorator to register a new command handler.""" @@ -130,7 +133,7 @@ class register: # noqa: N801,N806 pylint: disable=invalid-name # The arguments to pass to Command. self._kwargs = kwargs - def __call__(self, func: Callable) -> Callable: + def __call__(self, func: _CmdHandlerType) -> _CmdHandlerType: """Register the command before running the function. Gets called when a function should be decorated. @@ -222,7 +225,7 @@ class argument: # noqa: N801,N806 pylint: disable=invalid-name self._argname = argname # The name of the argument to handle. self._kwargs = kwargs # Valid ArgInfo members. - def __call__(self, func: Callable) -> Callable: + def __call__(self, func: _CmdHandlerType) -> _CmdHandlerType: funcname = func.__name__ if self._argname not in inspect.signature(func).parameters: diff --git a/qutebrowser/api/hook.py b/qutebrowser/api/hook.py index eadc310f3..884d6c67f 100644 --- a/qutebrowser/api/hook.py +++ b/qutebrowser/api/hook.py @@ -22,13 +22,13 @@ """Hooks for extensions.""" import importlib -from typing import Callable +from typing import Callable, Any from qutebrowser.extensions import loader -def _add_module_info(func: Callable) -> loader.ModuleInfo: +def _add_module_info(func: Callable[..., Any]) -> loader.ModuleInfo: """Add module info to the given function.""" module = importlib.import_module(func.__module__) return loader.add_module_info(module) @@ -48,7 +48,7 @@ class init: message.info("Extension initialized.") """ - def __call__(self, func: Callable) -> Callable: + def __call__(self, func: loader.InitHookType) -> loader.InitHookType: info = _add_module_info(func) if info.init_hook is not None: raise ValueError("init hook is already registered!") @@ -86,7 +86,10 @@ class config_changed: def __init__(self, option_filter: str = None) -> None: self._filter = option_filter - def __call__(self, func: Callable) -> Callable: + def __call__( + self, + func: loader.ConfigChangedHookType, + ) -> loader.ConfigChangedHookType: info = _add_module_info(func) info.config_changed_hooks.append((self._filter, func)) return func diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index cbe698009..b3d1e85f7 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -34,9 +34,10 @@ from PyQt5.QtPrintSupport import QPrintDialog, QPrinter from PyQt5.QtNetwork import QNetworkAccessManager if TYPE_CHECKING: - from PyQt5.QtWebKit import QWebHistory + from PyQt5.QtWebKit import QWebHistory, QWebHistoryItem from PyQt5.QtWebKitWidgets import QWebPage - from PyQt5.QtWebEngineWidgets import QWebEngineHistory, QWebEnginePage + from PyQt5.QtWebEngineWidgets import ( + QWebEngineHistory, QWebEngineHistoryItem, QWebEnginePage) from qutebrowser.keyinput import modeman from qutebrowser.config import config @@ -634,8 +635,8 @@ class AbstractHistoryPrivate: """Deserialize from a format produced by self.serialize.""" raise NotImplementedError - def load_items(self, items: Sequence) -> None: - """Deserialize from a list of WebHistoryItems.""" + def load_items(self, items: Sequence[sessions.TabHistoryItem]) -> None: + """Deserialize from a list of TabHistoryItems.""" raise NotImplementedError @@ -651,7 +652,7 @@ class AbstractHistory: def __len__(self) -> int: raise NotImplementedError - def __iter__(self) -> Iterable: + def __iter__(self) -> Iterable[Union['QWebHistoryItem', 'QWebEngineHistoryItem']]: raise NotImplementedError def _check_count(self, count: int) -> None: diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index e9653ae19..8cd73ae4f 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -602,7 +602,7 @@ class CommandDispatcher: widget = self._current_widget() url = self._current_url() - handlers: Dict[str, Callable] = { + handlers: Dict[str, Callable[..., QUrl]] = { 'prev': functools.partial(navigate.prevnext, prev=True), 'next': functools.partial(navigate.prevnext, prev=False), 'up': navigate.path_up, diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index cfb238188..031b6fe06 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -92,7 +92,8 @@ class Redirect(Exception): # Return value: (mimetype, data) (encoded as utf-8 if a str is returned) _HandlerRet = Tuple[str, Union[str, bytes]] -_Handler = TypeVar('_Handler', bound=Callable[[QUrl], _HandlerRet]) +_HandlerCallable = Callable[[QUrl], _HandlerRet] +_Handler = TypeVar('_Handler', bound=_HandlerCallable) class add_handler: # noqa: N801,N806 pylint: disable=invalid-name @@ -105,7 +106,7 @@ class add_handler: # noqa: N801,N806 pylint: disable=invalid-name def __init__(self, name: str) -> None: self._name = name - self._function: Optional[Callable] = None + self._function: Optional[_HandlerCallable] = None def __call__(self, function: _Handler) -> _Handler: self._function = function diff --git a/qutebrowser/browser/webelem.py b/qutebrowser/browser/webelem.py index f53ad1afb..11c95e4cd 100644 --- a/qutebrowser/browser/webelem.py +++ b/qutebrowser/browser/webelem.py @@ -58,7 +58,7 @@ def css_selector(group: str, url: QUrl) -> str: return ','.join(selectors[group]) -class AbstractWebElement(collections.abc.MutableMapping): +class AbstractWebElement(collections.abc.MutableMapping[str, str]): """A wrapper around QtWebKit/QtWebEngine web element.""" diff --git a/qutebrowser/browser/webengine/tabhistory.py b/qutebrowser/browser/webengine/tabhistory.py index d6c795fb2..ab4b05fe9 100644 --- a/qutebrowser/browser/webengine/tabhistory.py +++ b/qutebrowser/browser/webengine/tabhistory.py @@ -35,10 +35,10 @@ HISTORY_STREAM_VERSION = 3 def _serialize_item(item, stream): - """Serialize a single WebHistoryItem into a QDataStream. + """Serialize a single TabHistoryItem into a QDataStream. Args: - item: The WebHistoryItem to write. + item: The TabHistoryItem to write. stream: The QDataStream to write to. """ # Thanks to Otter Browser: @@ -108,10 +108,10 @@ def _serialize_item(item, stream): def serialize(items): - """Serialize a list of WebHistoryItems to a data stream. + """Serialize a list of TabHistoryItems to a data stream. Args: - items: An iterable of WebHistoryItems. + items: An iterable of TabHistoryItems. Return: A (stream, data, user_data) tuple. diff --git a/qutebrowser/browser/webkit/tabhistory.py b/qutebrowser/browser/webkit/tabhistory.py index c38968b62..a707030d1 100644 --- a/qutebrowser/browser/webkit/tabhistory.py +++ b/qutebrowser/browser/webkit/tabhistory.py @@ -64,10 +64,10 @@ def _serialize_item(item): def serialize(items): - """Serialize a list of WebHistoryItems to a data stream. + """Serialize a list of TabHistoryItems to a data stream. Args: - items: An iterable of WebHistoryItems. + items: An iterable of TabHistoryItems. Return: A (stream, data, user_data) tuple. diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 69f3ca2cc..437a54a33 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -97,7 +97,10 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name else: return False - def __call__(self, func: Callable) -> Callable: + def __call__( + self, + func: Callable[..., None], + ) -> Callable[..., None]: """Filter calls to the decorated function. Gets called when a function should be decorated. @@ -105,7 +108,9 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name Adds a filter which returns if we're not interested in the change-event and calls the wrapped function if we are. - We assume the function passed doesn't take any parameters. + We assume the function passed doesn't take any parameters. However, it + could take a "self" argument, so we can't cleary express this in the + type above. Args: func: The function to be decorated. @@ -309,7 +314,7 @@ class Config(QObject): def _init_values(self) -> None: """Populate the self._values dict.""" - self._values: Mapping = {} + self._values: Mapping[str, configutils.Values] = {} for name, opt in configdata.DATA.items(): self._values[name] = configutils.Values(opt) diff --git a/qutebrowser/config/configcommands.py b/qutebrowser/config/configcommands.py index 2084556da..143b02fca 100644 --- a/qutebrowser/config/configcommands.py +++ b/qutebrowser/config/configcommands.py @@ -21,7 +21,7 @@ import os.path import contextlib -from typing import TYPE_CHECKING, Iterator, List, Optional +from typing import TYPE_CHECKING, Iterator, List, Optional, Any, Tuple from PyQt5.QtCore import QUrl @@ -475,7 +475,7 @@ class ConfigCommands: raise cmdutils.CommandError("{} already exists - use --force to " "overwrite!".format(filename)) - options: List = [] + options: List[Tuple[Optional[urlmatch.UrlPattern], configdata.Option, Any]] = [] if defaults: options = [(None, opt, opt.default) for _name, opt in sorted(configdata.DATA.items())] diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py index a3320c5c1..6f0d0b13c 100644 --- a/qutebrowser/config/configfiles.py +++ b/qutebrowser/config/configfiles.py @@ -30,7 +30,7 @@ import configparser import contextlib import re from typing import (TYPE_CHECKING, Any, Dict, Iterable, Iterator, List, Mapping, - MutableMapping, Optional, cast) + MutableMapping, Optional, Tuple, cast) import yaml from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QSettings, qVersion @@ -302,18 +302,18 @@ class YamlConfig(QObject): self._validate_names(settings) self._build_values(settings) - def _load_settings_object(self, yaml_data: Any) -> '_SettingsType': + def _load_settings_object(self, yaml_data: Any) -> _SettingsType: """Load the settings from the settings: key.""" return self._pop_object(yaml_data, 'settings', dict) - def _load_legacy_settings_object(self, yaml_data: Any) -> '_SettingsType': + def _load_legacy_settings_object(self, yaml_data: Any) -> _SettingsType: data = self._pop_object(yaml_data, 'global', dict) settings = {} for name, value in data.items(): settings[name] = {'global': value} return settings - def _build_values(self, settings: Mapping) -> None: + def _build_values(self, settings: Mapping[str, Any]) -> None: """Build up self._values from the values in the given dict.""" errors = [] for name, yaml_values in settings.items(): @@ -740,9 +740,17 @@ class ConfigPyWriter: def __init__( self, - options: List, + options: List[ + Tuple[ + Optional[urlmatch.UrlPattern], + configdata.Option, + Any + ] + ], bindings: MutableMapping[str, Mapping[str, Optional[str]]], - *, commented: bool) -> None: + *, + commented: bool, + ) -> None: self._options = options self._bindings = bindings self._commented = commented diff --git a/qutebrowser/config/websettings.py b/qutebrowser/config/websettings.py index 896f7639c..7556d2b6d 100644 --- a/qutebrowser/config/websettings.py +++ b/qutebrowser/config/websettings.py @@ -85,7 +85,11 @@ class AttributeInfo: """Info about a settings attribute.""" - def __init__(self, *attributes: Any, converter: Callable = None) -> None: + def __init__( + self, + *attributes: Any, + converter: Callable[[Any], bool] = None, + ) -> None: self.attributes = attributes if converter is None: self.converter = lambda val: val diff --git a/qutebrowser/extensions/loader.py b/qutebrowser/extensions/loader.py index 9b704c94d..7ae45023b 100644 --- a/qutebrowser/extensions/loader.py +++ b/qutebrowser/extensions/loader.py @@ -39,6 +39,9 @@ from qutebrowser.misc import objects # ModuleInfo objects for all loaded plugins _module_infos = [] +InitHookType = Callable[['InitContext'], None] +ConfigChangedHookType = Callable[[], None] + @dataclasses.dataclass class InitContext: @@ -59,9 +62,13 @@ class ModuleInfo: """ skip_hooks: bool = False - init_hook: Optional[Callable] = None - config_changed_hooks: List[Tuple[Optional[str], Callable]] = dataclasses.field( - default_factory=list) + init_hook: Optional[InitHookType] = None + config_changed_hooks: List[ + Tuple[ + Optional[str], + ConfigChangedHookType, + ] + ] = dataclasses.field(default_factory=list) @dataclasses.dataclass diff --git a/qutebrowser/keyinput/basekeyparser.py b/qutebrowser/keyinput/basekeyparser.py index d1828791c..7e688dab1 100644 --- a/qutebrowser/keyinput/basekeyparser.py +++ b/qutebrowser/keyinput/basekeyparser.py @@ -112,7 +112,7 @@ class BindingTrie: return lines - def update(self, mapping: Mapping) -> None: + def update(self, mapping: Mapping[keyutils.KeySequence, str]) -> None: """Add data from the given mapping to the trie.""" for key in mapping: self[key] = mapping[key] diff --git a/qutebrowser/keyinput/keyutils.py b/qutebrowser/keyinput/keyutils.py index ddf818708..6bd8c99b8 100644 --- a/qutebrowser/keyinput/keyutils.py +++ b/qutebrowser/keyinput/keyutils.py @@ -458,7 +458,7 @@ class KeySequence: assert self self._validate() - def _convert_key(self, key: Qt.Key) -> int: + def _convert_key(self, key: Union[int, Qt.KeyboardModifiers]) -> int: """Convert a single key for QKeySequence.""" assert isinstance(key, (int, Qt.KeyboardModifiers)), key return int(key) diff --git a/qutebrowser/misc/debugcachestats.py b/qutebrowser/misc/debugcachestats.py index f172f0854..2004ad7ab 100644 --- a/qutebrowser/misc/debugcachestats.py +++ b/qutebrowser/misc/debugcachestats.py @@ -30,7 +30,7 @@ from typing import Any, Callable, List, Optional, Tuple, TypeVar _CACHE_FUNCTIONS: List[Tuple[str, Any]] = [] -_T = TypeVar('_T', bound=Callable) +_T = TypeVar('_T', bound=Callable[..., Any]) def register(name: Optional[str] = None) -> Callable[[_T], _T]: diff --git a/qutebrowser/misc/elf.py b/qutebrowser/misc/elf.py index 307d3b4ac..bf824880a 100644 --- a/qutebrowser/misc/elf.py +++ b/qutebrowser/misc/elf.py @@ -65,7 +65,7 @@ import re import dataclasses import mmap import pathlib -from typing import IO, ClassVar, Dict, Optional, Tuple, cast +from typing import Any, IO, ClassVar, Dict, Optional, Tuple, cast from PyQt5.QtCore import QLibraryInfo @@ -93,7 +93,7 @@ class Endianness(enum.Enum): big = 2 -def _unpack(fmt: str, fobj: IO[bytes]) -> Tuple: +def _unpack(fmt: str, fobj: IO[bytes]) -> Tuple[Any, ...]: """Unpack the given struct format from the given file.""" size = struct.calcsize(fmt) data = _safe_read(fobj, size) diff --git a/qutebrowser/misc/throttle.py b/qutebrowser/misc/throttle.py index 1beebe1aa..ac565b68d 100644 --- a/qutebrowser/misc/throttle.py +++ b/qutebrowser/misc/throttle.py @@ -45,7 +45,7 @@ class Throttle(QObject): """ def __init__(self, - func: Callable, + func: Callable[..., None], delay_ms: int, parent: QObject = None) -> None: """Constructor. diff --git a/qutebrowser/utils/debug.py b/qutebrowser/utils/debug.py index 54fcd5aa9..7d069909a 100644 --- a/qutebrowser/utils/debug.py +++ b/qutebrowser/utils/debug.py @@ -35,7 +35,7 @@ from qutebrowser.misc import objects from qutebrowser.qt import sip -def log_events(klass: Type) -> Type: +def log_events(klass: Type[QObject]) -> Type[QObject]: """Class decorator to log Qt events.""" old_event = klass.event @@ -46,7 +46,7 @@ def log_events(klass: Type) -> Type: qenum_key(QEvent, e.type()))) return old_event(self, e) - klass.event = new_event + klass.event = new_event # type: ignore[assignment] return klass @@ -96,10 +96,13 @@ def log_signals(obj: QObject) -> QObject: return obj -def qenum_key(base: Type, - value: Union[int, sip.simplewrapper], +_EnumValueType = Union[sip.simplewrapper, int] + + +def qenum_key(base: Type[_EnumValueType], + value: _EnumValueType, add_base: bool = False, - klass: Type = None) -> str: + klass: Type[_EnumValueType] = None) -> str: """Convert a Qt Enum value to its key as a string. Args: @@ -119,8 +122,9 @@ def qenum_key(base: Type, raise TypeError("Can't guess enum class of an int!") try: - idx = base.staticMetaObject.indexOfEnumerator(klass.__name__) - meta_enum = base.staticMetaObject.enumerator(idx) + meta_obj = base.staticMetaObject # type: ignore[union-attr] + idx = meta_obj.indexOfEnumerator(klass.__name__) + meta_enum = meta_obj.enumerator(idx) ret = meta_enum.valueToKey(int(value)) # type: ignore[arg-type] except AttributeError: ret = None @@ -139,10 +143,10 @@ def qenum_key(base: Type, return ret -def qflags_key(base: Type, - value: Union[int, sip.simplewrapper], +def qflags_key(base: Type[_EnumValueType], + value: _EnumValueType, add_base: bool = False, - klass: Type = None) -> str: + klass: Type[_EnumValueType] = None) -> str: """Convert a Qt QFlags value to its keys as string. Note: Passing a combined value (such as Qt.AlignCenter) will get the names @@ -220,7 +224,7 @@ def signal_name(sig: pyqtBoundSignal) -> str: return m.group('name') -def format_args(args: Sequence = None, kwargs: Mapping = None) -> str: +def format_args(args: Sequence[Any] = None, kwargs: Mapping[str, Any] = None) -> str: """Format a list of arguments/kwargs to a function-call like string.""" if args is not None: arglist = [utils.compact_text(repr(arg), 200) for arg in args] @@ -245,9 +249,9 @@ def dbg_signal(sig: pyqtBoundSignal, args: Any) -> str: return '{}({})'.format(signal_name(sig), format_args(args)) -def format_call(func: Callable, - args: Sequence = None, - kwargs: Mapping = None, +def format_call(func: Callable[..., Any], + args: Sequence[Any] = None, + kwargs: Mapping[str, Any] = None, full: bool = True) -> str: """Get a string representation of a function calls with the given args. @@ -302,7 +306,7 @@ class log_time: # noqa: N801,N806 pylint: disable=invalid-name self._logger.debug("{} took {} seconds.".format( self._action.capitalize(), delta)) - def __call__(self, func: Callable) -> Callable: + def __call__(self, func: Callable[..., Any]) -> Callable[..., Any]: @functools.wraps(func) def wrapped(*args: Any, **kwargs: Any) -> Any: """Call the original function.""" diff --git a/qutebrowser/utils/docutils.py b/qutebrowser/utils/docutils.py index 202fcba95..89e799c89 100644 --- a/qutebrowser/utils/docutils.py +++ b/qutebrowser/utils/docutils.py @@ -25,7 +25,7 @@ import inspect import os.path import collections import enum -from typing import Callable, MutableMapping, Optional, List, Union +from typing import Any, Callable, MutableMapping, Optional, List, Union import qutebrowser from qutebrowser.utils import log, utils @@ -88,7 +88,7 @@ class DocstringParser: arg_inside = enum.auto() misc = enum.auto() - def __init__(self, func: Callable) -> None: + def __init__(self, func: Callable[..., Any]) -> None: """Constructor. Args: diff --git a/qutebrowser/utils/objreg.py b/qutebrowser/utils/objreg.py index 99d8a0936..0819a5d0a 100644 --- a/qutebrowser/utils/objreg.py +++ b/qutebrowser/utils/objreg.py @@ -55,7 +55,8 @@ class CommandOnlyError(Exception): _IndexType = Union[str, int] -class ObjectRegistry(collections.UserDict): +# UserDict is only generic in Python 3.9+ +class ObjectRegistry(collections.UserDict): # type: ignore[type-arg] """A registry of long-living objects in qutebrowser. diff --git a/qutebrowser/utils/qtutils.py b/qutebrowser/utils/qtutils.py index 01234a42b..ff8983c50 100644 --- a/qutebrowser/utils/qtutils.py +++ b/qutebrowser/utils/qtutils.py @@ -31,7 +31,8 @@ Module attributes: import io import operator import contextlib -from typing import TYPE_CHECKING, BinaryIO, IO, Iterator, Optional, Union, Tuple, cast +from typing import (Any, AnyStr, TYPE_CHECKING, BinaryIO, IO, Iterator, + Optional, Union, Tuple, cast) from PyQt5.QtCore import (qVersion, QEventLoop, QDataStream, QByteArray, QIODevice, QFileDevice, QSaveFile, QT_VERSION_STR, @@ -227,7 +228,7 @@ def savefile_open( filename: str, binary: bool = False, encoding: str = 'utf-8' -) -> Iterator[IO]: +) -> Iterator[IO[AnyStr]]: """Context manager to easily use a QSaveFile.""" f = QSaveFile(filename) cancelled = False @@ -239,7 +240,7 @@ def savefile_open( dev = cast(BinaryIO, PyQIODevice(f)) if binary: - new_f: IO = dev + new_f: IO[Any] = dev # FIXME:mypy Why doesn't AnyStr work? else: new_f = io.TextIOWrapper(dev, encoding=encoding) @@ -298,7 +299,11 @@ class PyQIODevice(io.BufferedIOBase): if not self.writable(): raise OSError("Trying to write to unwritable file!") - def open(self, mode: QIODevice.OpenMode) -> contextlib.closing: + # contextlib.closing is only generic in Python 3.9+ + def open( + self, + mode: QIODevice.OpenMode, + ) -> contextlib.closing: # type: ignore[type-arg] """Open the underlying device and ensure opening succeeded. Raises OSError if opening failed. diff --git a/qutebrowser/utils/urlmatch.py b/qutebrowser/utils/urlmatch.py index 8dfd6d273..f14c2083d 100644 --- a/qutebrowser/utils/urlmatch.py +++ b/qutebrowser/utils/urlmatch.py @@ -104,7 +104,14 @@ class UrlPattern: self._init_path(parsed) self._init_port(parsed) - def _to_tuple(self) -> Tuple: + def _to_tuple(self) -> Tuple[ + bool, # _match_all + bool, # _match_subdomains + Optional[str], # _scheme + Optional[str], # host + Optional[str], # _path + Optional[int], # _port + ]: """Get a pattern with information used for __eq__/__hash__.""" return (self._match_all, self._match_subdomains, self._scheme, self.host, self._path, self._port) diff --git a/qutebrowser/utils/utils.py b/qutebrowser/utils/utils.py index 56ebe45c4..fb0165de2 100644 --- a/qutebrowser/utils/utils.py +++ b/qutebrowser/utils/utils.py @@ -341,7 +341,7 @@ class prevent_exceptions: # noqa: N801,N806 pylint: disable=invalid-name self._retval = retval self._predicate = predicate - def __call__(self, func: Callable) -> Callable: + def __call__(self, func: Callable[..., Any]) -> Callable[..., Any]: """Called when a function should be decorated. Args: @@ -447,7 +447,7 @@ def qualname(obj: Any) -> str: _ExceptionType = Union[Type[BaseException], Tuple[Type[BaseException]]] -def raises(exc: _ExceptionType, func: Callable, *args: Any) -> bool: +def raises(exc: _ExceptionType, func: Callable[..., Any], *args: Any) -> bool: """Check if a function raises a given exception. Args: @@ -725,7 +725,10 @@ def yaml_dump(data: Any, f: IO[str] = None) -> Optional[str]: return yaml_data.decode('utf-8') -def chunk(elems: Sequence, n: int) -> Iterator[Sequence]: +_T = TypeVar('_T') + + +def chunk(elems: Sequence[_T], n: int) -> Iterator[Sequence[_T]]: """Yield successive n-sized chunks from elems. If elems % n != 0, the last chunk will be smaller. |