-
Notifications
You must be signed in to change notification settings - Fork 96
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/static type annotations #128
Comments
Protocols just landed in Mypy, so you could use Mypy from git (Zulip does this), you can take advantage of Protocols |
This sounds good. Since we (1) indirectly pulled Edit: However, the fact that |
Just for kicks, I tried running mypy, and the result is ... not beautiful. There are lots of instances where mypy couldn't infer the type of a variable, I had to pepper the code with lots of |
It seems mypy does not do inference, it's 100% static. In the code, there are lots of occasions where a name is reused but the content changes. If we want to implement type checking, I suggest we use a type checker that does inference. |
Mypy does do static type inference. For example:
We don't know the best way to safely type But if you do something like:
We can statically infer types. Also keep in mind that runtime and static types are not always 1-to-1. Also for redefinition of types, there is I went ahead and ran mypy and it looks to me like most of the errors have to do with code paths potentially being None. |
That is actually my problem with mypy; it does not understand the context. Take, for instance, line 665 of
it does not understand that at that point, it is not possible for the And a lot of mypy's complaints about "potentially being None", again is due to mypy not having the ability to do contextual inference. To make the code pass mypy I have to pepper the code with lots of
Neither are perfect, but I find mypy's over-fastidiousness to be irritating and not worth the effort to fix. |
Okay so fixed a bunch of annotations thanks to pytype. Still on the fence w.r.t. mypy, but at least we're now on our way towards implementing proper type hinting in #202 (part of 1.3 milestone, btw) |
In 2.0, if Proposal No. 13 in #229 is agreed to, we can kinda enforce this per method. |
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
I'm definitely more of a fan of duck typing, so the structural/protocol typing would be 👍 |
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
In an ongoing attempt to fully annotate this package, I've submitted PR #259 |
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
Selection criteria: * Must be useful, even if many warnings For example: Plugins related to annotations. As @warsaw raised in aio-libs#128, it's a good idea to type-annotate as much as possible. * If not simple, must be maintained "maintained" here is overly-simplified to mean only "master has an update in 2020 or later". Some plugins have not received updates for a long time, but their logic are simple and really does not need updates, so those can also be included on a case-by-case basis. * Will not need significant change in logic Adding annotations, removing temp vars used just for return values, those are not logic changes. So even if lots of instances need to be fixed, that is okay. Plugins that need a restructurization of the logic flow (e.g., "flake8-cognitive-complexity") should not be included; or, if included, should not be activated. At least not until the next Epic.
Huh. rebasing + force pushing apparently causes LOTS of "referenced this issue" 😆 |
It seems reasonable to add type annotations since aiosmtpd is a Python 3 application/library and type annotations can provide better documentation to users. With the use of a tool like mypy, those assertions can even be tested.
We'll pretty quickly run into problems though since our
Handler
classes are duck typed, and mypy does not yet support structural typing. Meaning, examples such asController.__init__()
'shandler
argument does not have to be a subclass of anything; it simply needs to support some methods. Handlers are even weirder than straight up duck types too, becausehandle_*()
methods are optional.Similarly,
SMTP
methodssmtp_*()
are optional too.Some things that might help include:
The text was updated successfully, but these errors were encountered: