-
Notifications
You must be signed in to change notification settings - Fork 42
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable PyQt5 type checking #1611
Conversation
57daf93
to
636dca0
Compare
beb125e
to
ff17311
Compare
All credits go to @zekehuntergreen for finding about it!
I don't think we currently manipulate any unbound signals anywhere! That's a great insight provided by mypy's type checks :)
By default, Qt picks the a Qt.QueuedConnection automatically whenever needed. Explicit queued connections also happen to make testing harder, and mypy singles out the type parameter as unexpected. See https://doc.qt.io/qt-5/qt.html#ConnectionType-enum
Note how the tests are asserting on private attibutes and mocking the object under test. I am not fixing that at this time.
I didn't find how to hint mypy on the type of conversation_view.
The alternative would be to define a QApplication subclass, which doesn't seem worth it at this point.
Assertions allow to narrow the type of an ambiguous object. See https://mypy.readthedocs.io/en/stable/type_narrowing.html
Assertions allow to narrow the type of an ambiguous object. See https://mypy.readthedocs.io/en/stable/type_narrowing.html
Assertions allow to narrow the type of an ambiguous object. See https://mypy.readthedocs.io/en/stable/type_narrowing.html
Assertions allow to narrow the type of an ambiguous object. See https://mypy.readthedocs.io/en/stable/type_narrowing.html
Assertions allow to narrow the type of an ambiguous object. See https://mypy.readthedocs.io/en/stable/type_narrowing.html Note: the test that was modified contains two smells: - it mocks a type to assert on its __init__ method (should probably assert on the resulting instance) - the specification of the mock as a Messagewidget isn't enough to satisfy the code requirements... I am leaving both those issues unsolved because I think the entire test needs re-thinking and that is out of scope of the PR. Meanwhile, type annotations are useful immediately.
Assertions allow to narrow the type of an ambiguous object. See https://mypy.readthedocs.io/en/stable/type_narrowing.html
Assertions allow to narrow the type of an ambiguous object. See https://mypy.readthedocs.io/en/stable/type_narrowing.html
ff17311
to
51609f9
Compare
@zekehuntergreen For some reason, I don't seem to be able to request a review from you through GitHub's UI, but any thoughts or comments from you would be welcome! |
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.
Thanks so much for adding this stub!
The note to review commit by commit was very useful 👌
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.
These changes look great to me, @gonzalo-bulnes. I've left two considerations in pending discussions, after which I'll be happy to approve and merge.
Assertions are not checked in production, and are risky to use for any reason that relies on them at runtime. Type checking is not a runtime concern, and using assertions to narrow types during type checks is not a problem. See https://mypy.readthedocs.io/en/stable/type_narrowing.html and https://snyk.io/blog/the-dangers-of-assert-in-python/
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.
Looks good to me, @gonzalo-bulnes! And I've confirmed that fc3afca works as intended by pushing a branch with this patch, which failed as expected:
--- a/securedrop_client/gui/widgets.py
+++ b/securedrop_client/gui/widgets.py
@@ -2338,7 +2338,7 @@ class FileWidget(QWidget):
def eventFilter(self, obj: QObject, event: QEvent) -> bool:
t = event.type()
if t == QEvent.MouseButtonPress:
- assert isinstance(event, QMouseEvent)
+ assert True # should trigger semgrep rule "unsafe-assert"
if event.button() == Qt.LeftButton:
self._on_left_click()
elif t == QEvent.HoverEnter and not self.downloading:
Description
We are currently not providing PyQt5 stubs to mypy. As a result, Qt types are not checked. Since half of the repo is a Qt GUI, we should fix that.
@zekehuntergreen wrote (source):
This PR adds the library to the development requirements and fixes the issues highlighted by
make mypy
.Towards #1614
Test Plan
🔮 Reviewers: It makes a lot of sense to review this PR commit by commit. They're independent form each other, and I've added to the commit message when making the most significant decisions.
The gist of it is: