fixed ruff issues: UP007,UP045,PYI026

This commit is contained in:
Teddy 2025-10-31 13:21:13 +01:00
parent 897fc40f4d
commit e8f0178938
98 changed files with 433 additions and 444 deletions

View File

@ -102,7 +102,7 @@ class _CmdHandlerType(Protocol):
Below, we cast the decorated function to _CmdHandlerType to make mypy aware of this.
"""
qute_args: Optional[dict[str, 'command.ArgInfo']]
qute_args: dict[str, 'command.ArgInfo'] | None
def __call__(self, *args: Any, **kwargs: Any) -> Any:
...

View File

@ -234,7 +234,7 @@ def process_pos_args(args, via_ipc=False, cwd=None, target_arg=None):
if command_target in {'window', 'private-window'}:
command_target = 'tab-silent'
window: Optional[mainwindow.MainWindow] = None
window: mainwindow.MainWindow | None = None
if via_ipc and (not args or args == ['']):
window = mainwindow.get_window(via_ipc=via_ipc, target=new_window_target)
@ -296,7 +296,7 @@ def open_url(url, target=None, no_raise=False, via_ipc=True):
return window
def _open_startpage(window: Optional[mainwindow.MainWindow] = None) -> None:
def _open_startpage(window: mainwindow.MainWindow | None = None) -> None:
"""Open startpage.
The startpage is never opened if the given windows are not empty.

View File

@ -125,13 +125,13 @@ class TabData:
viewing_source: bool = False
inspector: Optional['AbstractWebInspector'] = None
open_target: usertypes.ClickTarget = usertypes.ClickTarget.normal
override_target: Optional[usertypes.ClickTarget] = None
override_target: usertypes.ClickTarget | None = None
pinned: bool = False
fullscreen: bool = False
netrc_used: bool = False
input_mode: usertypes.KeyMode = usertypes.KeyMode.normal
last_navigation: Optional[usertypes.NavigationRequest] = None
splitter: Optional[miscwidgets.InspectorSplitter] = None
last_navigation: usertypes.NavigationRequest | None = None
splitter: miscwidgets.InspectorSplitter | None = None
def should_show_icon(self) -> bool:
return (config.val.tabs.favicons.show == 'always' or
@ -225,7 +225,7 @@ class AbstractPrinting(QObject):
super().__init__(parent)
self._widget = cast(_WidgetType, None)
self._tab = tab
self._dialog: Optional[QPrintDialog] = None
self._dialog: QPrintDialog | None = None
self.printing_finished.connect(self._on_printing_finished)
self.pdf_printing_finished.connect(self._on_pdf_printing_finished)
@ -373,7 +373,7 @@ class AbstractSearch(QObject):
super().__init__(parent)
self._tab = tab
self._widget = cast(_WidgetType, None)
self.text: Optional[str] = None
self.text: str | None = None
self.search_displayed = False
self.match = SearchMatch()
@ -878,7 +878,7 @@ class AbstractTabPrivate:
self._tab = tab
self._mode_manager = mode_manager
def event_target(self) -> Optional[QWidget]:
def event_target(self) -> QWidget | None:
"""Return the widget events should be sent to."""
raise NotImplementedError
@ -913,7 +913,7 @@ class AbstractTabPrivate:
def clear_ssl_errors(self) -> None:
raise NotImplementedError
def networkaccessmanager(self) -> Optional[QNetworkAccessManager]:
def networkaccessmanager(self) -> QNetworkAccessManager | None:
"""Get the QNetworkAccessManager for this tab.
This is only implemented for QtWebKit.
@ -943,7 +943,7 @@ class AbstractTabPrivate:
self._tab.data.inspector = None
self.toggle_inspector(inspector.Position.window)
def toggle_inspector(self, position: Optional[inspector.Position]) -> None:
def toggle_inspector(self, position: inspector.Position | None) -> None:
"""Show/hide (and if needed, create) the web inspector for this tab."""
tabdata = self._tab.data
if tabdata.inspector is None:
@ -1056,7 +1056,7 @@ class AbstractTab(QWidget):
self._load_status = usertypes.LoadStatus.none
self._tab_event_filter = eventfilter.TabEventFilter(
self, parent=self)
self.backend: Optional[usertypes.Backend] = None
self.backend: usertypes.Backend | None = None
# If true, this tab has been requested to be removed (or is removed).
self.pending_removal = False
@ -1270,7 +1270,7 @@ class AbstractTab(QWidget):
self,
code: str,
callback: Callable[[Any], None] = None, *,
world: Union[usertypes.JsWorld, int] = None
world: usertypes.JsWorld | int = None
) -> None:
"""Run javascript async.
@ -1298,7 +1298,7 @@ class AbstractTab(QWidget):
self.data.pinned = pinned
self.pinned_changed.emit(pinned)
def renderer_process_pid(self) -> Optional[int]:
def renderer_process_pid(self) -> int | None:
"""Get the PID of the underlying renderer process.
Returns None if the PID can't be determined or if getting the PID isn't
@ -1306,7 +1306,7 @@ class AbstractTab(QWidget):
"""
raise NotImplementedError
def grab_pixmap(self, rect: QRect = None) -> Optional[QPixmap]:
def grab_pixmap(self, rect: QRect = None) -> QPixmap | None:
"""Grab a QPixmap of the displayed page.
Returns None if we got a null pixmap from Qt.

View File

@ -105,7 +105,7 @@ class CommandDispatcher:
background: bool = False,
window: bool = False,
related: bool = False,
private: Optional[bool] = None,
private: bool | None = None,
) -> None:
"""Helper function to open a page.
@ -511,10 +511,10 @@ class CommandDispatcher:
tab: bool,
bg: bool,
window: bool,
count: Optional[int],
count: int | None,
forward: bool,
quiet: bool,
index: Optional[int],
index: int | None,
) -> None:
"""Helper function for :back/:forward."""
history = self._current_widget().history
@ -975,7 +975,7 @@ class CommandDispatcher:
@cmdutils.argument('index', choices=['last', 'stack-next', 'stack-prev'],
completion=miscmodels.tab_focus)
@cmdutils.argument('count', value=cmdutils.Value.count)
def tab_focus(self, index: Union[str, int] = None,
def tab_focus(self, index: str | int = None,
count: int = None, no_last: bool = False) -> None:
"""Select the tab given as argument/[count].
@ -1022,7 +1022,7 @@ class CommandDispatcher:
@cmdutils.register(instance="command-dispatcher", scope="window")
@cmdutils.argument("index", choices=["+", "-", "start", "end"])
@cmdutils.argument("count", value=cmdutils.Value.count)
def tab_move(self, index: Union[str, int] = None, count: int = None) -> None:
def tab_move(self, index: str | int = None, count: int = None) -> None:
"""Move the current tab according to the argument and [count].
If neither is given, move it to the first position.
@ -1702,7 +1702,7 @@ class CommandDispatcher:
url: bool = False,
quiet: bool = False,
*,
world: Union[usertypes.JsWorld, int] = None) -> None:
world: usertypes.JsWorld | int = None) -> None:
"""Evaluate a JavaScript string.
Args:

View File

@ -35,7 +35,7 @@ class ModelRole(enum.IntEnum):
# Remember the last used directory
last_used_directory: Optional[str] = None
last_used_directory: str | None = None
# All REFRESH_INTERVAL milliseconds, speeds will be recalculated and downloads
# redrawn.
@ -221,7 +221,7 @@ def suggested_fn_from_title(url_path, title=None):
ext_whitelist = [".html", ".htm", ".php", ""]
_, ext = os.path.splitext(url_path)
suggested_fn: Optional[str] = None
suggested_fn: str | None = None
if ext.lower() in ext_whitelist and title:
suggested_fn = utils.sanitize_filename(title, shorten=True)
if not suggested_fn.lower().endswith((".html", ".htm")):
@ -451,14 +451,10 @@ class AbstractDownloadItem(QObject):
self.basename = '???'
self.successful = False
self.fileobj: Union[
UnsupportedAttribute, IO[bytes], None
] = UnsupportedAttribute()
self.raw_headers: Union[
UnsupportedAttribute, dict[bytes, bytes]
] = UnsupportedAttribute()
self.fileobj: UnsupportedAttribute | IO[bytes] | None = UnsupportedAttribute()
self.raw_headers: UnsupportedAttribute | dict[bytes, bytes] = UnsupportedAttribute()
self._filename: Optional[str] = None
self._filename: str | None = None
self._dead = False
def __repr__(self):

View File

@ -17,10 +17,7 @@ from qutebrowser.utils import qtutils, utils
_ActionListType = MutableSequence[
Union[
tuple[None, None], # separator
tuple[str, Callable[[], None]],
]
tuple[None, None] | tuple[str, Callable[[], None]]
]
@ -67,7 +64,7 @@ class DownloadView(QListView):
def __repr__(self):
model = qtutils.add_optional(self.model())
count: Union[int, str]
count: int | str
if model is None:
count = 'None'
else:

View File

@ -232,7 +232,7 @@ class LoadResults:
names = '\n'.join(str(script) for script in sorted(self.successful, key=str))
return f"Loaded Greasemonkey scripts:\n\n{names}"
def error_str(self) -> Optional[str]:
def error_str(self) -> str | None:
"""Get a string with all errors during script loading.
This can be used e.g. for a message.error() call.

View File

@ -187,9 +187,9 @@ class HintContext:
all_labels: list[HintLabel] = dataclasses.field(default_factory=list)
labels: dict[str, HintLabel] = dataclasses.field(default_factory=dict)
to_follow: Optional[str] = None
to_follow: str | None = None
first_run: bool = True
filterstr: Optional[str] = None
filterstr: str | None = None
def get_args(self, urlstr: str) -> Sequence[str]:
"""Get the arguments, with {hint-url} replaced by the given URL."""
@ -394,7 +394,7 @@ class HintManager(QObject):
"""Constructor."""
super().__init__(parent)
self._win_id = win_id
self._context: Optional[HintContext] = None
self._context: HintContext | None = None
self._word_hinter = WordHinter()
self._actions = HintActions(win_id)
@ -587,7 +587,7 @@ class HintManager(QObject):
raise cmdutils.CommandError(
"'args' is only allowed with target userscript/spawn.")
def _filter_matches(self, filterstr: Optional[str], elemstr: str) -> bool:
def _filter_matches(self, filterstr: str | None, elemstr: str) -> bool:
"""Return True if `filterstr` matches `elemstr`."""
# Empty string and None always match
if not filterstr:
@ -783,7 +783,7 @@ class HintManager(QObject):
error_cb=lambda err: message.error(str(err)),
only_visible=True)
def _get_hint_mode(self, mode: Optional[str]) -> str:
def _get_hint_mode(self, mode: str | None) -> str:
"""Get the hinting mode to use based on a mode argument."""
if mode is None:
return config.val.hints.mode
@ -795,7 +795,7 @@ class HintManager(QObject):
raise cmdutils.CommandError("Invalid mode: {}".format(e))
return mode
def current_mode(self) -> Optional[str]:
def current_mode(self) -> str | None:
"""Return the currently active hinting mode (or None otherwise)."""
if self._context is None:
return None
@ -868,7 +868,7 @@ class HintManager(QObject):
pass
self._handle_auto_follow(keystr=keystr)
def filter_hints(self, filterstr: Optional[str]) -> None:
def filter_hints(self, filterstr: str | None) -> None:
"""Filter displayed hints according to a text.
Args:
@ -1127,7 +1127,7 @@ class WordHinter:
def new_hint_for(self, elem: webelem.AbstractWebElement,
existing: Iterable[str],
fallback: Iterable[str]) -> Optional[str]:
fallback: Iterable[str]) -> str | None:
"""Return a hint for elem, not conflicting with the existing."""
new = self.tag_words_to_hints(self.extract_tag_words(elem))
new_no_prefixes = self.filter_prefixes(new, existing)

View File

@ -86,7 +86,7 @@ class CompletionMetaInfo(sql.SqlTable):
}
def __init__(self, database: sql.Database,
parent: Optional[QObject] = None) -> None:
parent: QObject | None = None) -> None:
self._fields = ['key', 'value']
self._constraints = {'key': 'PRIMARY KEY'}
super().__init__(database, "CompletionMetaInfo", self._fields,
@ -134,7 +134,7 @@ class CompletionHistory(sql.SqlTable):
"""History which only has the newest entry for each URL."""
def __init__(self, database: sql.Database,
parent: Optional[QObject] = None) -> None:
parent: QObject | None = None) -> None:
super().__init__(database, "CompletionHistory", ['url', 'title', 'last_atime'],
constraints={'url': 'PRIMARY KEY',
'title': 'NOT NULL',
@ -159,7 +159,7 @@ class WebHistory(sql.SqlTable):
url_cleared = pyqtSignal(QUrl)
def __init__(self, database: sql.Database, progress: HistoryProgress,
parent: Optional[QObject] = None) -> None:
parent: QObject | None = None) -> None:
super().__init__(database, "History", ['url', 'title', 'atime', 'redirect'],
constraints={'url': 'NOT NULL',
'title': 'NOT NULL',
@ -472,7 +472,7 @@ def debug_dump_history(dest):
raise cmdutils.CommandError(f'Could not write history: {e}')
def init(db_path: pathlib.Path, parent: Optional[QObject] = None) -> None:
def init(db_path: pathlib.Path, parent: QObject | None = None) -> None:
"""Initialize the web history.
Args:

View File

