-
-
Notifications
You must be signed in to change notification settings - Fork 724
Add mypy type checking #908
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
Add mypy type checking #908
Conversation
There is a breaking change, could you add a line in the changelog for that? |
Done. Please let me know if this is acceptable, or if other changes are desired. Thanks! |
Sorry for the delay. After a second thought, I am not comfortable with the breaking change: it's a historic API, and may be overridden a lot in the nature. |
Yep, I'll try to do that. I'll rewrite the history so the commits are clean. |
c590714
to
f535a8c
Compare
I think this is addressed now. I've rebased to keep the commit history clean. Please let me know if additional changes are needed! 👍 |
ef1fdeb
to
d03274d
Compare
Is this, or something like it, going to happen? If help is wanted, I'll do what I can. Having a |
@kurtmckee could you fix conflicts 🙏🏻 ? @altendky I'll review again the PR tomorrow. I would prefer to not remove |
Sure thing! It won't be immediate due to work requirements but I can jump back to this soon! |
I'm skeptical about finding a good solution to avoid platform checks that mypy is aware of. I guess a mypy plugin might be able to use it, but... ick. Could you provide some explanation of what about that code makes it important to keep around? I'm not questioning it yet, but i don't have any of the history to know what makes not changing it important. mypy platform checks have even annoying corner cases as it is. Thanks to you both for your interest in this both before, and now. |
Hmm, now that I said that... if (not typing.TYPE_CHECKING and platform.is_linux()) or (typing.TYPE_CHECKING and sys.platform == "linux"): Maybe? Point being to retain runtime behavior at runtime and preferred type checking behavior when type checking. Still ick, but something. |
Lets go with the cleanest way that works for mypy. Changes seem good then 👍🏻 |
As a first pass, it looks like all our mypy checks pass with this PR. https://github.com/Chia-Network/chia-blockchain/actions/runs/4355725081 I'll take a quick pass over the changes now and maybe more detailed after ci is green. |
Thanks, @altendky, that's a confidence boost for the direction of this work! I should be able to return to this soon but have to get through some work requirements first. 😀 |
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 are some high level things I would encourage doing beyond just this PR. I'm happy to put in my own time towards them and handling them in a separate following PR seems ok.
-
Run the mypy checks at least across multiple platforms if not also across supported Python versions. Dependencies can vary across each of those. The watchdog code itself certainly varies a lot depending on the platform.
-
I tend to work with quite strict mypy settings. Applications sort of get a choice but libraries need to live up to whatever standards they want to enable their users to achieve. The default mypy setting mostly only checks stuff that is actively hinted. Requiring that everything is hinted and that
Any
is banned as much as possible is valuable, along with misc other settings. For the record, I look to https://github.com/altendky/qtrio/blob/459492f5f3d1fe6b6bb8b4e93d9a1bd1cdb4dc32/mypy.ini and https://github.com/Chia-Network/chia-blockchain/blob/8430b072e262cb7a80e688fdc3ad8f1fd2b50d0e/mypy.ini as my personal references for where I've ended up with mypy config. -
I try to always ignore the specific error message as opposed to general
# type: ignore
comments. I see that some ignores here do, many don't. When following this, it is useful to addshow_error_codes = True
tomypy.ini
so they error output includes the error code to ignore. -
I certainly don't follow it in all my own cases... but I do like having comments for type ignores. This makes it easier to read and conclude they are appropriate. If possible, a link to a PR or issue that when resolved should result in a reconsideration of the ignore. Sometimes either some or all of the actual mypy complaint is good.
Again, thanks to all for the work here. Based on my mypy checks failing with v2.3.1 but passing with this PR, this is an improvement. Even if you like my suggestions, they can certainly be considered as followups for me to invest my own time in. :]
src/watchdog/observers/kqueue.py
Outdated
# The `select` module varies between platforms. | ||
# mypy may complain about missing module attributes | ||
# depending on which platform it's running on. | ||
# The comment below disables mypy's attribute check. | ||
# | ||
# type: ignore[attr-defined] | ||
# | ||
|
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.
Big Picture: I think this is a macOS/BSD only option? If so we can encase the whole thing in a platform check instead of ignoring. I guess perhaps a not-windows-not-linux check would be the applicable one here?
Small Picture: Locally, with the just-released mypy 1.1.1 anyways, I get src/watchdog/observers/kqueue.py:23: error: type ignore with error code is not supported for modules; use
# mypy: disable-error-code=... [syntax]
@@ -119,11 +119,11 @@ def _errcheck_dword(value, func, args): | |||
return args | |||
|
|||
|
|||
kernel32 = ctypes.WinDLL("kernel32") | |||
kernel32 = ctypes.WinDLL("kernel32") # type: ignore[attr-defined] |
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.
With this being Windows only we could again encapsulate the whole file with a platform check. I mean yeah, it's ugly. I take a layer of indentation over lack of good hint checking though, personally.
@@ -49,7 +52,7 @@ | |||
WindowsApiEmitter as Emitter | |||
) | |||
elif platform.is_bsd(): | |||
from watchdog.observers.kqueue import ( | |||
from watchdog.observers.kqueue import ( # type: ignore[attr-defined,no-redef] |
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.
Do we need to keep around the mypy-incompatible platform checks? Or can we apply the compatible ones everywhere? I think the result in terms of ignoring this code is the same unless we have BSD systems in the test matrix, but just as a general thing I wonder about fully dropping the incompatible check mechanism. Even if there is agreement on that, I understand that that could well end up as a breaking change to save for a major version bump. Though, it does appear to be not documented which makes it at least a little less clearly public API. :]
https://watchdog.readthedocs.io/en/latest/api.html#module-watchdog.utils
This allows mypy to perform platform-specific type-checking, which fixes type-checking of the example code in `README.rst`. Closes gorakhargosh#840
d03274d
to
81d49b2
Compare
✔️ Step 1: Rebased on I'm going to take a step back from this effort and work on CI, which needs an overhaul. @BoboTiG, expect separate PR's to address some issues in CI. |
@altendky I'm under the impression that you have a deeper knowledge of type annotations, and how they can be applied in platform-specific ways. Would you be open to @BoboTiG reviewing this PR as-is and then working in parallel toward tightening the type annotations and getting the test suite to pass reliably on all platforms? |
Yep, works for me. As is this is useful for both of us. |
Thanks both of you. It will be useful to a lot more people at the end :) |
This PR introduces the following changes:
emitter_class
parameter fromBaseObserver.__init__()
. This aligns the call signature of the base class with its subclasses and allows the code sample inREADME.rst
to pass mypy checks.Closes #840