Closed cdce8p closed 3 years ago
There is another case where this is useful
from __future__ import annotations
class SomethingSomething:
def something_else(self) -> SomethingSomething:
pass
I've been using it myself actually, even in Home Assistant.
It has my vote π
I like this a lot.
So did a small change in the linked PR of WLED:
Seems like pylint doesn't like it at this point
Reference issues pylint: https://github.com/PyCQA/pylint/issues/3320
Reference issues pylint: PyCQA/pylint#3320
Good catch. Unfortunately we can't use Python 3.9 as pylint environment either. With that Union
, Optional
and NamedTuple
would wrongly be marked as unsubsciptable. The issue is already fixed, but there are still some other ones blocking the next release. So no idea when it will be usable π€·π»ββοΈ https://github.com/PyCQA/pylint/issues/3882
We could temporarily disable unsubscriptable-object
. However we might miss some other errors. I don't know if it's worth it.
At least the alternative Union Syntax PEP 604
seem to work fine.
Agree, I think we should move forward on PEP 563 & 604 and leave PEP 585 hanging until PyLint releases a fix.
However, running Pylint on Python 3.9 might not be a good idea, as that kinda protects us from getting Python 3.9 features sneaked in (e.g., hostname.removesuffix('.local')
π )
I've opened a PR for pylint that should fix it. It's already approved, just waiting for an unrelated issue to get fixed before it will be merged. https://github.com/PyCQA/pylint/pull/4059
I expect it will be included in the next release. Just don't know when that will happen π€·π»
New versions of pylint
and astroid
were just released that include support for PEP 585 and 604.
It should also detect if the new syntax is used incorrectly. https://github.com/home-assistant/core/pull/47205
I think I covered all cases during implementation in pylint, but if you notice any bugs/issues, please tag me. Maybe I can help fix them.
Nice! Happy astroid
got fixed π―
So, this means this path is now a possibility and a go! (I would say).
So, this means this path is now a possibility and a go! (I would say).
I would suggest to wait with any larger changes, it would probably make any bugfix releases for 2021.03
a lot more difficult.
Additionally, I can investigate if it's possible to automate that process. The path there would probably be:
from __future__ import annotations
to each modulepyupgrade
to convert the old syntaxI'll report back.
--
One last note: For PEP 604 (alternative Union syntax) I would only suggest enforcing the change from Optional[int]
to int | None
(etc). The use of a Union
is often more deliberate. Although that shouldn't mean that we shouldn't change it at all if it makes sense.
I've written a tool to update the typing syntax more or less automatically. https://github.com/cdce8p/python-typing-update/ My plan, unless decided otherwise, would be to split those changes up in 20 - 50 files each, so that the PRs don't get too big. This hopefully also means that I don't have to rebase them that often.
Nice use of tools there @cdce8p π
Will try to keep up with you π
@frenck Just let me know and I'll open some more π Should be somewhere around 15 - 20 PRs.
As for the review. Personally I do trust pylint
to detect most (if not all) errors. If it won't, I wouldn't have done a good job implementing them. Before I open a new PR, I only scroll through the changes to see if there is some obvious error. Sometimes my tool has some issues with comments inside the import block, so that they might get removed. Although it detects that and notifies me. These are the manual
updates. Besides that there is only formatting which might look strange sometimes (especially for multiline type annotations).
All typing update PRs have been merged now, just the last pre-commit updates remaining. Thanks @frenck for taking the time to review them all. Since this is implemented now, shall we close it?
Yep, considering it done!
Thanks for all the work done here! (And not just on the Home Assistant side of things). Well done! ποΈ
Go ahead and close it.
Finally done π
Yup, great stuff :+1:
Context
We recently updated the mypy version to
0.800
, https://github.com/home-assistant/core/pull/45485. With that it would now be possible to uselist
instead oftyping.List
-> PEP 585 andint | None
instead oftyping.Optional[int]
-> PEP 604.There is a caveat though which is why I wanted to discuss it first.
PEP 585 normally requires Python 3.9 and PEP 604 would require 3.10. The use in versions prior to that, the current default is 3.8, is only possible with postponed evaluation of type annotations, PEP 563. This can be enabled starting in 3.7 with
from __future__ import annotations
. However this workaround also means that any dynamic evaluation will throw an error. Some common examples are the use oftyping.get_type_hints
oreval
.Proposal
Allow and/or encourage the use of PEP 585 and PEP 604 for type annotations. For an overview on what's possible and what isn't, see the appendix.
Consequences
We can't use any functions that use dynamic evaluation in combination with the new syntax until 3.10 is the min required version. This would also apply to all custom_components. Response: At the moment, Home Assistant doesn't use
get_type_hints
oreval
anywhere in the codebase. Furthermore we use type annotations mainly as an additional helper to catch errors early, so I don't expect we'll use any of those anytime soon.from __future__ import annotations
needs to be added to every file in which the new syntax should be used. Response: We can easily remove it once 3.10 is the default. In some cases we already use this import to delay the type evaluation.Starting with the new syntax now is future proof. At some point we will need to use
list
, sincetyping.List
is deprecated as of 3.9.In addition to mypy, I know that Pylance also supports it (for all devs the use VS Code). Other type checker might as well.
The standard-library types are arguably more elegant since you don't need an additional import and
int | None
is IMO easier to read thenOptional[int]
.Links
https://mypy-lang.blogspot.com/2021/01/mypy-0800-released.html https://mypy.readthedocs.io/en/latest/runtime_troubles.html#future-annotations-import-pep-563 https://www.python.org/dev/peps/pep-0563/ https://www.python.org/dev/peps/pep-0585/ https://www.python.org/dev/peps/pep-0604/
Appendix
The following code will work starting with Python 3.7
The following would work in theory with 3.7, however mypy doesn't support it yet
Lastly, the following will NOT work.