@ -57,7 +57,7 @@ class _EventFilter(QObject):
clicked = pyqtSignal()
def eventFilter(self, _obj: Optional[QObject], event: Optional[QEvent]) -> bool:
def eventFilter(self, _obj: QObject | None, event: QEvent | None) -> bool:
"""Translate mouse presses to a clicked signal."""
assert event is not None
if event.type() == QEvent.Type.MouseButtonPress:
@ -86,7 +86,7 @@ class AbstractWebInspector(QWidget):
self._widget = cast(_WidgetType, None)
self._layout = miscwidgets.WrapperLayout(self)
self._splitter = splitter
self._position: Optional[Position] = None
self._position: Position | None = None
self._win_id = win_id
self._event_filter = _EventFilter(parent=self)
@ -128,7 +128,7 @@ class AbstractWebInspector(QWidget):
modeman.enter(self._win_id, usertypes.KeyMode.insert,
reason='Inspector clicked', only_if_normal=True)
def set_position(self, position: Optional[Position]) -> None:
def set_position(self, position: Position | None) -> None:
"""Set the position of the inspector.
If the position is None, the last known position is used.
@ -183,7 +183,7 @@ class AbstractWebInspector(QWidget):
if not ok:
log.init.warning("Error while loading geometry.")
def closeEvent(self, _e: Optional[QCloseEvent]) -> None:
def closeEvent(self, _e: QCloseEvent | None) -> None:
"""Save the geometry when closed."""
data = self._widget.saveGeometry().data()
geom = base64.b64encode(data).decode('ASCII')

View File

@ -79,7 +79,7 @@ def incdec(url, count, inc_or_dec):
inc_or_dec: Either 'increment' or 'decrement'.
"""
urlutils.ensure_valid(url)
segments: Optional[set[str]] = (
segments: set[str] | None = (
set(config.val.url.incdec_segments)
)

View File

@ -248,7 +248,7 @@ class PACFetcher(QObject):
with qtlog.disable_qt_msghandler():
# WORKAROUND for a hang when messages are printed, see our
# NetworkAccessManager subclass for details.
self._manager: Optional[QNetworkAccessManager] = QNetworkAccessManager()
self._manager: QNetworkAccessManager | None = QNetworkAccessManager()
self._manager.setProxy(QNetworkProxy(QNetworkProxy.ProxyType.NoProxy))
self._pac = None
self._error_message = None

View File

@ -72,7 +72,7 @@ class DownloadItem(downloads.AbstractDownloadItem):
reply: The QNetworkReply to download.
"""
super().__init__(manager=manager, parent=manager)
self.fileobj: Optional[IO[bytes]] = None
self.fileobj: IO[bytes] | None = None
self.raw_headers: dict[bytes, bytes] = {}
self._autoclose = True

View File

@ -33,7 +33,7 @@ from qutebrowser.qt import sip
pyeval_output = ":pyeval was never called"
csrf_token: Optional[str] = None
csrf_token: str | None = None
_HANDLERS: dict[str, "_HandlerCallable"] = {}
@ -78,7 +78,7 @@ class Redirect(Exception):
# Return value: (mimetype, data) (encoded as utf-8 if a str is returned)
_HandlerRet = tuple[str, Union[str, bytes]]
_HandlerRet = tuple[str, str | bytes]
_HandlerCallable = Callable[[QUrl], _HandlerRet]
_Handler = TypeVar('_Handler', bound=_HandlerCallable)
@ -93,7 +93,7 @@ class add_handler: # noqa: N801,N806 pylint: disable=invalid-name
def __init__(self, name: str) -> None:
self._name = name
self._function: Optional[_HandlerCallable] = None
self._function: _HandlerCallable | None = None
def __call__(self, function: _Handler) -> _Handler:
self._function = function
@ -201,7 +201,7 @@ def qute_tabs(_url: QUrl) -> _HandlerRet:
def history_data(
start_time: float,
offset: int = None
) -> Sequence[dict[str, Union[str, int]]]:
) -> Sequence[dict[str, str | int]]:
"""Return history data.
Arguments:
@ -349,7 +349,7 @@ def qute_gpl(_url: QUrl) -> _HandlerRet:
return 'text/html', resources.read_file('html/license.html')
def _asciidoc_fallback_path(html_path: str) -> Optional[str]:
def _asciidoc_fallback_path(html_path: str) -> str | None:
"""Fall back to plaintext asciidoc if the HTML is unavailable."""
path = html_path.replace('.html', '.asciidoc')
try:

View File

@ -513,7 +513,7 @@ def choose_file(qb_mode: FileSelectionMode) -> list[str]:
def _execute_fileselect_command(
command: list[str],
qb_mode: FileSelectionMode,
tmpfilename: Optional[str] = None
tmpfilename: str | None = None
) -> list[str]:
"""Execute external command to choose file.

View File

@ -20,12 +20,12 @@ if TYPE_CHECKING:
from qutebrowser.browser import browsertab
JsValueType = Union[int, float, str, None]
JsValueType = int| float | str | None
if machinery.IS_QT6:
KeyboardModifierType = Qt.KeyboardModifier
else:
KeyboardModifierType = Union[Qt.KeyboardModifiers, Qt.KeyboardModifier]
KeyboardModifierType = Qt.KeyboardModifiers | Qt.KeyboardModifier
class Error(Exception):
@ -81,7 +81,7 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
def __repr__(self) -> str:
try:
html: Optional[str] = utils.compact_text(self.outer_xml(), 500)
html: str | None = utils.compact_text(self.outer_xml(), 500)
except Error:
html = None
return utils.get_repr(self, html=html)
@ -273,7 +273,7 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
"""Remove target from link."""
raise NotImplementedError
def resolve_url(self, baseurl: QUrl) -> Optional[QUrl]:
def resolve_url(self, baseurl: QUrl) -> QUrl | None:
"""Resolve the URL in the element's src/href attribute.
Args:

View File

@ -205,14 +205,14 @@ class _Setting:
option: str
chromium_key: str
mapping: Optional[Mapping[Any, Union[str, int, None]]] = None
mapping: Mapping[Any, str | int | None] | None = None
def _value_str(self, value: Any) -> str:
if self.mapping is None:
return str(value)
return str(self.mapping[value])
def chromium_tuple(self, value: Any) -> Optional[tuple[str, str]]:
def chromium_tuple(self, value: Any) -> tuple[str, str] | None:
"""Get the Chromium key and value, or None if no value should be set."""
if self.mapping is not None and self.mapping[value] is None:
return None
@ -244,7 +244,7 @@ class _Definition:
*args: _Setting,
mandatory: set[str],
prefix: str,
switch_names: Mapping[Optional[str], str] = None,
switch_names: Mapping[str | None, str] = None,
) -> None:
self._settings = args
self.mandatory = mandatory
@ -340,7 +340,7 @@ _DEFINITIONS[Variant.qt_66] = _DEFINITIONS[Variant.qt_64].copy_add_setting(
_DEFINITIONS[Variant.qt_67] = _DEFINITIONS[Variant.qt_66].copy_remove_setting('enabled')
_SettingValType = Union[str, usertypes.Unset]
_SettingValType = str | usertypes.Unset
_PREFERRED_COLOR_SCHEME_DEFINITIONS: MutableMapping[Variant, Mapping[_SettingValType, str]] = {
Variant.qt_515_2: {
# 0: no-preference (not exposed)

View File

@ -154,7 +154,7 @@ class AbstractNotificationAdapter(QObject):
self,
qt_notification: "QWebEngineNotification",
*,
replaces_id: Optional[int],
replaces_id: int | None,
) -> int:
"""Show the given notification.
@ -197,7 +197,7 @@ class NotificationBridgePresenter(QObject):
super().__init__(parent)
self._active_notifications: dict[int, 'QWebEngineNotification'] = {}
self._adapter: Optional[AbstractNotificationAdapter] = None
self._adapter: AbstractNotificationAdapter | None = None
config.instance.changed.connect(self._init_adapter)
@ -300,7 +300,7 @@ class NotificationBridgePresenter(QObject):
def _find_replaces_id(
self,
new_notification: "QWebEngineNotification",
) -> Optional[int]:
) -> int | None:
"""Find an existing notification to replace.
If no notification should be replaced or the notification to be replaced was not
@ -441,7 +441,7 @@ class SystrayNotificationAdapter(AbstractNotificationAdapter):
self,
qt_notification: "QWebEngineNotification",
*,
replaces_id: Optional[int],
replaces_id: int | None,
) -> int:
utils.unused(replaces_id) # QSystemTray can only show one message
self.close_id.emit(self.NOTIFICATION_ID)
@ -503,7 +503,7 @@ class MessagesNotificationAdapter(AbstractNotificationAdapter):
self,
qt_notification: "QWebEngineNotification",
*,
replaces_id: Optional[int],
replaces_id: int | None,
) -> int:
markup = self._format_message(qt_notification)
new_id = replaces_id if replaces_id is not None else next(self._id_gen)
@ -563,7 +563,7 @@ class HerbeNotificationAdapter(AbstractNotificationAdapter):
self,
qt_notification: "QWebEngineNotification",
*,
replaces_id: Optional[int],
replaces_id: int | None,
) -> int:
if replaces_id is not None:
self.on_web_closed(replaces_id)
@ -647,11 +647,11 @@ class _ServerQuirks:
"""Quirks for certain DBus notification servers."""
spec_version: Optional[str] = None
spec_version: str | None = None
avoid_actions: bool = False
avoid_body_hyperlinks: bool = False
escape_title: bool = False
icon_key: Optional[str] = None
icon_key: str | None = None
skip_capabilities: bool = False
wrong_replaces_id: bool = False
no_padded_images: bool = False
@ -778,7 +778,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
name: str,
vendor: str,
ver: str,
) -> Optional[_ServerQuirks]:
) -> _ServerQuirks | None:
"""Find quirks to use based on the server information."""
if (name, vendor) == ("notify-osd", "Canonical Ltd"):
# Shows a dialog box instead of a notification bubble as soon as a
@ -1009,7 +1009,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
self,
qt_notification: "QWebEngineNotification",
*,
replaces_id: Optional[int],
replaces_id: int | None,
) -> int:
"""Shows a notification over DBus."""
if replaces_id is None:
@ -1045,7 +1045,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
self._verify_notification_id(notification_id, replaces_id=replaces_id)
return notification_id
def _convert_image(self, qimage: QImage) -> Optional[QDBusArgument]:
def _convert_image(self, qimage: QImage) -> QDBusArgument | None:
"""Convert a QImage to the structure DBus expects.
https://specifications.freedesktop.org/notification-spec/latest/ar01s05.html#icons-and-images-formats

View File

@ -29,7 +29,7 @@ class WebEngineElement(webelem.AbstractWebElement):
tab: 'webenginetab.WebEngineTab') -> None:
super().__init__(tab)
# Do some sanity checks on the data we get from JS
js_dict_types: dict[str, Union[type, tuple[type, ...]]] = {
js_dict_types: dict[str, type | tuple[type, ...]] = {
'id': int,
'text': str,
'value': (str, int, float),
@ -138,7 +138,7 @@ class WebEngineElement(webelem.AbstractWebElement):
composed: bool = False) -> None:
self._js_call('dispatch_event', event, bubbles, cancelable, composed)
def caret_position(self) -> Optional[int]:
def caret_position(self) -> int | None:
"""Get the text caret position for the current element.
If the element is not a text element, None is returned.

View File

@ -61,7 +61,7 @@ class WebEngineInspector(inspector.AbstractWebInspector):
parent: QWidget = None) -> None:
super().__init__(splitter, win_id, parent)
self._check_devtools_resources()
self._settings: Optional[webenginesettings.WebEngineSettings] = None
self._settings: webenginesettings.WebEngineSettings | None = None
def _on_window_close_requested(self) -> None:
"""Called when the 'x' was clicked in the devtools."""

View File

@ -33,11 +33,11 @@ if TYPE_CHECKING:
# The default QWebEngineProfile
default_profile = cast(QWebEngineProfile, None)
# The QWebEngineProfile used for private (off-the-record) windows
private_profile: Optional[QWebEngineProfile] = None
private_profile: QWebEngineProfile | None = None
# The global WebEngineSettings object
_global_settings = cast('WebEngineSettings', None)
parsed_user_agent: Optional[websettings.UserAgent] = None
parsed_user_agent: websettings.UserAgent | None = None
_qute_scheme_handler = cast(webenginequtescheme.QuteSchemeHandler, None)
_req_interceptor = cast('interceptor.RequestInterceptor', None)
@ -223,7 +223,7 @@ class WebEngineSettings(websettings.AbstractSettings):
}
def set_unknown_url_scheme_policy(
self, policy: Union[str, usertypes.Unset]) -> None:
self, policy: str | usertypes.Unset) -> None:
"""Set the UnknownUrlSchemePolicy to use."""
if isinstance(policy, usertypes.Unset):
self._settings.resetUnknownUrlSchemePolicy()
@ -231,7 +231,7 @@ class WebEngineSettings(websettings.AbstractSettings):
new_value = self._UNKNOWN_URL_SCHEME_POLICY[policy]
self._settings.setUnknownUrlSchemePolicy(new_value)
def _set_js_clipboard(self, value: Union[str, usertypes.Unset]) -> None:
def _set_js_clipboard(self, value: str | usertypes.Unset) -> None:
attr_access = QWebEngineSettings.WebAttribute.JavascriptCanAccessClipboard
attr_paste = QWebEngineSettings.WebAttribute.JavascriptCanPaste

View File

@ -92,7 +92,7 @@ class WebEnginePrinting(browsertab.AbstractPrinting):
if machinery.IS_QT5:
_FindFlagType = Union[QWebEnginePage.FindFlag, QWebEnginePage.FindFlags]
_FindFlagType = QWebEnginePage.FindFlag | QWebEnginePage.FindFlags
else:
_FindFlagType = QWebEnginePage.FindFlag
@ -1019,7 +1019,7 @@ class _Quirk:
QWebEngineScript.InjectionPoint.DocumentCreation)
world: QWebEngineScript.ScriptWorldId = QWebEngineScript.ScriptWorldId.MainWorld
predicate: bool = True
name: Optional[str] = None
name: str | None = None
def __post_init__(self):
if self.name is None:
@ -1375,7 +1375,7 @@ class WebEngineTab(browsertab.AbstractTab):
log.misc.debug("run_js_async called on deleted tab")
return
world_id_type = Union[QWebEngineScript.ScriptWorldId, int]
world_id_type = QWebEngineScript.ScriptWorldId | int
if world is None:
world_id: world_id_type = QWebEngineScript.ScriptWorldId.ApplicationWorld
elif isinstance(world, int):

View File

@ -314,8 +314,8 @@ class WebEnginePage(QWebEnginePage):
def chooseFiles(
self,
mode: QWebEnginePage.FileSelectionMode,
old_files: Iterable[Optional[str]],
accepted_mimetypes: Iterable[Optional[str]],
old_files: Iterable[str | None],
accepted_mimetypes: Iterable[str | None],
) -> list[str]:
"""Override chooseFiles to (optionally) invoke custom file uploader."""
accepted_mimetypes_filtered = [m for m in accepted_mimetypes if m is not None]

View File

@ -21,7 +21,7 @@ class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
self._reply = reply
self._errors = tuple(errors) # needs to be hashable
try:
self._host_tpl: Optional[urlutils.HostTupleType] = urlutils.host_tuple(reply.url())
self._host_tpl: urlutils.HostTupleType | None = urlutils.host_tuple(reply.url())
except ValueError:
self._host_tpl = None

View File

