diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index 141555290..547e276db 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -19,6 +19,7 @@ """Base class for a wrapper over QWebView/QWebEngineView.""" +import enum import itertools import attr @@ -74,7 +75,7 @@ class UnsupportedOperationError(WebTabError): """Raised when an operation is not supported with the given backend.""" -TerminationStatus = usertypes.enum('TerminationStatus', [ +TerminationStatus = enum.Enum('TerminationStatus', [ 'normal', 'abnormal', # non-zero exit status 'crashed', # e.g. segfault diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 07e5c7c30..4ab271423 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -27,6 +27,7 @@ import collections import functools import pathlib import tempfile +import enum import sip from PyQt5.QtCore import (pyqtSlot, pyqtSignal, Qt, QObject, QModelIndex, @@ -38,8 +39,7 @@ from qutebrowser.utils import (usertypes, standarddir, utils, message, log, qtutils) -ModelRole = usertypes.enum('ModelRole', ['item'], start=Qt.UserRole, - is_int=True) +ModelRole = enum.IntEnum('ModelRole', ['item'], start=Qt.UserRole) # Remember the last used directory diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py index 90ef9b7ec..4312a7876 100644 --- a/qutebrowser/browser/hints.py +++ b/qutebrowser/browser/hints.py @@ -24,6 +24,7 @@ import functools import math import re import html +import enum from string import ascii_lowercase import attr @@ -37,10 +38,9 @@ from qutebrowser.commands import userscripts, cmdexc, cmdutils, runners from qutebrowser.utils import usertypes, log, qtutils, message, objreg, utils -Target = usertypes.enum('Target', ['normal', 'current', 'tab', 'tab_fg', - 'tab_bg', 'window', 'yank', 'yank_primary', - 'run', 'fill', 'hover', 'download', - 'userscript', 'spawn']) +Target = enum.Enum('Target', ['normal', 'current', 'tab', 'tab_fg', 'tab_bg', + 'window', 'yank', 'yank_primary', 'run', 'fill', + 'hover', 'download', 'userscript', 'spawn']) class HintingError(Exception): diff --git a/qutebrowser/browser/webelem.py b/qutebrowser/browser/webelem.py index 85efebd03..067f33cff 100644 --- a/qutebrowser/browser/webelem.py +++ b/qutebrowser/browser/webelem.py @@ -24,6 +24,7 @@ Module attributes: SELECTORS: CSS selectors for different groups of elements. """ +import enum import collections.abc from PyQt5.QtCore import QUrl, Qt, QEvent, QTimer @@ -35,7 +36,7 @@ from qutebrowser.mainwindow import mainwindow from qutebrowser.utils import log, usertypes, utils, qtutils, objreg -Group = usertypes.enum('Group', ['all', 'links', 'images', 'url', 'inputs']) +Group = enum.Enum('Group', ['all', 'links', 'images', 'url', 'inputs']) SELECTORS = { diff --git a/qutebrowser/keyinput/basekeyparser.py b/qutebrowser/keyinput/basekeyparser.py index 2f75cbdfe..14efd00ab 100644 --- a/qutebrowser/keyinput/basekeyparser.py +++ b/qutebrowser/keyinput/basekeyparser.py @@ -19,6 +19,7 @@ """Base class for vim-like key sequence parser.""" +import enum import re import unicodedata @@ -75,8 +76,8 @@ class BaseKeyParser(QObject): do_log = True passthrough = False - Match = usertypes.enum('Match', ['partial', 'definitive', 'other', 'none']) - Type = usertypes.enum('Type', ['chain', 'special']) + Match = enum.Enum('Match', ['partial', 'definitive', 'other', 'none']) + Type = enum.Enum('Type', ['chain', 'special']) def __init__(self, win_id, parent=None, supports_count=None, supports_chains=False): diff --git a/qutebrowser/keyinput/modeparsers.py b/qutebrowser/keyinput/modeparsers.py index 7aa8ca371..40624cee6 100644 --- a/qutebrowser/keyinput/modeparsers.py +++ b/qutebrowser/keyinput/modeparsers.py @@ -24,6 +24,7 @@ Module attributes: """ import traceback +import enum from PyQt5.QtCore import pyqtSlot, Qt @@ -34,7 +35,7 @@ from qutebrowser.utils import usertypes, log, message, objreg, utils STARTCHARS = ":/?" -LastPress = usertypes.enum('LastPress', ['none', 'filtertext', 'keystring']) +LastPress = enum.Enum('LastPress', ['none', 'filtertext', 'keystring']) class NormalKeyParser(keyparser.CommandKeyParser): diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index da18deae8..61bb35ace 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -19,6 +19,7 @@ """The main statusbar widget.""" +import enum import attr from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty, Qt, QSize, QTimer from PyQt5.QtWidgets import QWidget, QHBoxLayout, QStackedLayout, QSizePolicy @@ -46,7 +47,7 @@ class ColorFlags: passthrough: If we're currently in passthrough-mode. """ - CaretMode = usertypes.enum('CaretMode', ['off', 'on', 'selection']) + CaretMode = enum.Enum('CaretMode', ['off', 'on', 'selection']) prompt = attr.ib(False) insert = attr.ib(False) command = attr.ib(False) diff --git a/qutebrowser/mainwindow/statusbar/text.py b/qutebrowser/mainwindow/statusbar/text.py index e99891ecd..b232cedc8 100644 --- a/qutebrowser/mainwindow/statusbar/text.py +++ b/qutebrowser/mainwindow/statusbar/text.py @@ -19,10 +19,12 @@ """Text displayed in the statusbar.""" +import enum + from PyQt5.QtCore import pyqtSlot from qutebrowser.mainwindow.statusbar import textbase -from qutebrowser.utils import usertypes, log +from qutebrowser.utils import log class Text(textbase.TextBase): @@ -37,7 +39,7 @@ class Text(textbase.TextBase): available. If not, the permanent text is shown. """ - Text = usertypes.enum('Text', ['normal', 'temp']) + Text = enum.Enum('Text', ['normal', 'temp']) def __init__(self, parent=None): super().__init__(parent) diff --git a/qutebrowser/mainwindow/statusbar/url.py b/qutebrowser/mainwindow/statusbar/url.py index f75960f88..a91c67550 100644 --- a/qutebrowser/mainwindow/statusbar/url.py +++ b/qutebrowser/mainwindow/statusbar/url.py @@ -19,6 +19,8 @@ """URL displayed in the statusbar.""" +import enum + from PyQt5.QtCore import pyqtSlot, pyqtProperty, Qt, QUrl from qutebrowser.mainwindow.statusbar import textbase @@ -27,8 +29,8 @@ from qutebrowser.utils import usertypes, urlutils # Note this has entries for success/error/warn from widgets.webview:LoadStatus -UrlType = usertypes.enum('UrlType', ['success', 'success_https', 'error', - 'warn', 'hover', 'normal']) +UrlType = enum.Enum('UrlType', ['success', 'success_https', 'error', 'warn', + 'hover', 'normal']) class UrlText(textbase.TextBase): diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py index 98d6bdbc7..5af709c85 100644 --- a/qutebrowser/mainwindow/tabwidget.py +++ b/qutebrowser/mainwindow/tabwidget.py @@ -20,6 +20,7 @@ """The tab widget used for TabbedBrowser from browser.py.""" import functools +import enum import attr from PyQt5.QtCore import (pyqtSignal, pyqtSlot, Qt, QSize, QRect, QPoint, @@ -34,8 +35,8 @@ from qutebrowser.config import config from qutebrowser.misc import objects -PixelMetrics = usertypes.enum('PixelMetrics', ['icon_padding'], - start=QStyle.PM_CustomBase, is_int=True) +PixelMetrics = enum.IntEnum('PixelMetrics', ['icon_padding'], + start=QStyle.PM_CustomBase) class TabWidget(QTabWidget): diff --git a/qutebrowser/misc/backendproblem.py b/qutebrowser/misc/backendproblem.py index f126ceda5..6adc0c722 100644 --- a/qutebrowser/misc/backendproblem.py +++ b/qutebrowser/misc/backendproblem.py @@ -25,6 +25,7 @@ import functools import html import ctypes import ctypes.util +import enum import attr from PyQt5.QtCore import Qt @@ -37,10 +38,10 @@ from qutebrowser.utils import usertypes, objreg, version, qtutils, log, utils from qutebrowser.misc import objects, msgbox -_Result = usertypes.enum( +_Result = enum.IntEnum( '_Result', ['quit', 'restart', 'restart_webkit', 'restart_webengine'], - is_int=True, start=QDialog.Accepted + 1) + start=QDialog.Accepted + 1) @attr.s diff --git a/qutebrowser/misc/crashdialog.py b/qutebrowser/misc/crashdialog.py index 2da8eeeaf..f8b37c742 100644 --- a/qutebrowser/misc/crashdialog.py +++ b/qutebrowser/misc/crashdialog.py @@ -27,6 +27,7 @@ import getpass import fnmatch import traceback import datetime +import enum import pkg_resources from PyQt5.QtCore import pyqtSlot, Qt, QSize @@ -35,14 +36,14 @@ from PyQt5.QtWidgets import (QDialog, QLabel, QTextEdit, QPushButton, QDialogButtonBox, QApplication, QMessageBox) import qutebrowser -from qutebrowser.utils import version, log, utils, objreg, usertypes +from qutebrowser.utils import version, log, utils, objreg from qutebrowser.misc import (miscwidgets, autoupdate, msgbox, httpclient, pastebin) from qutebrowser.config import config, configfiles -Result = usertypes.enum('Result', ['restore', 'no_restore'], is_int=True, - start=QDialog.Accepted + 1) +Result = enum.IntEnum('Result', ['restore', 'no_restore'], + start=QDialog.Accepted + 1) def parse_fatal_stacktrace(text): diff --git a/qutebrowser/utils/docutils.py b/qutebrowser/utils/docutils.py index 567451e05..d645b41ac 100644 --- a/qutebrowser/utils/docutils.py +++ b/qutebrowser/utils/docutils.py @@ -24,9 +24,10 @@ import sys import inspect import os.path import collections +import enum import qutebrowser -from qutebrowser.utils import usertypes, log, utils +from qutebrowser.utils import log, utils def is_git_repo(): @@ -75,8 +76,8 @@ class DocstringParser: arg_descs: A dict of argument names to their descriptions """ - State = usertypes.enum('State', ['short', 'desc', 'desc_hidden', - 'arg_start', 'arg_inside', 'misc']) + State = enum.Enum('State', ['short', 'desc', 'desc_hidden', + 'arg_start', 'arg_inside', 'misc']) def __init__(self, func): """Constructor. diff --git a/qutebrowser/utils/standarddir.py b/qutebrowser/utils/standarddir.py index c5ee356c0..1efd47590 100644 --- a/qutebrowser/utils/standarddir.py +++ b/qutebrowser/utils/standarddir.py @@ -24,19 +24,20 @@ import sys import shutil import os.path import contextlib +import enum from PyQt5.QtCore import QStandardPaths from PyQt5.QtWidgets import QApplication -from qutebrowser.utils import log, debug, usertypes, message, utils +from qutebrowser.utils import log, debug, message, utils # The cached locations _locations = {} -Location = usertypes.enum('Location', ['config', 'auto_config', - 'data', 'system_data', - 'cache', 'download', 'runtime']) +Location = enum.Enum('Location', ['config', 'auto_config', + 'data', 'system_data', + 'cache', 'download', 'runtime']) APPNAME = 'qutebrowser' diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index 1bc928697..99716c062 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -25,7 +25,7 @@ Module attributes: import operator import collections.abc -import enum as pyenum +import enum from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QTimer @@ -35,22 +35,6 @@ from qutebrowser.utils import log, qtutils, utils _UNSET = object() -def enum(name, items, start=1, is_int=False): - """Factory for simple enumerations. - - Args: - name: Name of the enum - items: Iterable of items to be sequentially enumerated. - start: The number to use for the first value. - We use 1 as default so enum members are always True. - is_init: True if the enum should be a Python IntEnum - """ - enums = [(v, i) for (i, v) in enumerate(items, start)] - base = pyenum.IntEnum if is_int else pyenum.Enum - base = pyenum.unique(base) - return base(name, enums) - - class NeighborList(collections.abc.Sequence): """A list of items which saves its current position. @@ -65,7 +49,7 @@ class NeighborList(collections.abc.Sequence): _mode: The current mode. """ - Modes = enum('Modes', ['edge', 'exception']) + Modes = enum.Enum('Modes', ['edge', 'exception']) def __init__(self, items=None, default=_UNSET, mode=Modes.exception): """Constructor. @@ -221,45 +205,46 @@ class NeighborList(collections.abc.Sequence): # The mode of a Question. -PromptMode = enum('PromptMode', ['yesno', 'text', 'user_pwd', 'alert', - 'download']) +PromptMode = enum.Enum('PromptMode', ['yesno', 'text', 'user_pwd', 'alert', + 'download']) # Where to open a clicked link. -ClickTarget = enum('ClickTarget', ['normal', 'tab', 'tab_bg', 'window', - 'hover']) +ClickTarget = enum.Enum('ClickTarget', ['normal', 'tab', 'tab_bg', 'window', + 'hover']) # Key input modes -KeyMode = enum('KeyMode', ['normal', 'hint', 'command', 'yesno', 'prompt', - 'insert', 'passthrough', 'caret', 'set_mark', - 'jump_mark', 'record_macro', 'run_macro']) +KeyMode = enum.Enum('KeyMode', ['normal', 'hint', 'command', 'yesno', 'prompt', + 'insert', 'passthrough', 'caret', 'set_mark', + 'jump_mark', 'record_macro', 'run_macro']) # Exit statuses for errors. Needs to be an int for sys.exit. -Exit = enum('Exit', ['ok', 'reserved', 'exception', 'err_ipc', 'err_init', - 'err_config', 'err_key_config'], is_int=True, start=0) +Exit = enum.IntEnum('Exit', ['ok', 'reserved', 'exception', 'err_ipc', + 'err_init', 'err_config', 'err_key_config'], + start=0) # Load status of a tab -LoadStatus = enum('LoadStatus', ['none', 'success', 'success_https', 'error', - 'warn', 'loading']) +LoadStatus = enum.Enum('LoadStatus', ['none', 'success', 'success_https', + 'error', 'warn', 'loading']) # Backend of a tab -Backend = enum('Backend', ['QtWebKit', 'QtWebEngine']) +Backend = enum.Enum('Backend', ['QtWebKit', 'QtWebEngine']) # JS world for QtWebEngine -JsWorld = enum('JsWorld', ['main', 'application', 'user', 'jseval']) +JsWorld = enum.Enum('JsWorld', ['main', 'application', 'user', 'jseval']) # Log level of a JS message. This needs to match up with the keys allowed for # the content.javascript.log setting. -JsLogLevel = enum('JsLogLevel', ['unknown', 'info', 'warning', 'error']) +JsLogLevel = enum.Enum('JsLogLevel', ['unknown', 'info', 'warning', 'error']) -MessageLevel = enum('MessageLevel', ['error', 'warning', 'info']) +MessageLevel = enum.Enum('MessageLevel', ['error', 'warning', 'info']) class Question(QObject): diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index 547185623..9d1b7c90d 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -27,6 +27,7 @@ import platform import subprocess import importlib import collections +import enum import pkg_resources import attr @@ -63,7 +64,7 @@ class DistributionInfo: pretty = attr.ib() -Distribution = usertypes.enum( +Distribution = enum.Enum( 'Distribution', ['unknown', 'ubuntu', 'debian', 'void', 'arch', 'gentoo', 'fedora', 'opensuse', 'linuxmint', 'manjaro']) diff --git a/tests/unit/commands/test_argparser.py b/tests/unit/commands/test_argparser.py index 4cd3e7ee1..00f000acb 100644 --- a/tests/unit/commands/test_argparser.py +++ b/tests/unit/commands/test_argparser.py @@ -20,15 +20,15 @@ """Tests for qutebrowser.commands.argparser.""" import inspect +import enum import pytest from PyQt5.QtCore import QUrl from qutebrowser.commands import argparser, cmdexc -from qutebrowser.utils import usertypes -Enum = usertypes.enum('Enum', ['foo', 'foo_bar']) +Enum = enum.Enum('Enum', ['foo', 'foo_bar']) class TestArgumentParser: diff --git a/tests/unit/commands/test_cmdutils.py b/tests/unit/commands/test_cmdutils.py index 2da13881c..cc4313211 100644 --- a/tests/unit/commands/test_cmdutils.py +++ b/tests/unit/commands/test_cmdutils.py @@ -25,6 +25,7 @@ import sys import logging import types import typing +import enum import pytest @@ -243,7 +244,7 @@ class TestRegister: else: assert pos_args == [('arg', 'arg')] - Enum = usertypes.enum('Test', ['x', 'y']) + Enum = enum.Enum('Test', ['x', 'y']) @pytest.mark.parametrize('typ, inp, choices, expected', [ (int, '42', None, 42), diff --git a/tests/unit/utils/usertypes/test_enum.py b/tests/unit/utils/usertypes/test_enum.py deleted file mode 100644 index a5d2f33e5..000000000 --- a/tests/unit/utils/usertypes/test_enum.py +++ /dev/null @@ -1,74 +0,0 @@ -# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: - -# Copyright 2014-2017 Florian Bruhin (The Compiler) -# -# This file is part of qutebrowser. -# -# qutebrowser is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# qutebrowser is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with qutebrowser. If not, see . - -"""Tests for the Enum class.""" - -from qutebrowser.utils import usertypes - -import pytest - - -@pytest.fixture -def enum(): - return usertypes.enum('Enum', ['one', 'two']) - - -def test_values(enum): - """Test if enum members resolve to the right values.""" - assert enum.one.value == 1 - assert enum.two.value == 2 - - -def test_name(enum): - """Test .name mapping.""" - assert enum.one.name == 'one' - assert enum.two.name == 'two' - - -def test_unknown(enum): - """Test invalid values which should raise an AttributeError.""" - with pytest.raises(AttributeError): - _ = enum.three # flake8: disable=F841 - - -def test_start(): - """Test the start= argument.""" - e = usertypes.enum('Enum', ['three', 'four'], start=3) - assert e.three.value == 3 - assert e.four.value == 4 - - -def test_exit(): - """Make sure the exit status enum is correct.""" - assert usertypes.Exit.ok == 0 - assert usertypes.Exit.reserved == 1 - - -def test_is_int(): - """Test the is_int argument.""" - int_enum = usertypes.enum('Enum', ['item'], is_int=True) - no_int_enum = usertypes.enum('Enum', ['item']) - assert isinstance(int_enum.item, int) - assert not isinstance(no_int_enum.item, int) - - -def test_unique(): - """Make sure elements need to be unique.""" - with pytest.raises(TypeError): - usertypes.enum('Enum', ['item', 'item'])