-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resolve remaining Qt wrapper selection UX issues #7741
Conversation
Contains the exact same string we have in .WRAPPER already anyways.
This means we will now get errors via the usual mechanisms (e.g. a Tk error dialog) when all Qt wrappers failed to import. We also add information about the picked Qt wrapper (and any errors) to the error message.
This also moves the checking for sys.modules into _select_wrapper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a huge improvement! You've managed to thread quite a few threads neatly through the new SelectionInfo class and a few supporting functions which made this pretty easy to review.
I haven't ran this up locally or thought too critically about messaging and such since I don't have much time available. But I've read through the code changes a few times looking for broad themes I disagree with or blockers I could spot and I haven't seen anything so I fully support this being merged as is.
I've left some line comments about a few things, nothing blocking.
And some rambling non-committal comments while I sign off: I don't fully understand the implicit vs explicit init thing and the NameError if init() isn't called first thing. Like there is error messaging in the machinery module that tells you you did something wrong in the init module, which seems like a bit of coupling. There's probably a good reason for it but it's not in my head at the moment. Same for the implicit init thing. Not quite getting why that is needed and what alternatives there are. It seems like there is copypasta being added to every qt module just for tests, which makes me feel a bit suspicious that maybe it isn't the perfect solution.
The idea there was that there is basically two ways that an
>>> from qutebrowser.utils import utils
>>> utils.format_seconds(123)
'2:03' to try something out. For the latter case, I'd still like that to work, without having to carefully do Thus, importing anything without an explicit init first will implicitly ensure that things are initialized - but if that happens in qutebrowser as an application, that would be a bug, because it's not supposed to import anything from Does that make things clearer? Thanks for the review! Going to look at the things you commented on and then merge this, but not sure if I'll get around to it today. |
886f2ad
to
69c21a5
Compare
1a4b676
to
d6af539
Compare
This tries to resolve various UX issues (and code-style issues) with the initial Qt wrapper prototype, turning it into something I'm comfortable with unleashing on users 馃檭
In particular, it:
machinery.init()
, rather than doing it implicitly at import-time ofmachinery.py
. This ensures that we can do additional logic (more complex than just reading from an environment variable) when initializing qutebrowser. Basically, anything that can be done during early initialization (before any Qt imports, i.e. mostlyqutebrowser.py
andearlyinit.py
) is now fair game.machinery.py
are unset and cause aNameError
before initialization is done. This is deliberate: That way we will detect any unintended access to them before initialization, but without having to create a magicNotYetKnown()
object which raises in__eq__
and/or__bool__
.machinery.init_implicit()
which performs an implicit initialization if any of thequtebrowser.qt.*
modules is imported, butinit()
has not been called so far. This is needed so that we can still import qutebrowser modules in tests, for some linters, for interactive usage during development, etc.ImportError
exceptions encountered with details) via aSelectionInfo
dataclass andSelectionReason
enum.:version
earlyinit.py
, asmachinery.py
is too early to usequtebrowser.utils.log
, due to that having Qt dependencies)earlyinit.py
, e.g. QtCore/QtWidgets not being foundbackendproblem.py
, e.g. QtWebKit/QtWebEngine not being foundearlyinit.py
which can show a graphical dialog again (using Tk if needed) instead of showing an error on stdout only.ModuleNotFoundError
should lead to the tried wrapper to be skipped. Any otherImportError
is an unintended breakage of the setup, and leads to the wrapper selection process being aborted, and the error being surfaced byearlyinit.py
.QUTE_QT_WRAPPER=auto
for any brave early adopters (and tests).--qt-wrapper
which has precedence overQUTE_QT_WRAPPER
, very useful during development.machinery.py
.qutebrowser/qt/sip.py
a bit.tox.ini
to dropUSE_PYSIDE2
(we decided to not support that due to many missing APIs), but addIS_PYQT
andIS_PYSIDE
frommachinery.py
.I will add some screenshots and answers to #7656 in a follow-up comment over there.
Closes #7656
See #7202