@ -246,7 +246,7 @@ class NetworkManager(QNetworkAccessManager):
errors = certificateerror.CertificateErrorWrapper(reply, qt_errors)
log.network.debug("Certificate errors: {!r}".format(errors))
try:
host_tpl: Optional[urlutils.HostTupleType] = urlutils.host_tuple(
host_tpl: urlutils.HostTupleType | None = urlutils.host_tuple(
reply.url())
except ValueError:
host_tpl = None

View File

@ -167,13 +167,13 @@ class WebKitElement(webelem.AbstractWebElement):
def _parent(self) -> Optional['WebKitElement']:
"""Get the parent element of this element."""
self._check_vanished()
elem = cast(Optional[QWebElement], self._elem.parent())
elem = cast(QWebElement | None, self._elem.parent())
if elem is None or elem.isNull():
return None
return WebKitElement(elem, tab=self._tab)
def _rect_on_view_js(self) -> Optional[QRect]:
def _rect_on_view_js(self) -> QRect | None:
"""Javascript implementation for rect_on_view."""
# FIXME:qtwebengine maybe we can reuse this?
rects = self._elem.evaluateJavaScript("this.getClientRects()")
@ -203,7 +203,7 @@ class WebKitElement(webelem.AbstractWebElement):
rect = QRect(int(rect["left"]), int(rect["top"]),
int(width), int(height))
frame = cast(Optional[QWebFrame], self._elem.webFrame())
frame = cast(QWebFrame | None, self._elem.webFrame())
while frame is not None:
# Translate to parent frames' position (scroll position
# is taken care of inside getClientRects)
@ -214,7 +214,7 @@ class WebKitElement(webelem.AbstractWebElement):
return None
def _rect_on_view_python(self, elem_geometry: Optional[QRect]) -> QRect:
def _rect_on_view_python(self, elem_geometry: QRect | None) -> QRect:
"""Python implementation for rect_on_view."""
if elem_geometry is None:
geometry = self._elem.geometry()
@ -222,11 +222,11 @@ class WebKitElement(webelem.AbstractWebElement):
geometry = elem_geometry
rect = QRect(geometry)
frame = cast(Optional[QWebFrame], self._elem.webFrame())
frame = cast(QWebFrame | None, self._elem.webFrame())
while frame is not None:
rect.translate(frame.geometry().topLeft())
rect.translate(frame.scrollPosition() * -1)
frame = cast(Optional[QWebFrame], frame.parentFrame())
frame = cast(QWebFrame | None, frame.parentFrame())
return rect
@ -320,7 +320,7 @@ class WebKitElement(webelem.AbstractWebElement):
return all([visible_on_screen, visible_in_frame])
def remove_blank_target(self) -> None:
elem: Optional[WebKitElement] = self
elem: WebKitElement | None = self
for _ in range(5):
if elem is None:
break

View File

@ -760,7 +760,7 @@ class WebKitElements(browsertab.AbstractElements):
self.find_css('#' + elem_id, find_id_cb, error_cb=lambda exc: None)
def find_focused(self, callback):
frame = cast(Optional[QWebFrame], self._widget.page().currentFrame())
frame = cast(QWebFrame | None, self._widget.page().currentFrame())
if frame is None:
callback(None)
return
@ -774,7 +774,7 @@ class WebKitElements(browsertab.AbstractElements):
def find_at_pos(self, pos, callback):
assert pos.x() >= 0
assert pos.y() >= 0
frame = cast(Optional[QWebFrame], self._widget.page().frameAt(pos))
frame = cast(QWebFrame | None, self._widget.page().frameAt(pos))
if frame is None:
# This happens when we click inside the webview, but not actually
# on the QWebPage - for example when clicking the scrollbar
@ -930,7 +930,7 @@ class WebKitTab(browsertab.AbstractTab):
def title(self):
return self._widget.title()
def renderer_process_pid(self) -> Optional[int]:
def renderer_process_pid(self) -> int | None:
return None
@pyqtSlot()

View File

@ -25,12 +25,12 @@ class ArgInfo:
"""Information about an argument."""
value: Optional[usertypes.CommandValue] = None
value: usertypes.CommandValue | None = None
hide: bool = False
metavar: Optional[str] = None
flag: Optional[str] = None
completion: Optional[Callable[..., completionmodel.CompletionModel]] = None
choices: Optional[list[str]] = None
metavar: str | None = None
flag: str | None = None
completion: Callable[..., completionmodel.CompletionModel] | None = None
choices: list[str] | None = None
class Command:

View File

@ -101,7 +101,7 @@ class CompletionView(QTreeView):
win_id: int,
parent: QWidget = None) -> None:
super().__init__(parent)
self.pattern: Optional[str] = None
self.pattern: str | None = None
self._win_id = win_id
self._cmd = cmd
self._active = False

View File

@ -21,4 +21,4 @@ class BaseCategory(QAbstractItemModel):
name: str
columns_to_filter: Sequence[int]
delete_func: Optional[DeleteFuncType] = None
delete_func: DeleteFuncType | None = None

View File

@ -39,7 +39,7 @@ class CompletionModel(QAbstractItemModel):
self.column_widths = column_widths
self._categories: MutableSequence[BaseCategory] = []
def _cat_from_idx(self, index: QModelIndex) -> Optional[BaseCategory]:
def _cat_from_idx(self, index: QModelIndex) -> BaseCategory | None:
"""Return the category pointed to by the given index.
Args:
@ -128,7 +128,7 @@ class CompletionModel(QAbstractItemModel):
else:
@overload
def parent(self) -> Optional[QObject]:
def parent(self) -> QObject | None:
...
def parent(self, index=None):

View File

@ -87,7 +87,7 @@ class FilePathCategory(QAbstractListModel, BaseCategory):
paths = self._glob(expanded)
self._paths = sorted(self._contract_user(val, path) for path in paths)
def data(self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole) -> Optional[str]:
def data(self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole) -> str | None:
"""Implement abstract method in QAbstractListModel."""
if role == Qt.ItemDataRole.DisplayRole and index.column() == 0:
return self._paths[index.row()]

View File

@ -26,12 +26,12 @@ class HistoryCategory(QSqlQueryModel, BaseCategory):
super().__init__(parent=parent)
self._database = database
self.name = "History"
self._query: Optional[sql.Query] = None
self._query: sql.Query | None = None
# advertise that this model filters by URL and title
self.columns_to_filter = [0, 1]
self.delete_func = delete_func
self._empty_prefix: Optional[str] = None
self._empty_prefix: str | None = None
def _atime_expr(self):
"""If max_items is set, return an expression to limit the query."""

View File

@ -102,7 +102,7 @@ _RESOURCE_TYPE_STRINGS = {
}
def _resource_type_to_string(resource_type: Optional[ResourceType]) -> str:
def _resource_type_to_string(resource_type: ResourceType | None) -> str:
return _RESOURCE_TYPE_STRINGS.get(resource_type, "other")
@ -174,8 +174,8 @@ class BraveAdBlocker:
def _is_blocked(
self,
request_url: QUrl,
first_party_url: Optional[QUrl] = None,
resource_type: Optional[interceptor.ResourceType] = None,
first_party_url: QUrl | None = None,
resource_type: interceptor.ResourceType | None = None,
) -> bool:
"""Check whether the given request is blocked."""
if not self.enabled:

View File

@ -34,7 +34,7 @@ _LOGGER = logging.getLogger('misc')
@cmdutils.register(name='reload')
@cmdutils.argument('tab', value=cmdutils.Value.count_tab)
def reloadpage(tab: Optional[apitypes.Tab],
def reloadpage(tab: apitypes.Tab | None,
force: bool = False) -> None:
"""Reload the current/[count]th tab.
@ -48,7 +48,7 @@ def reloadpage(tab: Optional[apitypes.Tab],
@cmdutils.register()
@cmdutils.argument('tab', value=cmdutils.Value.count_tab)
def stop(tab: Optional[apitypes.Tab]) -> None:
def stop(tab: apitypes.Tab | None) -> None:
"""Stop loading in the current/[count]th tab.
Args:
@ -88,9 +88,9 @@ def _print_pdf(tab: apitypes.Tab, path: pathlib.Path) -> None:
@cmdutils.register(name='print')
@cmdutils.argument('tab', value=cmdutils.Value.count_tab)
@cmdutils.argument('pdf', flag='f', metavar='file')
def printpage(tab: Optional[apitypes.Tab],
def printpage(tab: apitypes.Tab | None,
preview: bool = False, *,
pdf: Optional[pathlib.Path] = None) -> None:
pdf: pathlib.Path | None = None) -> None:
"""Print the current/[count]th tab.
Args:
@ -193,7 +193,7 @@ def insert_text(tab: apitypes.Tab, text: str) -> None:
Args:
text: The text to insert.
"""
def _insert_text_cb(elem: Optional[apitypes.WebElement]) -> None:
def _insert_text_cb(elem: apitypes.WebElement | None) -> None:
if elem is None:
message.error("No element focused!")
return
@ -207,7 +207,7 @@ def insert_text(tab: apitypes.Tab, text: str) -> None:
def _wrap_find_at_pos(value: str, tab: apitypes.Tab,
callback: Callable[[Optional[apitypes.WebElement]], None]
callback: Callable[[apitypes.WebElement | None], None]
) -> None:
try:
point = utils.parse_point(value)
@ -257,7 +257,7 @@ def click_element(tab: apitypes.Tab, filter_: str, value: str = None, *, # noqa
except apitypes.WebElemError as e:
message.error(str(e))
def single_cb(elem: Optional[apitypes.WebElement]) -> None:
def single_cb(elem: apitypes.WebElement | None) -> None:
"""Click a single element."""
if elem is None:
message.error(f"No element found {_FILTER_ERRORS[filter_](value)}!")
@ -322,7 +322,7 @@ def debug_webaction(tab: apitypes.Tab, action: str, count: int = 1) -> None:
@cmdutils.register()
@cmdutils.argument('tab', value=cmdutils.Value.count_tab)
def tab_mute(tab: Optional[apitypes.Tab]) -> None:
def tab_mute(tab: apitypes.Tab | None) -> None:
"""Mute/Unmute the current/[count]th tab.
Args:

View File

@ -24,7 +24,7 @@ class _ReadlineBridge:
def __init__(self) -> None:
self._deleted: MutableMapping[QLineEdit, str] = {}
def _widget(self) -> Optional[QLineEdit]:
def _widget(self) -> QLineEdit | None:
"""Get the currently active QLineEdit."""
# FIXME add this to api.utils or so
qapp = QApplication.instance()

View File

@ -47,7 +47,7 @@ class BlocklistDownloads(QObject):
single_download_finished = pyqtSignal(object) # arg: the file object
all_downloads_finished = pyqtSignal(int) # arg: download count
def __init__(self, urls: list[QUrl], parent: Optional[QObject] = None) -> None:
def __init__(self, urls: list[QUrl], parent: QObject | None = None) -> None:
super().__init__(parent)
self._urls = urls

View File

@ -69,7 +69,7 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name
not configdata.is_valid_prefix(self._option)):
raise configexc.NoOptionError(self._option)
def check_match(self, option: Optional[str]) -> bool:
def check_match(self, option: str | None) -> bool:
"""Check if the given option matches the filter."""
if option is None:
# Called directly, not from a config change event.
@ -153,7 +153,7 @@ class KeyConfig:
bindings[key] = binding
return bindings
def _implied_cmd(self, cmdline: str) -> Optional[str]:
def _implied_cmd(self, cmdline: str) -> str | None:
"""Return cmdline, or the implied cmd if cmdline is a cmd-set-text."""
try:
results = parser.CommandParser().parse_all(cmdline)
@ -198,7 +198,7 @@ class KeyConfig:
def get_command(self,
key: keyutils.KeySequence,
mode: str,
default: bool = False) -> Optional[str]:
default: bool = False) -> str | None:
"""Get the command for a given key (or None)."""
self._validate(key, mode)
if default:
@ -410,7 +410,7 @@ class Config(QObject):
def get_obj_for_pattern(
self, name: str, *,
pattern: Optional[urlmatch.UrlPattern]
pattern: urlmatch.UrlPattern | None
) -> Any:
"""Get the given setting as object (for YAML/config.py).

View File

@ -40,7 +40,7 @@ class ConfigCommands:
except configexc.Error as e:
raise cmdutils.CommandError(str(e))
def _parse_pattern(self, pattern: Optional[str]) -> Optional[urlmatch.UrlPattern]:
def _parse_pattern(self, pattern: str | None) -> urlmatch.UrlPattern | None:
"""Parse a pattern string argument to a pattern."""
if pattern is None:
return None
@ -58,7 +58,7 @@ class ConfigCommands:
except keyutils.KeyParseError as e:
raise cmdutils.CommandError(str(e))
def _print_value(self, option: str, pattern: Optional[urlmatch.UrlPattern]) -> None:
def _print_value(self, option: str, pattern: urlmatch.UrlPattern | None) -> None:
"""Print the value of the given option."""
with self._handle_config_error():
value = self._config.get_str(option, pattern=pattern)
@ -474,7 +474,7 @@ class ConfigCommands:
raise cmdutils.CommandError("{} already exists - use --force to "
"overwrite!".format(filename))
options: list[tuple[Optional[urlmatch.UrlPattern], configdata.Option, Any]] = []
options: list[tuple[urlmatch.UrlPattern | None, configdata.Option, Any]] = []
if defaults:
options = [(None, opt, opt.default)
for _name, opt in sorted(configdata.DATA.items())]

View File

@ -21,7 +21,7 @@ from qutebrowser.misc import debugcachestats
DATA = cast(Mapping[str, 'Option'], None)
MIGRATIONS = cast('Migrations', None)
_BackendDict = Mapping[str, Union[str, bool]]
_BackendDict = Mapping[str, str | bool]
@dataclasses.dataclass(order=True)
@ -36,7 +36,7 @@ class Option:
typ: configtypes.BaseType
default: Any
backends: Iterable[usertypes.Backend]
raw_backends: Optional[Mapping[str, bool]]
raw_backends: Mapping[str, bool] | None
description: str
supports_pattern: bool = False
restart: bool = False
@ -71,7 +71,7 @@ def _raise_invalid_node(name: str, what: str, node: Any) -> NoReturn:
def _parse_yaml_type(
name: str,
node: Union[str, Mapping[str, Any]],
node: str | Mapping[str, Any],
) -> configtypes.BaseType:
if isinstance(node, str):
# e.g:
@ -157,7 +157,7 @@ def _parse_yaml_backends_dict(
def _parse_yaml_backends(
name: str,
node: Union[None, str, _BackendDict],
node: None | str | _BackendDict,
) -> Sequence[usertypes.Backend]:
"""Parse a backend node in the yaml.

View File

