-
Notifications
You must be signed in to change notification settings - Fork 391
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
feat: Add mypy type checking #4863
base: main
Are you sure you want to change the base?
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 3 Skipped Deployments
|
Docker builds report
|
Uffizzi Ephemeral Environment
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #4863 +/- ##
=======================================
Coverage 97.38% 97.38%
=======================================
Files 1189 1189
Lines 41420 41453 +33
=======================================
+ Hits 40338 40371 +33
Misses 1082 1082 ☔ View full report in Codecov by Sentry. |
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 seems like a decent enough solution to me but I have some general questions:
-
What happens if we (perhaps inadvertently) resolve an existing issue. Based on the logic in your script, I guess we wouldn't know about it, right? Because we're just seeing what's left after we subtract the original errors from the new ones which wouldn't tell us anything about any that we've solved. It would obviously be great to incentivise resolving existing issues where we can.
-
This approach works fine I guess, but another solution would have been to just add all of the distinct files into the exclude. Then every new file would need to conform to mypy, but changes to existing files wouldn't. I'm not sure how we could incentivise fixing the existing errors. (Note: I'm certainly not suggesting this is a better option, I'm just playing devil's advocate).
.pre-commit-config.yaml
Outdated
hooks: | ||
- id: mypy-check | ||
name: mypy check | ||
entry: bash -c "cd api && poetry run python scripts/mypy_check.py" |
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.
Since I was looking at similar functionality yesterday (see here) , I am somewhat intrigued by this.
My understanding of pre-commit is that it passes the modified files into the command specified in entry
, so the resulting command would look something like:
bash -c "cd api && poetry run python scripts/mypy_check.py" file1.py file2.py
... which I would expect to just not work at all, or at least throw some sort of error?
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.
@zachaysan I'm not sure the latest changes make any reference to this?
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.
I've altered the script to run the files one at a time. I had to use git diff
to list the target files of the commit because no matter what I tried to pass into the bash script it just wouldn't run with the automatic listed files. The good news is that we are now doing a mypy
check on only the committed files.
I think we should treat the baseline as something we can devote engineering time towards. Delete a chunk of the baseline then re-run mypy see the failures that you eliminated from the baseline then handle them. Over time, I think we can get to a point where the baseline file is deleted and we have full coverage.
I think the approach I've taken is actually better for coverage because new errors in existing files will be surfaced. As for incentivizing fixing the existing errors, I really think we should just have engineering time to delete things from the baseline then fix them up locally. |
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.
Approving with a minor comment, but as discussed in the engineering meeting, I'd like to get everyone's eyes on this.
pre-commit.ci run |
@@ -99,6 +99,16 @@ skip = ['migrations', '.venv', '.direnv'] | |||
addopts = ['--ds=app.settings.test', '-vvvv', '-p', 'no:warnings'] | |||
console_output_style = 'count' | |||
|
|||
[tool.mypy] | |||
exclude = "^(tests/)$" |
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.
Is there a reason to exclude the test code?
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.
Mypy throws an error when we try to include the tests
module in the coverage. We tried hard to figure out how to solve this bug but it was outside of our grasp.
|
||
# Detect new errors and remove information line filtering out third party packages | ||
current_errors = {line for line in current_output if "site-packages" not in line} | ||
new_errors = current_errors - baseline |
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.
I think we should check for baseline - current_errors
as well to make sure the baseline file contains up to date errors. Rarely, but things may change implicitly (e.g. with a dependency update).
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.
Great idea. I've implemented this with a helpful error message.
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.
Just realized that this doesn't actually work since mypy
only checks errors for the current working module. I've reverted my change.
baseline = set(line.strip() for line in f if line.strip()) | ||
|
||
# Detect new errors and remove information line filtering out third party packages | ||
current_errors = {line for line in current_output if "site-packages" not in line} |
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.
I appreciate it's going to be slightly more difficult to compare against, but why not just have third party errors in the baseline as well?
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.
Since the line numbers change between installs it becomes difficult to handle it that way. Plus, site-packages
is going to be only ever present in the installation path for non-local modules.
hooks: | ||
- id: mypy-check | ||
name: mypy check | ||
entry: bash -c "cd api && poetry run python scripts/mypy_check.py $(git diff --name-only --cached -- '*.py')" |
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.
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.
The additional_dependencies
seems to have worked once I changed the language
to python
.
@zachaysan I think you'll need to rebase onto the main branch to get pre-commit to pass after I merged this PR. |
Changes
This adds mypy type checking. Existing failures have been grandfathered in and a helper script is run to compare failures against the predefined list. Mypy was also added into the
pre-commit
config and will run on any commits to python code.How did you test this code?
I altered the predefined mypy list and saw a failure crop up when running
pre-commit
.