@ -33,7 +33,7 @@ class BackendError(Error):
def __init__(
self, name: str,
backend: usertypes.Backend,
raw_backends: Optional[Mapping[str, bool]]
raw_backends: Mapping[str, bool] | None
) -> None:
if raw_backends is None or not raw_backends[backend.name]:
msg = ("The {} setting is not available with the {} backend!"
@ -63,7 +63,7 @@ class ValidationError(Error):
msg: Additional error message.
"""
def __init__(self, value: Any, msg: Union[str, Exception]) -> None:
def __init__(self, value: Any, msg: str | Exception) -> None:
super().__init__("Invalid value '{}' - {}".format(value, msg))
self.option = None
@ -111,8 +111,8 @@ class ConfigErrorDesc:
"""
text: str
exception: Union[str, Exception]
traceback: Optional[str] = None
exception: str | Exception
traceback: str | None = None
def __str__(self) -> str:
if self.traceback:

View File

@ -114,7 +114,7 @@ class StateConfig(configparser.ConfigParser):
return False
return True
def _qtwe_versions(self) -> Optional[version.WebEngineVersions]:
def _qtwe_versions(self) -> version.WebEngineVersions | None:
"""Get the QtWebEngine versions."""
if not self._has_webengine():
return None
@ -758,7 +758,7 @@ class ConfigAPI:
urlpattern = urlmatch.UrlPattern(pattern) if pattern else None
self._config.set_obj(name, value, pattern=urlpattern)
def bind(self, key: str, command: Optional[str], mode: str = 'normal') -> None:
def bind(self, key: str, command: str | None, mode: str = 'normal') -> None:
"""Bind a key to a command, with an optional key mode."""
with self._handle_error(f"binding '{key}'"):
seq = keyutils.KeySequence.parse(key)
@ -805,12 +805,12 @@ class ConfigPyWriter:
self,
options: list[
tuple[
Optional[urlmatch.UrlPattern],
urlmatch.UrlPattern | None,
configdata.Option,
Any
]
],
bindings: MutableMapping[str, Mapping[str, Optional[str]]],
bindings: MutableMapping[str, Mapping[str, str | None]],
*,
commented: bool,
) -> None:

View File

@ -20,7 +20,7 @@ from qutebrowser.misc import msgbox, objects, savemanager
# Error which happened during init, so we can show a message box.
_init_errors: Optional[configexc.ConfigFileErrors] = None
_init_errors: configexc.ConfigFileErrors | None = None
def early_init(args: argparse.Namespace) -> None:

View File

@ -66,13 +66,13 @@ BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True,
'0': False, 'no': False, 'false': False, 'off': False}
_Completions = Optional[Iterable[tuple[str, str]]]
_StrUnset = Union[str, usertypes.Unset]
_UnsetNone = Union[None, usertypes.Unset]
_StrUnsetNone = Union[str, _UnsetNone]
_Completions = _Completions = Iterable[tuple[str, str]] | None
_StrUnset = str | usertypes.Unset
_UnsetNone = None | usertypes.Unset
_StrUnsetNone = str | _UnsetNone
def _validate_encoding(encoding: Optional[str], value: str) -> None:
def _validate_encoding(encoding: str | None, value: str) -> None:
"""Check if the given value fits into the given encoding.
Raises ValidationError if not.
@ -101,11 +101,7 @@ class ValidValues:
def __init__(
self,
*values: Union[
str,
dict[str, Optional[str]],
tuple[str, Optional[str]],
],
*values: str | dict[str, str | None] | tuple[str, str | None],
generate_docs: bool = True,
others_permitted: bool = False
) -> None:
@ -178,19 +174,19 @@ class BaseType:
) -> None:
self._completions = completions
self.none_ok = none_ok
self.valid_values: Optional[ValidValues] = None
self.valid_values: ValidValues | None = None
def get_name(self) -> str:
"""Get a name for the type for documentation."""
return self.__class__.__name__
def get_valid_values(self) -> Optional[ValidValues]:
def get_valid_values(self) -> ValidValues | None:
"""Get the type's valid values for documentation."""
return self.valid_values
def _basic_py_validation(
self, value: Any,
pytype: Union[type, tuple[type, ...]]) -> None:
pytype: type | tuple[type, ...]) -> None:
"""Do some basic validation for Python values (emptyness, type).
Arguments:
@ -356,7 +352,7 @@ class MappingType(BaseType):
MAPPING: A mapping from config values to (translated_value, docs) tuples.
"""
MAPPING: dict[str, tuple[Any, Optional[str]]] = {}
MAPPING: dict[str, tuple[Any, str | None]] = {}
def __init__(
self, *,
@ -505,10 +501,10 @@ class List(BaseType):
name += " of " + self.valtype.get_name()
return name
def get_valid_values(self) -> Optional[ValidValues]:
def get_valid_values(self) -> ValidValues | None:
return self.valtype.get_valid_values()
def from_str(self, value: str) -> Optional[list]:
def from_str(self, value: str) -> list | None:
self._basic_str_validation(value)
if not value:
return None
@ -523,15 +519,15 @@ class List(BaseType):
self.to_py(yaml_val)
return yaml_val
def from_obj(self, value: Optional[list]) -> list:
def from_obj(self, value: list | None) -> list:
if value is None:
return []
return [self.valtype.from_obj(v) for v in value]
def to_py(
self,
value: Union[list, usertypes.Unset]
) -> Union[list, usertypes.Unset]:
value: list | usertypes.Unset
) -> list | usertypes.Unset:
self._basic_py_validation(value, list)
if isinstance(value, usertypes.Unset):
return value
@ -610,7 +606,7 @@ class ListOrValue(BaseType):
def get_name(self) -> str:
return self.listtype.get_name() + ', or ' + self.valtype.get_name()
def get_valid_values(self) -> Optional[ValidValues]:
def get_valid_values(self) -> ValidValues | None:
return self.valtype.get_valid_values()
def from_str(self, value: str) -> Any:
@ -659,7 +655,7 @@ class FlagList(List):
the valid values of the setting.
"""
combinable_values: Optional[Sequence] = None
combinable_values: Sequence | None = None
_show_valtype = False
@ -685,8 +681,8 @@ class FlagList(List):
def to_py(
self,
value: Union[usertypes.Unset, list],
) -> Union[usertypes.Unset, list]:
value: usertypes.Unset | list,
) -> usertypes.Unset | list:
vals = super().to_py(value)
if not isinstance(vals, usertypes.Unset):
self._check_duplicates(vals)
@ -737,12 +733,12 @@ class Bool(BaseType):
super().__init__(none_ok=none_ok, completions=completions)
self.valid_values = ValidValues('true', 'false', generate_docs=False)
def to_py(self, value: Union[bool, str, None]) -> Optional[bool]:
def to_py(self, value: bool | str | None) -> bool | None:
self._basic_py_validation(value, bool)
assert not isinstance(value, str)
return value
def from_str(self, value: str) -> Optional[bool]:
def from_str(self, value: str) -> bool | None:
self._basic_str_validation(value)
if not value:
return None
@ -752,7 +748,7 @@ class Bool(BaseType):
except KeyError:
raise configexc.ValidationError(value, "must be a boolean!")
def to_str(self, value: Optional[bool]) -> str:
def to_str(self, value: bool | None) -> str:
mapping = {
None: '',
True: 'true',
@ -774,7 +770,7 @@ class BoolAsk(Bool):
self.valid_values = ValidValues('true', 'false', 'ask')
def to_py(self, # type: ignore[override]
value: Union[bool, str]) -> Union[bool, str, None]:
value: bool | str) -> bool | str | None:
# basic validation unneeded if it's == 'ask' and done by Bool if we
# call super().to_py
if isinstance(value, str) and value.lower() == 'ask':
@ -782,14 +778,14 @@ class BoolAsk(Bool):
return super().to_py(value)
def from_str(self, # type: ignore[override]
value: str) -> Union[bool, str, None]:
value: str) -> bool | str | None:
# basic validation unneeded if it's == 'ask' and done by Bool if we
# call super().from_str
if value.lower() == 'ask':
return 'ask'
return super().from_str(value)
def to_str(self, value: Union[bool, str, None]) -> str:
def to_str(self, value: bool | str | None) -> str:
mapping = {
None: '',
True: 'true',
@ -826,8 +822,8 @@ class _Numeric(BaseType): # pylint: disable=abstract-method
.format(self.minval, self.maxval))
def _parse_bound(
self, bound: Union[None, str, int, float]
) -> Union[None, int, float]:
self, bound: None | str | int | float
) -> None | int | float:
"""Get a numeric bound from a string like 'maxint'."""
if bound == 'maxint':
return qtutils.MAXVALS['int']
@ -839,7 +835,7 @@ class _Numeric(BaseType): # pylint: disable=abstract-method
return bound
def _validate_bounds(self,
value: Union[int, float, _UnsetNone],
value: int | float | _UnsetNone,
suffix: str = '') -> None:
"""Validate self.minval and self.maxval."""
if value is None:
@ -855,7 +851,7 @@ class _Numeric(BaseType): # pylint: disable=abstract-method
elif not self.zero_ok and value == 0:
raise configexc.ValidationError(value, "must not be 0!")
def to_str(self, value: Union[None, int, float]) -> str:
def to_str(self, value: None | int | float) -> str:
if value is None:
return ''
return str(value)
@ -869,7 +865,7 @@ class Int(_Numeric):
"""Base class for an integer setting."""
def from_str(self, value: str) -> Optional[int]:
def from_str(self, value: str) -> int | None:
self._basic_str_validation(value)
if not value:
return None
@ -881,7 +877,7 @@ class Int(_Numeric):
self.to_py(intval)
return intval
def to_py(self, value: Union[int, _UnsetNone]) -> Union[int, _UnsetNone]:
def to_py(self, value: int | _UnsetNone) -> int | _UnsetNone:
self._basic_py_validation(value, int)
self._validate_bounds(value)
return value
@ -891,7 +887,7 @@ class Float(_Numeric):
"""Base class for a float setting."""
def from_str(self, value: str) -> Optional[float]:
def from_str(self, value: str) -> float | None:
self._basic_str_validation(value)
if not value:
return None
@ -905,8 +901,8 @@ class Float(_Numeric):
def to_py(
self,
value: Union[int, float, _UnsetNone],
) -> Union[int, float, _UnsetNone]:
value: int | float | _UnsetNone,
) -> int | float | _UnsetNone:
self._basic_py_validation(value, (int, float))
self._validate_bounds(value)
return value
@ -918,8 +914,8 @@ class Perc(_Numeric):
def to_py(
self,
value: Union[float, int, str, _UnsetNone]
) -> Union[float, int, _UnsetNone]:
value: float | int | str | _UnsetNone
) -> float | int | _UnsetNone:
self._basic_py_validation(value, (float, int, str))
if isinstance(value, usertypes.Unset):
return value
@ -936,7 +932,7 @@ class Perc(_Numeric):
self._validate_bounds(value, suffix='%')
return value
def to_str(self, value: Union[None, float, int, str]) -> str:
def to_str(self, value: None | float | int | str) -> str:
if value is None:
return ''
elif isinstance(value, str):
@ -978,7 +974,7 @@ class PercOrInt(_Numeric):
raise ValueError("minperc ({}) needs to be <= maxperc "
"({})!".format(self.minperc, self.maxperc))
def from_str(self, value: str) -> Union[None, str, int]:
def from_str(self, value: str) -> None | str | int:
self._basic_str_validation(value)
if not value:
return None
@ -995,7 +991,7 @@ class PercOrInt(_Numeric):
self.to_py(intval)
return intval
def to_py(self, value: Union[None, str, int]) -> Union[None, str, int]:
def to_py(self, value: None | str | int) -> None | str | int:
"""Expect a value like '42%' as string, or 23 as int."""
self._basic_py_validation(value, (int, str))
if value is None:
@ -1110,7 +1106,7 @@ class QtColor(BaseType):
except ValueError:
raise configexc.ValidationError(val, "must be a valid color value")
def to_py(self, value: _StrUnset) -> Union[_UnsetNone, QColor]:
def to_py(self, value: _StrUnset) -> _UnsetNone | QColor:
self._basic_py_validation(value, str)
if isinstance(value, usertypes.Unset):
return value
@ -1193,8 +1189,8 @@ class FontBase(BaseType):
"""Base class for Font/FontFamily."""
# Gets set when the config is initialized.
default_family: Optional[str] = None
default_size: Optional[str] = None
default_family: str | None = None
default_size: str | None = None
font_regex = re.compile(r"""
(
(
@ -1334,8 +1330,8 @@ class Regex(BaseType):
def to_py(
self,
value: Union[str, Pattern[str], usertypes.Unset]
) -> Union[_UnsetNone, Pattern[str]]:
value: str | Pattern[str] | usertypes.Unset
) -> _UnsetNone | Pattern[str]:
"""Get a compiled regex from either a string or a regex object."""
self._basic_py_validation(value, (str, self._regex_type))
if isinstance(value, usertypes.Unset):
@ -1347,7 +1343,7 @@ class Regex(BaseType):
else:
return value
def to_str(self, value: Union[None, str, Pattern[str]]) -> str:
def to_str(self, value: None | str | Pattern[str]) -> str:
if value is None:
return ''
elif isinstance(value, self._regex_type):
@ -1396,7 +1392,7 @@ class Dict(BaseType):
raise configexc.ValidationError(
value, "Required keys {}".format(self.required_keys))
def from_str(self, value: str) -> Optional[dict]:
def from_str(self, value: str) -> dict | None:
self._basic_str_validation(value)
if not value:
return None
@ -1411,7 +1407,7 @@ class Dict(BaseType):
self.to_py(yaml_val)
return yaml_val
def from_obj(self, value: Optional[dict]) -> dict:
def from_obj(self, value: dict | None) -> dict:
if value is None:
return {}
@ -1429,8 +1425,8 @@ class Dict(BaseType):
def to_py(
self,
value: Union[dict, _UnsetNone]
) -> Union[dict, usertypes.Unset]:
value: dict | _UnsetNone
) -> dict | usertypes.Unset:
self._basic_py_validation(value, dict)
if isinstance(value, usertypes.Unset):
return value
@ -1606,8 +1602,8 @@ class ShellCommand(List):
def to_py(
self,
value: Union[list, usertypes.Unset],
) -> Union[list, usertypes.Unset]:
value: list | usertypes.Unset,
) -> list | usertypes.Unset:
py_value = super().to_py(value)
if isinstance(py_value, usertypes.Unset):
return py_value
@ -1646,7 +1642,7 @@ class Proxy(BaseType):
def to_py(
self,
value: _StrUnset
) -> Union[_UnsetNone, QNetworkProxy, _SystemProxy, pac.PACFetcher]:
) -> _UnsetNone | QNetworkProxy | _SystemProxy | pac.PACFetcher:
self._basic_py_validation(value, str)
if isinstance(value, usertypes.Unset):
return value
@ -1719,7 +1715,7 @@ class FuzzyUrl(BaseType):
"""A URL which gets interpreted as search if needed."""
def to_py(self, value: _StrUnset) -> Union[QUrl, _UnsetNone]:
def to_py(self, value: _StrUnset) -> QUrl | _UnsetNone:
self._basic_py_validation(value, str)
if isinstance(value, usertypes.Unset):
return value
@ -1764,8 +1760,8 @@ class Padding(Dict):
def to_py( # type: ignore[override]
self,
value: Union[dict, _UnsetNone],
) -> Union[usertypes.Unset, PaddingValues]:
value: dict | _UnsetNone,
) -> usertypes.Unset | PaddingValues:
d = super().to_py(value)
if isinstance(d, usertypes.Unset):
return d
@ -1842,7 +1838,7 @@ class Url(BaseType):
"""A URL as a string."""
def to_py(self, value: _StrUnset) -> Union[_UnsetNone, QUrl]:
def to_py(self, value: _StrUnset) -> _UnsetNone | QUrl:
self._basic_py_validation(value, str)
if isinstance(value, usertypes.Unset):
return value
@ -1917,8 +1913,8 @@ class ConfirmQuit(FlagList):
def to_py(
self,
value: Union[usertypes.Unset, list],
) -> Union[list, usertypes.Unset]:
value: usertypes.Unset | list,
) -> list | usertypes.Unset:
values = super().to_py(value)
if isinstance(values, usertypes.Unset):
return values
@ -1979,7 +1975,7 @@ class Key(BaseType):
def to_py(
self,
value: _StrUnset
) -> Union[_UnsetNone, keyutils.KeySequence]:
) -> _UnsetNone | keyutils.KeySequence:
self._basic_py_validation(value, str)
if isinstance(value, usertypes.Unset):
return value
@ -2004,7 +2000,7 @@ class UrlPattern(BaseType):
def to_py(
self,
value: _StrUnset
) -> Union[_UnsetNone, urlmatch.UrlPattern]:
) -> _UnsetNone | urlmatch.UrlPattern:
self._basic_py_validation(value, str)
if isinstance(value, usertypes.Unset):
return value

View File

@ -36,7 +36,7 @@ class ScopedValue:
id_gen = itertools.count(0)
def __init__(self, value: Any,
pattern: Optional[urlmatch.UrlPattern],
pattern: urlmatch.UrlPattern | None,
hide_userconfig: bool = False) -> None:
self.value = value
self.pattern = pattern
@ -69,7 +69,7 @@ class Values:
_domain_map: A mapping from hostnames to all associated ScopedValues.
"""
_VmapKeyType = Optional[urlmatch.UrlPattern]
_VmapKeyType = urlmatch.UrlPattern | None
def __init__(self,
opt: 'configdata.Option',
@ -79,7 +79,7 @@ class Values:
Values._VmapKeyType, ScopedValue] = collections.OrderedDict()
# A map from domain parts to rules that fall under them.
self._domain_map: dict[
Optional[str], set[ScopedValue]] = collections.defaultdict(set)
str | None, set[ScopedValue]] = collections.defaultdict(set)
for scoped in values:
self._add_scoped(scoped)
@ -130,7 +130,7 @@ class Values:
return bool(self._vmap)
def _check_pattern_support(
self, arg: Union[urlmatch.UrlPattern, QUrl, None]) -> None:
self, arg: urlmatch.UrlPattern | QUrl | None) -> None:
"""Make sure patterns are supported if one was given."""
if arg is not None and not self.opt.supports_pattern:
raise configexc.NoPatternError(self.opt.name)
@ -225,7 +225,7 @@ class Values:
return self._get_fallback(fallback)
def get_for_pattern(self,
pattern: Optional[urlmatch.UrlPattern], *,
pattern: urlmatch.UrlPattern | None, *,
fallback: bool = True) -> Any:
"""Get a value only if it's been overridden for the given pattern.

View File

@ -213,7 +213,7 @@ def _webengine_locales_path() -> pathlib.Path:
def _get_lang_override(
webengine_version: utils.VersionNumber,
locale_name: str
) -> Optional[str]:
) -> str | None:
"""Get a --lang switch to override Qt's locale handling.
This is needed as a WORKAROUND for https://bugreports.qt.io/browse/QTBUG-91715
@ -290,16 +290,15 @@ def _qtwebengine_args(
yield from _qtwebengine_settings_args(versions)
_SettingValueType = Union[
str,
Callable[
[
version.WebEngineVersions,
],
Optional[str],
],
]
_WEBENGINE_SETTINGS: dict[str, dict[Any, Optional[_SettingValueType]]] = {
_SettingValueType = (
str
| Callable[
[version.WebEngineVersions],
str | None,
]
)
_WEBENGINE_SETTINGS: dict[str, dict[Any, _SettingValueType | None]] = {
'qt.force_software_rendering': {
'software-opengl': None,
'qt-quick': None,

View File

@ -58,7 +58,7 @@ class _StyleSheetObserver(QObject):
"""
def __init__(self, obj: QWidget,
stylesheet: Optional[str], update: bool) -> None:
stylesheet: str | None, update: bool) -> None:
super().__init__()
self._obj = obj
self._update = update
@ -72,7 +72,7 @@ class _StyleSheetObserver(QObject):
self._stylesheet = stylesheet
if update:
self._options: Optional[frozenset[str]] = jinja.template_config_variables(
self._options: frozenset[str] | None = jinja.template_config_variables(
self._stylesheet)
else:
self._options = None

View File

@ -32,7 +32,7 @@ class UserAgent:
upstream_browser_key: str
upstream_browser_version: str
qt_key: str
qt_version: Optional[str]
qt_version: str | None
@property
def upstream_browser_version_short(self) -> str:
@ -123,7 +123,7 @@ class AbstractSettings:
info = self._ATTRIBUTES[name]
return self._settings.testAttribute(info.attributes[0])
def set_font_size(self, name: str, value: Union[int, usertypes.Unset]) -> None:
def set_font_size(self, name: str, value: int | usertypes.Unset) -> None:
"""Set the given QWebSettings/QWebEngineSettings font size."""
family = self._FONT_SIZES[name]
if value is usertypes.UNSET:
@ -134,7 +134,7 @@ class AbstractSettings:
def set_font_family(
self,
name: str,
value: Union[str, None, usertypes.Unset],
value: str | None | usertypes.Unset,
) -> None:
"""Set the given QWebSettings/QWebEngineSettings font family.
@ -152,7 +152,7 @@ class AbstractSettings:
else:
self._settings.setFontFamily(family, value)
def set_default_text_encoding(self, encoding: Union[str, usertypes.Unset]) -> None:
def set_default_text_encoding(self, encoding: str | usertypes.Unset) -> None:
"""Set the default text encoding to use."""
assert encoding is not usertypes.UNSET # unclear how to reset
self._settings.setDefaultTextEncoding(encoding)

View File

@ -55,7 +55,7 @@ class Request:
"""A request which can be intercepted/blocked."""
#: The URL of the page being shown.
first_party_url: Optional[QUrl]
first_party_url: QUrl | None
#: The URL of the file being requested.
request_url: QUrl
@ -63,7 +63,7 @@ class Request:
is_blocked: bool = False
#: The resource type of the request. None if not supported on this backend.
resource_type: Optional[ResourceType] = None
resource_type: ResourceType | None = None
def block(self) -> None:
"""Block this request."""

View File

@ -47,10 +47,10 @@ class ModuleInfo:
"""
skip_hooks: bool = False
init_hook: Optional[InitHookType] = None
init_hook: InitHookType | None = None
config_changed_hooks: list[
tuple[
Optional[str],
str | None,
ConfigChangedHookType,
]
] = dataclasses.field(default_factory=list)

View File

@ -25,7 +25,7 @@ class MatchResult:
"""The result of matching a keybinding."""
match_type: QKeySequence.SequenceMatch
command: Optional[str]
command: str | None
sequence: keyutils.KeySequence
def __post_init__(self) -> None:
@ -63,7 +63,7 @@ class BindingTrie:
def __init__(self) -> None:
self.children: MutableMapping[keyutils.KeyInfo, BindingTrie] = {}
self.command: Optional[str] = None
self.command: str | None = None
def __setitem__(self, sequence: keyutils.KeySequence,
command: str) -> None:

View File

@ -62,7 +62,7 @@ class EventFilter(QObject):
# No window available yet, or not a MainWindow
return False
def eventFilter(self, obj: Optional[QObject], event: Optional[QEvent]) -> bool:
def eventFilter(self, obj: QObject | None, event: QEvent | None) -> bool:
"""Handle an event.
Args:

View File

@ -52,7 +52,7 @@ _MODIFIER_MAP = {
}
try:
_NIL_KEY: Union[Qt.Key, int] = Qt.Key(0)
_NIL_KEY: Qt.Key | int = Qt.Key(0)
except ValueError:
# WORKAROUND for
# https://www.riverbankcomputing.com/pipermail/pyqt/2022-April/044607.html
@ -63,7 +63,7 @@ if machinery.IS_QT6:
_ModifierType = Qt.KeyboardModifier
else:
_KeyInfoType = int
_ModifierType = Union[Qt.KeyboardModifiers, Qt.KeyboardModifier]
_ModifierType = Qt.KeyboardModifiers | Qt.KeyboardModifier
_SPECIAL_NAMES = {
@ -203,7 +203,7 @@ def _remap_unicode(key: Qt.Key, text: str) -> Qt.Key:
return key
def _check_valid_utf8(s: str, data: Union[Qt.Key, _ModifierType]) -> None:
def _check_valid_utf8(s: str, data: Qt.Key | _ModifierType) -> None:
"""Make sure the given string is valid UTF-8.
Makes sure there are no chars where Qt did fall back to weird UTF-16
@ -259,7 +259,7 @@ class KeyParseError(Exception):
"""Raised by _parse_single_key/parse_keystring on parse errors."""
def __init__(self, keystr: Optional[str], error: str) -> None:
def __init__(self, keystr: str | None, error: str) -> None:
if keystr is None:
msg = "Could not parse keystring: {}".format(error)
else:
@ -593,7 +593,7 @@ class KeySequence:
def __getitem__(self, item: slice) -> 'KeySequence':
...
def __getitem__(self, item: Union[int, slice]) -> Union[KeyInfo, 'KeySequence']:
def __getitem__(self, item: int | slice) -> Union[KeyInfo, 'KeySequence']:
infos = list(self)
if isinstance(item, slice):
return self.__class__(*infos[item])

View File

@ -33,9 +33,9 @@ class MacroRecorder:
def __init__(self) -> None:
self._macros: dict[str, list[_CommandType]] = {}
self._recording_macro: Optional[str] = None
self._recording_macro: str | None = None
self._macro_count: dict[int, int] = {}
self._last_register: Optional[str] = None
self._last_register: str | None = None
@cmdutils.register(instance='macro-recorder')
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)

View File

@ -185,7 +185,7 @@ def init(win_id: int, parent: QObject) -> 'ModeManager':
return modeman
def instance(win_id: Union[int, str]) -> 'ModeManager':
def instance(win_id: int | str) -> 'ModeManager':
"""Get a modemanager object.
Raises UnavailableError if there is no instance available yet.

View File

@ -184,8 +184,8 @@ class MainWindow(QWidget):
def __init__(self, *,
private: bool,
geometry: Optional[QByteArray] = None,
parent: Optional[QWidget] = None) -> None:
geometry: QByteArray | None = None,
parent: QWidget | None = None) -> None:
"""Create a new main window.
Args:

View File

@ -22,7 +22,7 @@ class Message(QLabel):
self,
level: usertypes.MessageLevel,
text: str,
replace: Optional[str],
replace: str | None,
text_format: Qt.TextFormat,
parent: QWidget = None,
) -> None:

View File

@ -270,7 +270,7 @@ class PromptContainer(QWidget):
self._layout = QVBoxLayout(self)
self._layout.setContentsMargins(10, 10, 10, 10)
self._win_id = win_id
self._prompt: Optional[_BasePrompt] = None
self._prompt: _BasePrompt | None = None
self.setObjectName('PromptContainer')
self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)

View File

@ -238,7 +238,7 @@ class Command(misc.CommandLineEdit):
self.clear_completion_selection.emit()
self.hide_completion.emit()
def setText(self, text: Optional[str]) -> None:
def setText(self, text: str | None) -> None:
"""Extend setText to set prefix and make sure the prompt is ok."""
if not text:
pass
@ -252,7 +252,7 @@ class Command(misc.CommandLineEdit):
text = cast(str, text)
super().setText(text)
def keyPressEvent(self, e: Optional[QKeyEvent]) -> None:
def keyPressEvent(self, e: QKeyEvent | None) -> None:
"""Override keyPressEvent to ignore Return key presses, and add Shift-Ins.
If this widget is focused, we are in passthrough key mode, and

View File

@ -85,7 +85,7 @@ class TabDeque:
Throws IndexError on failure.
"""
tab: Optional[browsertab.AbstractTab] = None
tab: browsertab.AbstractTab | None = None
while tab is None or tab.pending_removal or tab is cur_tab:
tab = self._stack.pop()()
self._stack_deleted.append(weakref.ref(cur_tab))
@ -102,7 +102,7 @@ class TabDeque:
Throws IndexError on failure.
"""
tab: Optional[browsertab.AbstractTab] = None
tab: browsertab.AbstractTab | None = None
while tab is None or tab.pending_removal or tab is cur_tab:
tab = self._stack_deleted.pop()()
# On next tab-switch, current tab will be added to stack as normal.
@ -397,7 +397,7 @@ class TabbedBrowser(QWidget):
assert window is not None
return window
def _tab_by_idx(self, idx: int) -> Optional[browsertab.AbstractTab]:
def _tab_by_idx(self, idx: int) -> browsertab.AbstractTab | None:
"""Get a browser tab by index.
If no tab was found at the given index, None is returned.

View File

@ -79,7 +79,7 @@ class TabWidget(QTabWidget):
assert isinstance(bar, TabBar), bar
return bar
def _tab_by_idx(self, idx: int) -> Optional[browsertab.AbstractTab]:
def _tab_by_idx(self, idx: int) -> browsertab.AbstractTab | None:
"""Get the tab at the given index."""
tab = self.widget(idx)
if tab is not None:

View File

@ -154,8 +154,8 @@ class _BackendImports:
"""Whether backend modules could be imported."""
webkit_error: Optional[str] = None
webengine_error: Optional[str] = None
webkit_error: str | None = None
webengine_error: str | None = None
class _BackendProblemChecker:

View File

@ -323,10 +323,10 @@ class SignalHandler(QObject):
self._timer = usertypes.Timer(self, 'python_hacks')
self._orig_handlers: MutableMapping[int, 'signal._HANDLER'] = {}
self._activated = False
self._orig_wakeup_fd: Optional[int] = None
self._orig_wakeup_fd: int | None = None
self._handlers: dict[
signal.Signals, Callable[[int, Optional[types.FrameType]], None]
signal.Signals, Callable[[int, types.FrameType | None], None]
] = {
signal.SIGINT: self.interrupt,
signal.SIGTERM: self.interrupt,

View File

@ -22,7 +22,7 @@ _CACHE_FUNCTIONS: MutableMapping[str, Any] = weakref.WeakValueDictionary()
_T = TypeVar('_T', bound=Callable[..., Any])
def register(name: Optional[str] = None) -> Callable[[_T], _T]:
def register(name: str | None = None) -> Callable[[_T], _T]:
"""Register a lru_cache wrapped function for debug_cache_stats."""
def wrapper(fn: _T) -> _T:
fn_name = fn.__name__ if name is None else name

View File

@ -289,7 +289,7 @@ def _parse_from_file(f: IO[bytes]) -> Versions:
return _find_versions(data)
def parse_webenginecore() -> Optional[Versions]:
def parse_webenginecore() -> Versions | None:
"""Parse the QtWebEngineCore library file."""
if version.is_flatpak():
# Flatpak has Qt in /usr/lib/x86_64-linux-gnu, but QtWebEngine in /app/lib.

View File

@ -21,7 +21,7 @@ from qutebrowser.completion.models import miscmodels
all_processes: dict[int, Optional['GUIProcess']] = {}
last_pid: Optional[int] = None
last_pid: int | None = None
@cmdutils.register()
@ -71,8 +71,8 @@ class ProcessOutcome:
what: str
running: bool = False
status: Optional[QProcess.ExitStatus] = None
code: Optional[int] = None
status: QProcess.ExitStatus | None = None
code: int | None = None
def was_successful(self) -> bool:
"""Whether the process exited successfully.
@ -95,7 +95,7 @@ class ProcessOutcome:
self.code == signal.SIGTERM
)
def _crash_signal(self) -> Optional[signal.Signals]:
def _crash_signal(self) -> signal.Signals | None:
"""Get a Python signal (e.g. signal.SIGTERM) from a crashed process."""
assert self.status == QProcess.ExitStatus.CrashExit
if self.code is None:
@ -185,10 +185,10 @@ class GUIProcess(QObject):
self.verbose = verbose
self._output_messages = output_messages
self.outcome = ProcessOutcome(what=what)
self.cmd: Optional[str] = None
self.resolved_cmd: Optional[str] = None
self.args: Optional[Sequence[str]] = None
self.pid: Optional[int] = None
self.cmd: str | None = None
self.resolved_cmd: str | None = None
self.args: Sequence[str] | None = None
self.pid: int | None = None
self.stdout: str = ""
self.stderr: str = ""

View File

@ -176,7 +176,7 @@ class IPCServer(QObject):
self._atime_timer.timeout.connect(self.update_atime)
self._atime_timer.setTimerType(Qt.TimerType.VeryCoarseTimer)
self._server: Optional[QLocalServer] = QLocalServer(self)
self._server: QLocalServer | None = QLocalServer(self)
self._server.newConnection.connect(self.handle_connection)
self._socket = None

View File

@ -192,8 +192,8 @@ class WrapperLayout(QLayout):
def __init__(self, parent=None):
super().__init__(parent)
self._widget: Optional[QWidget] = None
self._container: Optional[QWidget] = None
self._widget: QWidget | None = None
self._container: QWidget | None = None
def addItem(self, _widget):
raise utils.Unreachable
@ -310,10 +310,10 @@ class InspectorSplitter(QSplitter):
self.addWidget(main_webview)
self.setFocusProxy(main_webview)
self.splitterMoved.connect(self._on_splitter_moved)
self._main_idx: Optional[int] = None
self._inspector_idx: Optional[int] = None
self._position: Optional[inspector.Position] = None
self._preferred_size: Optional[int] = None
self._main_idx: int | None = None
self._inspector_idx: int | None = None
self._position: inspector.Position | None = None
self._preferred_size: int | None = None
def cycle_focus(self):
"""Cycle keyboard focus between the main/inspector widget."""
@ -439,7 +439,7 @@ class InspectorSplitter(QSplitter):
self._preferred_size = sizes[self._inspector_idx]
self._save_preferred_size()
def resizeEvent(self, e: Optional[QResizeEvent]) -> None:
def resizeEvent(self, e: QResizeEvent | None) -> None:
"""Window resize event."""
assert e is not None
super().resizeEvent(e)

View File

@ -138,8 +138,8 @@ class NativeEventFilter(QAbstractNativeEventFilter):
def nativeEventFilter(
self,
evtype: Union[QByteArray, bytes, bytearray, memoryview],
message: Optional[sip.voidptr],
evtype: QByteArray | bytes | bytearray | memoryview,
message: sip.voidptr | None,
) -> tuple[bool, _PointerRetType]:
"""Handle XCB events."""
# We're only installed when the platform plugin is xcb

View File

@ -124,7 +124,7 @@ class PakParser:
except ValueError:
raise binparsing.ParseError("Couldn't find URL in manifest")
def _maybe_get_hangouts_manifest(self, entry: PakEntry) -> Optional[bytes]:
def _maybe_get_hangouts_manifest(self, entry: PakEntry) -> bytes | None:
self.fobj.seek(entry.file_offset)
data = self.fobj.read(entry.size)
@ -207,7 +207,7 @@ def _find_webengine_resources() -> pathlib.Path:
f"Couldn't find webengine resources dir, candidates:\n{candidates_str}")
def copy_webengine_resources() -> Optional[pathlib.Path]:
def copy_webengine_resources() -> pathlib.Path | None:
"""Copy qtwebengine resources to local dir for patching."""
resources_dir = _find_webengine_resources()
work_dir = pathlib.Path(standarddir.cache()) / CACHE_DIR_NAME
@ -262,7 +262,7 @@ def _patch(file_to_patch: pathlib.Path) -> None:
_error(e, "Failed to apply quirk to resources pak.")
def _error(exc: Optional[BaseException], text: str) -> None:
def _error(exc: BaseException | None, text: str) -> None:
if config.val.qt.workarounds.disable_hangouts_extension:
# Explicitly requested -> hard error
lines = ["Failed to disable Hangouts extension:", text]

View File

@ -37,7 +37,7 @@ class Sentinel:
default = Sentinel()
session_manager = cast('SessionManager', None)
ArgType = Union[str, Sentinel]
ArgType = str | Sentinel
def init(parent=None):
@ -63,7 +63,7 @@ def init(parent=None):
session_manager = SessionManager(str(base_path), parent)
def shutdown(session: Optional[ArgType], last_window: bool) -> None:
def shutdown(session: ArgType | None, last_window: bool) -> None:
"""Handle a shutdown by saving sessions and removing the autosave file."""
if session_manager is None:
return # type: ignore[unreachable]
@ -136,7 +136,7 @@ class SessionManager(QObject):
def __init__(self, base_path, parent=None):
super().__init__(parent)
self.current: Optional[str] = None
self.current: str | None = None
self._base_path = base_path
self._last_window_session = None
self.did_load = False
@ -436,7 +436,7 @@ class SessionManager(QObject):
orig_url = url
if histentry.get("last_visited"):
last_visited: Optional[QDateTime] = QDateTime.fromString(
last_visited: QDateTime | None = QDateTime.fromString(
histentry.get("last_visited"),
Qt.DateFormat.ISODate,
)

View File

@ -101,7 +101,7 @@ class Error(Exception):
"""Base class for all SQL related errors."""
def __init__(self, msg: str, error: Optional[QSqlError] = None) -> None:
def __init__(self, msg: str, error: QSqlError | None = None) -> None:
super().__init__(msg)
self.error = error
@ -135,7 +135,7 @@ class BugError(Error):
def raise_sqlite_error(msg: str, error: QSqlError) -> None:
"""Raise either a BugError or KnownError."""
error_code = error.nativeErrorCode()
primary_error_code: Union[SqliteErrorCode, str]
primary_error_code: SqliteErrorCode | str
try:
# https://sqlite.org/rescode.html#pve
primary_error_code = SqliteErrorCode(int(error_code) & 0xff)
@ -228,8 +228,8 @@ class Database:
return Query(self, querystr, forward_only)
def table(self, name: str, fields: list[str],
constraints: Optional[dict[str, str]] = None,
parent: Optional[QObject] = None) -> 'SqlTable':
constraints: dict[str, str] | None = None,
parent: QObject | None = None) -> 'SqlTable':
"""Return a SqlTable instance linked to this Database."""
return SqlTable(self, name, fields, constraints, parent)
@ -277,9 +277,9 @@ class Transaction(contextlib.AbstractContextManager): # type: ignore[type-arg]
raise_sqlite_error(msg, error)
def __exit__(self,
_exc_type: Optional[type[BaseException]],
exc_val: Optional[BaseException],
_exc_tb: Optional[types.TracebackType]) -> None:
_exc_type: type[BaseException] | None,
exc_val: BaseException | None,
_exc_tb: types.TracebackType | None) -> None:
db = self._database.qt_database()
if exc_val:
log.sql.debug('Rolling back a transaction')
@ -428,8 +428,8 @@ class SqlTable(QObject):
database: Database
def __init__(self, database: Database, name: str, fields: list[str],
constraints: Optional[dict[str, str]] = None,
parent: Optional[QObject] = None) -> None:
constraints: dict[str, str] | None = None,
parent: QObject | None = None) -> None:
"""Wrapper over a table in the SQL database.
Args:
@ -443,7 +443,7 @@ class SqlTable(QObject):
self.database = database
self._create_table(fields, constraints)
def _create_table(self, fields: list[str], constraints: Optional[dict[str, str]],
def _create_table(self, fields: list[str], constraints: dict[str, str] | None,
*, force: bool = False) -> None:
"""Create the table if the database is uninitialized.

View File

@ -45,8 +45,8 @@ class Throttle(QObject):
super().__init__(parent)
self._delay_ms = delay_ms
self._func = func
self._pending_call: Optional[_CallArgs] = None
self._last_call_ms: Optional[int] = None
self._pending_call: _CallArgs | None = None
self._last_call_ms: int | None = None
self._timer = usertypes.Timer(self, 'throttle-timer')
self._timer.setSingleShot(True)

View File

@ -264,7 +264,7 @@ def version(win_id: int, paste: bool = False) -> None:
pastebin_version()
_keytester_widget: Optional[miscwidgets.KeyTesterWidget] = None
_keytester_widget: miscwidgets.KeyTesterWidget | None = None
@cmdutils.register(debug=True)

View File

@ -105,7 +105,7 @@ class SelectionReason(enum.Enum):
class SelectionInfo:
"""Information about outcomes of importing Qt wrappers."""
wrapper: Optional[str] = None
wrapper: str | None = None
outcomes: dict[str, str] = dataclasses.field(default_factory=dict)
reason: SelectionReason = SelectionReason.unknown
@ -164,7 +164,7 @@ def _autoselect_wrapper() -> SelectionInfo:
return info
def _select_wrapper(args: Optional[argparse.Namespace]) -> SelectionInfo:
def _select_wrapper(args: argparse.Namespace | None) -> SelectionInfo:
"""Select a Qt wrapper.
- If --qt-wrapper is given, use that.

View File

@ -40,7 +40,7 @@ def log_events(klass: type[QObject]) -> type[QObject]:
return klass
def log_signals(obj: Union[QObject, type[QObject]]) -> Union[QObject, type[QObject]]:
def log_signals(obj: QObject | type[QObject]) -> QObject | type[QObject]:
"""Log all signals of an object or class.
Can be used as class decorator.
@ -89,15 +89,15 @@ def log_signals(obj: Union[QObject, type[QObject]]) -> Union[QObject, type[QObje
if machinery.IS_QT6:
_EnumValueType = Union[enum.Enum, int]
_EnumValueType = enum.Enum | int
else:
_EnumValueType = Union[sip.simplewrapper, int]
_EnumValueType = sip.simplewrapper | int
def _qenum_key_python(
value: _EnumValueType,
klass: type[_EnumValueType],
) -> Optional[str]:
) -> str | None:
"""New-style PyQt6: Try getting value from Python enum."""
if isinstance(value, enum.Enum) and value.name:
return value.name
@ -119,7 +119,7 @@ def _qenum_key_qt(
base: type[sip.simplewrapper],
value: _EnumValueType,
klass: type[_EnumValueType],
) -> Optional[str]:
) -> str | None:
# On PyQt5, or PyQt6 with int passed: Try to ask Qt's introspection.
# However, not every Qt enum value has a staticMetaObject
try:
@ -308,7 +308,7 @@ class log_time: # noqa: N801,N806 pylint: disable=invalid-name
Usable as context manager or as decorator.
"""
def __init__(self, logger: Union[logging.Logger, str],
def __init__(self, logger: logging.Logger | str,
action: str = 'operation') -> None:
"""Constructor.
@ -320,16 +320,16 @@ class log_time: # noqa: N801,N806 pylint: disable=invalid-name
self._logger = logging.getLogger(logger)
else:
self._logger = logger
self._started: Optional[datetime.datetime] = None
self._started: datetime.datetime | None = None
self._action = action
def __enter__(self) -> None:
self._started = datetime.datetime.now()
def __exit__(self,
_exc_type: Optional[type[BaseException]],
_exc_val: Optional[BaseException],
_exc_tb: Optional[types.TracebackType]) -> None:
_exc_type: type[BaseException] | None,
_exc_val: BaseException | None,
_exc_tb: types.TracebackType | None) -> None:
assert self._started is not None
finished = datetime.datetime.now()
delta = (finished - self._started).total_seconds()

View File

@ -81,11 +81,11 @@ class DocstringParser:
func: The function to parse the docstring for.
"""
self._state = self.State.short
self._cur_arg_name: Optional[str] = None
self._cur_arg_name: str | None = None
self._short_desc_parts: list[str] = []
self._long_desc_parts: list[str] = []
self.arg_descs: MutableMapping[
str, Union[str, list[str]]] = collections.OrderedDict()
str, str | list[str]] = collections.OrderedDict()
doc = inspect.getdoc(func)
handlers = {
self.State.short: self._parse_short,

View File

@ -7,8 +7,8 @@
from typing import Union
from collections.abc import Sequence
_InnerJsArgType = Union[None, str, bool, int, float]
_JsArgType = Union[_InnerJsArgType, Sequence[_InnerJsArgType]]
_InnerJsArgType = None | str | bool | int | float
_JsArgType = _InnerJsArgType | Sequence[_InnerJsArgType]
def string_escape(text: str) -> str:

View File

@ -32,7 +32,7 @@ if TYPE_CHECKING:
from qutebrowser.config import config as configmodule
_log_inited = False
_args: Optional[argparse.Namespace] = None
_args: argparse.Namespace | None = None
COLORS = ['black', 'red', 'green', 'yellow', 'blue', 'purple', 'cyan', 'white']
COLOR_ESCAPES = {color: '\033[{}m'.format(i)
@ -146,7 +146,7 @@ LOGGER_NAMES = [
ram_handler: Optional['RAMHandler'] = None
console_handler: Optional[logging.Handler] = None
console_handler: logging.Handler | None = None
console_filter: Optional["LogFilter"] = None
@ -426,7 +426,7 @@ class LogFilter(logging.Filter):
self.only_debug = only_debug
@classmethod
def parse(cls, filter_str: Optional[str], *,
def parse(cls, filter_str: str | None, *,
only_debug: bool = True) -> 'LogFilter':
"""Parse a log filter from a string."""
if filter_str is None or filter_str == 'none':
@ -480,7 +480,7 @@ class RAMHandler(logging.Handler):
def __init__(self, capacity: int) -> None:
super().__init__()
self.html_formatter: Optional[HTMLFormatter] = None
self.html_formatter: HTMLFormatter | None = None
if capacity != -1:
self._data: MutableSequence[logging.LogRecord] = collections.deque(
maxlen=capacity

View File

@ -25,7 +25,7 @@ class MessageInfo:
level: usertypes.MessageLevel
text: str
replace: Optional[str] = None
replace: str | None = None
rich: bool = False
@ -108,7 +108,7 @@ def info(message: str, *, replace: str = None, rich: bool = False) -> None:
def _build_question(title: str,
text: str = None, *,
mode: usertypes.PromptMode,
default: Union[None, bool, str] = None,
default: None | bool | str = None,
abort_on: Iterable[pyqtBoundSignal] = (),
url: str = None,
option: bool = None) -> usertypes.Question:

View File

@ -20,7 +20,7 @@ if TYPE_CHECKING:
from qutebrowser.mainwindow import mainwindow
_WindowTab = Union[str, int, None]
_WindowTab = str | int | None
class RegistryUnavailableError(Exception):
@ -38,7 +38,7 @@ class CommandOnlyError(Exception):
"""Raised when an object is requested which is used for commands only."""
_IndexType = Union[str, int]
_IndexType = str | int
# UserDict is only generic in Python 3.9+
@ -153,7 +153,7 @@ def _get_tab_registry(win_id: _WindowTab,
if tab_id is None:
raise ValueError("Got tab_id None (win_id {})".format(win_id))
if tab_id == 'current' and win_id is None:
window: Optional[QWidget] = QApplication.activeWindow()
window: QWidget | None = QApplication.activeWindow()
if window is None or not hasattr(window, 'win_id'):
raise RegistryUnavailableError('tab')
win_id = window.win_id
@ -179,7 +179,7 @@ def _get_window_registry(window: _WindowTab) -> ObjectRegistry:
raise TypeError("window is None with scope window!")
try:
if window == 'current':
win: Optional[QWidget] = QApplication.activeWindow()
win: QWidget | None = QApplication.activeWindow()
elif window == 'last-focused':
win = last_focused_window()
else:

View File

@ -16,7 +16,7 @@ from collections.abc import Iterator
from qutebrowser.qt import core as qtcore
from qutebrowser.utils import log
_args: Optional[argparse.Namespace] = None
_args: argparse.Namespace | None = None
def init(args: argparse.Namespace) -> None:
@ -43,7 +43,7 @@ def disable_qt_msghandler() -> Iterator[None]:
def qt_message_handler(msg_type: qtcore.QtMsgType,
context: qtcore.QMessageLogContext,
msg: Optional[str]) -> None:
msg: str | None) -> None:
"""Qt message handler to redirect qWarning etc. to the logging system.
Args:
@ -179,7 +179,7 @@ def qt_message_handler(msg_type: qtcore.QtMsgType,
assert _args is not None
if _args.debug:
stack: Optional[str] = ''.join(traceback.format_stack())
stack: str | None = ''.join(traceback.format_stack())
else:
stack = None

View File

@ -62,7 +62,7 @@ class QtOSError(OSError):
if msg is None:
msg = dev.errorString()
self.qt_errno: Optional[QFileDevice.FileError] = None
self.qt_errno: QFileDevice.FileError | None = None
if isinstance(dev, QFileDevice):
msg = self._init_filedev(dev, msg)
@ -271,7 +271,7 @@ def savefile_open(
filename: str,
binary: bool = False,
encoding: str = 'utf-8'
) -> Iterator[Union[IO[str], IO[bytes]]]:
) -> Iterator[IO[str] | IO[bytes]]:
"""Context manager to easily use a QSaveFile."""
f = QSaveFile(filename)
cancelled = False
@ -283,7 +283,7 @@ def savefile_open(
dev = cast(BinaryIO, PyQIODevice(f))
if binary:
new_f: Union[IO[str], IO[bytes]] = dev
new_f: IO[str] | IO[bytes] = dev
else:
new_f = io.TextIOWrapper(dev, encoding=encoding)
@ -405,7 +405,7 @@ class PyQIODevice(io.BufferedIOBase):
def readable(self) -> bool:
return self.dev.isReadable()
def readline(self, size: Optional[int] = -1) -> bytes:
def readline(self, size: int | None = -1) -> bytes:
self._check_open()
self._check_readable()
@ -416,7 +416,7 @@ class PyQIODevice(io.BufferedIOBase):
else:
qt_size = size + 1 # Qt also counts the NUL byte
buf: Union[QByteArray, bytes, None] = None
buf: QByteArray | bytes | None = None
if self.dev.canReadLine():
if qt_size is None:
buf = self.dev.readLine()
@ -450,7 +450,7 @@ class PyQIODevice(io.BufferedIOBase):
def write( # type: ignore[override]
self,
data: Union[bytes, bytearray]
data: bytes | bytearray
) -> int:
self._check_open()
self._check_writable()
@ -459,11 +459,11 @@ class PyQIODevice(io.BufferedIOBase):
raise QtOSError(self.dev)
return num
def read(self, size: Optional[int] = None) -> bytes:
def read(self, size: int | None = None) -> bytes:
self._check_open()
self._check_readable()
buf: Union[QByteArray, bytes, None] = None
buf: QByteArray | bytes | None = None
if size in [None, -1]:
buf = self.dev.readAll()
else:
@ -499,8 +499,9 @@ class QtValueError(ValueError):
if machinery.IS_QT6:
_ProcessEventFlagType = QEventLoop.ProcessEventsFlag
else:
_ProcessEventFlagType = Union[
QEventLoop.ProcessEventsFlag, QEventLoop.ProcessEventsFlags]
_ProcessEventFlagType = (
QEventLoop.ProcessEventsFlag
| QEventLoop.ProcessEventsFlags )
class EventLoop(QEventLoop):
@ -559,7 +560,7 @@ def interpolate_color(
start: QColor,
end: QColor,
percent: int,
colorspace: Optional[QColor.Spec] = QColor.Spec.Rgb
colorspace: QColor.Spec | None = QColor.Spec.Rgb
) -> QColor:
"""Get an interpolated color value.
@ -677,7 +678,7 @@ def library_path(which: LibraryPath) -> pathlib.Path:
return pathlib.Path(ret)
def extract_enum_val(val: Union[sip.simplewrapper, int, enum.Enum]) -> int:
def extract_enum_val(val: sip.simplewrapper | int | enum.Enum) -> int:
"""Extract an int value from a Qt enum value.
For Qt 5, enum values are basically Python integers.
@ -691,7 +692,7 @@ def extract_enum_val(val: Union[sip.simplewrapper, int, enum.Enum]) -> int:
return val
def qobj_repr(obj: Optional[QObject]) -> str:
def qobj_repr(obj: QObject | None) -> str:
"""Show nicer debug information for a QObject."""
py_repr = repr(obj)
if obj is None:
@ -731,21 +732,21 @@ if machinery.IS_QT5:
# Also we have a special QT_NONE, which (being Any) we can pass to functions
# where PyQt type hints claim that it's not allowed.
def remove_optional(obj: Optional[_T]) -> _T:
def remove_optional(obj: _T | None) -> _T:
return cast(_T, obj)
def add_optional(obj: _T) -> Optional[_T]:
return cast(Optional[_T], obj)
def add_optional(obj: _T) -> _T | None:
return cast(_T | None, obj)
QT_NONE: Any = None
else:
# On Qt 6, all those things are handled correctly by type annotations, so we
# have a no-op below.
def remove_optional(obj: Optional[_T]) -> Optional[_T]:
def remove_optional(obj: _T | None) -> _T | None:
return obj
def add_optional(obj: Optional[_T]) -> Optional[_T]:
def add_optional(obj: _T | None) -> _T | None:
return obj
QT_NONE: None = None

View File

@ -24,7 +24,7 @@ _cache: dict[str, str] = {}
_bin_cache: dict[str, bytes] = {}
_ResourceType = Union[Traversable, pathlib.Path]
_ResourceType = Traversable | pathlib.Path
def _path(filename: str) -> _ResourceType:

View File

@ -62,7 +62,7 @@ def _unset_organization() -> Iterator[None]:
qapp.setOrganizationName(orgname)
def _init_config(args: Optional[argparse.Namespace]) -> None:
def _init_config(args: argparse.Namespace | None) -> None:
"""Initialize the location for configs."""
typ = QStandardPaths.StandardLocation.ConfigLocation
path = _from_args(typ, args)
@ -113,7 +113,7 @@ def config_py() -> str:
return _locations[_Location.config_py]
def _init_data(args: Optional[argparse.Namespace]) -> None:
def _init_data(args: argparse.Namespace | None) -> None:
"""Initialize the location for data."""
typ = QStandardPaths.StandardLocation.AppDataLocation
path = _from_args(typ, args)
@ -154,7 +154,7 @@ def data(system: bool = False) -> str:
return _locations[_Location.data]
def _init_cache(args: Optional[argparse.Namespace]) -> None:
def _init_cache(args: argparse.Namespace | None) -> None:
"""Initialize the location for the cache."""
typ = QStandardPaths.StandardLocation.CacheLocation
path = _from_args(typ, args)
@ -174,7 +174,7 @@ def cache() -> str:
return _locations[_Location.cache]
def _init_download(args: Optional[argparse.Namespace]) -> None:
def _init_download(args: argparse.Namespace | None) -> None:
"""Initialize the location for downloads.
Note this is only the default directory as found by Qt.
@ -191,7 +191,7 @@ def download() -> str:
return _locations[_Location.download]
def _init_runtime(args: Optional[argparse.Namespace]) -> None:
def _init_runtime(args: argparse.Namespace | None) -> None:
"""Initialize location for runtime data."""
if utils.is_mac or utils.is_windows:
# RuntimeLocation is a weird path on macOS and Windows.
@ -277,8 +277,8 @@ def _writable_location(typ: QStandardPaths.StandardLocation) -> str:
def _from_args(
typ: QStandardPaths.StandardLocation,
args: Optional[argparse.Namespace]
) -> Optional[str]:
args: argparse.Namespace | None
) -> str | None:
"""Get the standard directory from an argparse namespace.
Return:
@ -337,7 +337,7 @@ def _init_dirs(args: argparse.Namespace = None) -> None:
_init_runtime(args)
def init(args: Optional[argparse.Namespace]) -> None:
def init(args: argparse.Namespace | None) -> None:
"""Initialize all standard dirs."""
if args is not None:
# args can be None during tests

View File

@ -59,10 +59,10 @@ class UrlPattern:
self._pattern = pattern
self._match_all = False
self._match_subdomains: bool = False
self._scheme: Optional[str] = None
self.host: Optional[str] = None
self._path: Optional[str] = None
self._port: Optional[int] = None
self._scheme: str | None = None
self.host: str | None = None
self._path: str | None = None
self._port: int | None = None
# > The special pattern <all_urls> matches any URL that starts with a
# > permitted scheme.
@ -92,10 +92,10 @@ class UrlPattern:
def _to_tuple(self) -> tuple[
bool, # _match_all
bool, # _match_subdomains
Optional[str], # _scheme
Optional[str], # host
Optional[str], # _path
Optional[int], # _port
str | None, # _scheme
str | None, # host
str | None, # _path
int | None, # _port
]:
"""Get a pattern with information used for __eq__/__hash__."""
return (self._match_all, self._match_subdomains, self._scheme,

View File

@ -29,7 +29,7 @@ from qutebrowser.browser.network import pac
if machinery.IS_QT6:
UrlFlagsType = Union[QUrl.UrlFormattingOption, QUrl.ComponentFormattingOption]
UrlFlagsType = QUrl.UrlFormattingOption | QUrl.ComponentFormattingOption
class FormatOption:
"""Simple wrapper around Qt enums to fix typing problems on Qt 5."""
@ -42,12 +42,12 @@ if machinery.IS_QT6:
REMOVE_PASSWORD = QUrl.UrlFormattingOption.RemovePassword
REMOVE_QUERY = QUrl.UrlFormattingOption.RemoveQuery
else:
UrlFlagsType = Union[
QUrl.FormattingOptions,
QUrl.UrlFormattingOption,
QUrl.ComponentFormattingOption,
QUrl.ComponentFormattingOptions,
]
UrlFlagsType = (
QUrl.FormattingOptions
| QUrl.UrlFormattingOption
| QUrl.ComponentFormattingOption
| QUrl.ComponentFormattingOptions
)
class _QtFormattingOptions(QUrl.FormattingOptions):
"""WORKAROUND for invalid stubs.
@ -112,7 +112,7 @@ class InvalidUrlError(Error):
super().__init__(self.msg)
def _parse_search_term(s: str) -> tuple[Optional[str], Optional[str]]:
def _parse_search_term(s: str) -> tuple[str | None, str | None]:
"""Get a search engine name and search term from a string.
Args:
@ -128,8 +128,8 @@ def _parse_search_term(s: str) -> tuple[Optional[str], Optional[str]]:
if len(split) == 2:
if split[0] in config.val.url.searchengines:
engine: Optional[str] = split[0]
term: Optional[str] = split[1]
engine: str | None = split[0]
term: str | None = split[1]
else:
engine = None
term = s
@ -390,7 +390,7 @@ def raise_cmdexc_if_invalid(url: QUrl) -> None:
def get_path_if_valid(pathstr: str,
cwd: str = None,
relative: bool = False,
check_exists: bool = False) -> Optional[str]:
check_exists: bool = False) -> str | None:
"""Check if path is a valid path.
Args:
@ -408,7 +408,7 @@ def get_path_if_valid(pathstr: str,
expanded = os.path.expanduser(pathstr)
if os.path.isabs(expanded):
path: Optional[str] = expanded
path: str | None = expanded
elif relative and cwd:
path = os.path.join(cwd, expanded)
elif relative:
@ -435,7 +435,7 @@ def get_path_if_valid(pathstr: str,
return path
def filename_from_url(url: QUrl, fallback: str = None) -> Optional[str]:
def filename_from_url(url: QUrl, fallback: str = None) -> str | None:
"""Get a suitable filename from a URL.
Args:
@ -616,7 +616,7 @@ class InvalidProxyTypeError(Exception):
super().__init__("Invalid proxy type {}!".format(typ))
def proxy_from_url(url: QUrl) -> Union[QNetworkProxy, pac.PACFetcher]:
def proxy_from_url(url: QUrl) -> QNetworkProxy | pac.PACFetcher:
"""Create a QNetworkProxy from QUrl and a proxy type.
Args:

View File

@ -57,7 +57,7 @@ class NeighborList(Sequence[_T]):
exception = enum.auto()
def __init__(self, items: Sequence[_T] = None,
default: Union[_T, Unset] = UNSET,
default: _T | Unset = UNSET,
mode: Modes = Modes.exception) -> None:
"""Constructor.
@ -78,12 +78,12 @@ class NeighborList(Sequence[_T]):
if not isinstance(default, Unset):
idx = self._items.index(default)
self._idx: Optional[int] = idx
self._idx: int | None = idx
else:
self._idx = None
self._mode = mode
self.fuzzyval: Optional[int] = None
self.fuzzyval: int | None = None
def __getitem__(self, key: int) -> _T: # type: ignore[override]
return self._items[key]
@ -393,13 +393,13 @@ class Question(QObject):
def __init__(self, parent: QObject = None) -> None:
super().__init__(parent)
self.mode: Optional[PromptMode] = None
self.default: Union[bool, str, None] = None
self.title: Optional[str] = None
self.text: Optional[str] = None
self.url: Optional[str] = None
self.option: Optional[bool] = None
self.answer: Union[str, bool, None] = None
self.mode: PromptMode | None = None
self.default: bool | str | None = None
self.title: str | None = None
self.text: str | None = None
self.url: str | None = None
self.option: bool | None = None
self.answer: str | bool | None = None
self.is_aborted = False
self.interrupted = False
@ -446,7 +446,7 @@ class Timer(QTimer):
def __init__(self, parent: QObject = None, name: str = None) -> None:
super().__init__(parent)
self._start_time: Optional[float] = None
self._start_time: float | None = None
self.timeout.connect(self._validity_check_handler)
if name is None:
self._name = "unnamed"
@ -515,7 +515,7 @@ class AbstractCertificateErrorWrapper:
"""A wrapper over an SSL/certificate error."""
def __init__(self) -> None:
self._certificate_accepted: Optional[bool] = None
self._certificate_accepted: bool | None = None
def __str__(self) -> str:
raise NotImplementedError

View File

@ -40,7 +40,7 @@ except ImportError: # pragma: no cover
from qutebrowser.utils import log
fake_clipboard: Optional[str] = None
fake_clipboard: str | None = None
log_clipboard = False
is_mac = sys.platform.startswith('darwin')
@ -231,7 +231,7 @@ def format_seconds(total_seconds: int) -> str:
return prefix + ':'.join(chunks)
def format_size(size: Optional[float], base: int = 1024, suffix: str = '') -> str:
def format_size(size: float | None, base: int = 1024, suffix: str = '') -> str:
"""Format a byte size so it's human readable.
Inspired by https://stackoverflow.com/q/1094841
@ -408,7 +408,7 @@ def qualname(obj: Any) -> str:
return repr(obj)
_ExceptionType = Union[type[BaseException], tuple[type[BaseException]]]
_ExceptionType = type[BaseException] | tuple[type[BaseException]]
def raises(exc: _ExceptionType, func: Callable[..., Any], *args: Any) -> bool:
@ -439,7 +439,7 @@ def force_encoding(text: str, encoding: str) -> str:
def sanitize_filename(name: str,
replacement: Optional[str] = '_',
replacement: str | None = '_',
shorten: bool = False) -> str:
"""Replace invalid filename characters.
@ -647,7 +647,7 @@ def expand_windows_drive(path: str) -> str:
return path
def yaml_load(f: Union[str, IO[str]]) -> Any:
def yaml_load(f: str | IO[str]) -> Any:
"""Wrapper over yaml.load using the C loader if possible."""
start = datetime.datetime.now()
@ -687,7 +687,7 @@ def yaml_load(f: Union[str, IO[str]]) -> Any:
return data
def yaml_dump(data: Any, f: IO[str] = None) -> Optional[str]:
def yaml_dump(data: Any, f: IO[str] = None) -> str | None:
"""Wrapper over yaml.dump using the C dumper if possible.
Also returns a str instead of bytes.
@ -777,7 +777,7 @@ def parse_duration(duration: str) -> int:
return milliseconds
def mimetype_extension(mimetype: str) -> Optional[str]:
def mimetype_extension(mimetype: str) -> str | None:
"""Get a suitable extension for a given mimetype.
This mostly delegates to Python's mimetypes.guess_extension(), but backports some
@ -876,7 +876,7 @@ def parse_point(s: str) -> QPoint:
raise ValueError(e)
def match_globs(patterns: list[str], value: str) -> Optional[str]:
def match_globs(patterns: list[str], value: str) -> str | None:
"""Match a list of glob-like patterns against a value.
Return:

View File

@ -74,12 +74,12 @@ class DistributionInfo:
"""Information about the running distribution."""
id: Optional[str]
id: str | None
parsed: 'Distribution'
pretty: str
pastebin_url: Optional[str] = None
pastebin_url: str | None = None
class Distribution(enum.Enum):
@ -106,7 +106,7 @@ class Distribution(enum.Enum):
solus = enum.auto()
def _parse_os_release() -> Optional[dict[str, str]]:
def _parse_os_release() -> dict[str, str] | None:
"""Parse an /etc/os-release file."""
filename = os.environ.get('QUTE_FAKE_OS_RELEASE', '/etc/os-release')
info = {}
@ -124,7 +124,7 @@ def _parse_os_release() -> Optional[dict[str, str]]:
return info
def distribution() -> Optional[DistributionInfo]:
def distribution() -> DistributionInfo | None:
"""Get some information about the running Linux distribution.
Returns:
@ -178,7 +178,7 @@ def is_flatpak() -> bool:
_FLATPAK_INFO_PATH = '/.flatpak-info'
def flatpak_id() -> Optional[str]:
def flatpak_id() -> str | None:
"""Get the ID of the currently running Flatpak (or None if outside of Flatpak)."""
if 'FLATPAK_ID' in os.environ:
return os.environ['FLATPAK_ID']
@ -195,7 +195,7 @@ def flatpak_id() -> Optional[str]:
return parser['Application']['name']
def _git_str() -> Optional[str]:
def _git_str() -> str | None:
"""Try to find out git version.
Return:
@ -229,7 +229,7 @@ def _call_git(gitpath: str, *args: str) -> str:
stdout=subprocess.PIPE).stdout.decode('UTF-8').strip()
def _git_str_subprocess(gitpath: str) -> Optional[str]:
def _git_str_subprocess(gitpath: str) -> str | None:
"""Try to get the git commit ID and timestamp by calling git.
Args:
@ -296,13 +296,13 @@ class ModuleInfo:
self,
name: str,
version_attributes: Sequence[str],
min_version: Optional[str] = None
min_version: str | None = None
):
self.name = name
self._version_attributes = version_attributes
self.min_version = min_version
self._installed = False
self._version: Optional[str] = None
self._version: str | None = None
self._initialized = False
def _reset_cache(self) -> None:
@ -341,7 +341,7 @@ class ModuleInfo:
self._initialized = True
def get_version(self) -> Optional[str]:
def get_version(self) -> str | None:
"""Finds the module version if it exists."""
if not self._initialized:
self._initialize_info()
@ -353,7 +353,7 @@ class ModuleInfo:
self._initialize_info()
return self._installed
def is_outdated(self) -> Optional[bool]:
def is_outdated(self) -> bool | None:
"""Checks whether the module is outdated.
Return:
@ -505,7 +505,7 @@ def _pdfjs_version() -> str:
return '{} ({})'.format(pdfjs_version, file_path)
def _get_pyqt_webengine_qt_version() -> Optional[str]:
def _get_pyqt_webengine_qt_version() -> str | None:
"""Get the version of the PyQtWebEngine-Qt package.
With PyQtWebEngine 5.15.3, the QtWebEngine binary got split into its own
@ -541,10 +541,10 @@ class WebEngineVersions:
"""Version numbers for QtWebEngine and the underlying Chromium."""
webengine: utils.VersionNumber
chromium: Optional[str]
chromium: str | None
source: str
chromium_security: Optional[str] = None
chromium_major: Optional[int] = dataclasses.field(init=False)
chromium_security: str | None = None
chromium_major: int | None = dataclasses.field(init=False)
# Dates based on https://chromium.googlesource.com/chromium/src/+refs
_BASES: ClassVar[dict[int, str]] = {
@ -563,7 +563,7 @@ class WebEngineVersions:
}
# Dates based on https://chromereleases.googleblog.com/
_CHROMIUM_VERSIONS: ClassVar[dict[utils.VersionNumber, tuple[str, Optional[str]]]] = {
_CHROMIUM_VERSIONS: ClassVar[dict[utils.VersionNumber, tuple[str, str | None]]] = {
# ====== UNSUPPORTED =====
# Qt 5.12: Chromium 69
@ -732,7 +732,7 @@ class WebEngineVersions:
def _infer_chromium_version(
cls,
pyqt_webengine_version: utils.VersionNumber,
) -> tuple[Optional[str], Optional[str]]:
) -> tuple[str | None, str | None]:
"""Infer the Chromium version based on the PyQtWebEngine version.
Returns:
@ -760,8 +760,8 @@ class WebEngineVersions:
def from_api(
cls,
qtwe_version: str,
chromium_version: Optional[str],
chromium_security: Optional[str] = None,
chromium_version: str | None,
chromium_security: str | None = None,
) -> 'WebEngineVersions':
"""Get the versions based on the exact versions.
@ -1036,16 +1036,16 @@ class OpenGLInfo:
# The name of the vendor. Examples:
# - nouveau
# - "Intel Open Source Technology Center", "Intel", "Intel Inc."
vendor: Optional[str] = None
vendor: str | None = None
# The OpenGL version as a string. See tests for examples.
version_str: Optional[str] = None
version_str: str | None = None
# The parsed version as a (major, minor) tuple of ints
version: Optional[tuple[int, ...]] = None
version: tuple[int, ...] | None = None
# The vendor specific information following the version number
vendor_specific: Optional[str] = None
vendor_specific: str | None = None
def __str__(self) -> str:
if self.gles:
@ -1083,7 +1083,7 @@ class OpenGLInfo:
@functools.lru_cache(maxsize=1)
def opengl_info() -> Optional[OpenGLInfo]: # pragma: no cover
def opengl_info() -> OpenGLInfo | None: # pragma: no cover
"""Get the OpenGL vendor used.
This returns a string such as 'nouveau' or
@ -1098,7 +1098,7 @@ def opengl_info() -> Optional[OpenGLInfo]: # pragma: no cover
vendor, version = override.split(', ', maxsplit=1)
return OpenGLInfo.parse(vendor=vendor, version=version)
old_context: Optional[QOpenGLContext] = QOpenGLContext.currentContext()
old_context: QOpenGLContext | None = QOpenGLContext.currentContext()
old_surface = None if old_context is None else old_context.surface()
surface = QOffscreenSurface()

BIN
run_profile.py.lprof Normal file

Binary file not shown.

View File

@ -18,7 +18,7 @@ CACHE_PATH = pathlib.Path(tempfile.gettempdir(), "ublock-matches-cache.tsv")
ROWS_TO_USE = 30_000
def type_rename(type_str: str) -> Optional[str]:
def type_rename(type_str: str) -> str | None:
"""Use the same resource type names as QtWebEngine."""
if type_str == "other":
return "unknown"

View File

@ -25,8 +25,8 @@ def collect_tests():
@dataclasses.dataclass
class ParsedFile:
target: Optional[str]
qtwebengine_todo: Optional[str]
target: str | None
qtwebengine_todo: str | None
class InvalidFile(Exception):

View File

@ -375,7 +375,7 @@ def enum_members(base, enumtype):
}
def is_userns_restricted() -> Optional[bool]:
def is_userns_restricted() -> bool | None:
if not utils.is_linux:
return None

View File

@ -29,7 +29,7 @@ class FakeDBusMessage:
signature: str,
*arguments: Any,
typ: QDBusMessage.MessageType = QDBusMessage.MessageType.ReplyMessage,
error_name: Optional[str] = None,
error_name: str | None = None,
) -> None:
self._signature = signature
self._arguments = arguments
@ -170,7 +170,7 @@ class FakeNotificationAdapter(notification.AbstractNotificationAdapter):
def present(
self,
qt_notification: "QWebEngineNotification", *,
replaces_id: Optional[int],
replaces_id: int | None,
) -> int:
self.presented.append(qt_notification)
return next(self.id_gen)

View File

@ -28,10 +28,10 @@ class Key:
"""
attribute: str
name: Optional[str] = None
name: str | None = None
text: str = ''
uppertext: str = ''
member: Optional[int] = None
member: int | None = None
qtest: bool = True
def __post_init__(self):
@ -54,8 +54,8 @@ class Modifier:
"""
attribute: str
name: Optional[str] = None
member: Optional[int] = None
name: str | None = None
member: int | None = None
def __post_init__(self):
self.member = getattr(Qt.KeyboardModifier, self.attribute + 'Modifier')

View File

@ -632,7 +632,7 @@ class TestSendOrListen:
no_err_windows: bool
basedir: str
command: list[str]
target: Optional[str]
target: str | None
@pytest.fixture
def args(self):

View File

@ -210,7 +210,7 @@ def modules():
)
def test_autoselect(
stubs: Any,
available: dict[str, Union[bool, Exception]],
available: dict[str, bool | Exception],
expected: machinery.SelectionInfo,
monkeypatch: pytest.MonkeyPatch,
):
@ -222,9 +222,9 @@ def test_autoselect(
class SelectWrapperCase:
name: str
expected: machinery.SelectionInfo
args: Optional[argparse.Namespace] = None
env: Optional[str] = None
override: Optional[str] = None
args: argparse.Namespace | None = None
env: str | None = None
override: str | None = None
def __str__(self):
return self.name
@ -345,8 +345,8 @@ class TestSelectWrapper:
)
def test_autoselect_by_default(
self,
args: Optional[argparse.Namespace],
env: Optional[str],
args: argparse.Namespace | None,
env: str | None,
monkeypatch: pytest.MonkeyPatch,
):
"""Test that the default behavior is to autoselect a wrapper.