Skip to content
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

Fix type hints for Python versions < 3.10 #1897

Merged
merged 14 commits into from
Feb 2, 2023
Merged

Conversation

bouweandela
Copy link
Member

@bouweandela bouweandela commented Jan 18, 2023

Description

Python 3.8 and 3.9 do not support

a = str | int

Python 3.8 does not support

a = list[str]

even with from __future__ import annotations.

In function signatures, the syntax is supported though.

Credits to @schlunma for figuring this out.

This pull request updates the code so the older Python versions are type hinted correctly.


Before you get started

Checklist

It is the responsibility of the author to make sure the pull request is ready to review. The icons indicate whether the item will be subject to the 🛠 Technical or 🧪 Scientific review.


To help with the number pull requests:

@codecov
Copy link

codecov bot commented Jan 18, 2023

Codecov Report

Merging #1897 (3c3decd) into main (69a284d) will not change coverage.
The diff coverage is 100.00%.

@@           Coverage Diff           @@
##             main    #1897   +/-   ##
=======================================
  Coverage   92.03%   92.03%           
=======================================
  Files         234      234           
  Lines       12034    12034           
=======================================
  Hits        11075    11075           
  Misses        959      959           
Impacted Files Coverage Δ
esmvalcore/_recipe/from_datasets.py 100.00% <100.00%> (ø)
esmvalcore/dataset.py 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@valeriupredoi
Copy link
Contributor

valeriupredoi commented Jan 19, 2023

not sure this can be solved easily @bouweandela - have a look at this fastapi/typer#348 - am trying to pin typer see what's out of that, but until they fix it upstream I reckon we can't do much - here's the PR where I pin typer to no avail #1900

@bouweandela
Copy link
Member Author

I'm not sure if typer is related to this issue. What puzzles me is that dask uses a very similar configuration, so why is it not working for us?

@valeriupredoi
Copy link
Contributor

I'm not sure if typer is related to this issue. What puzzles me is that dask uses a very similar configuration, so why is it not working for us?

I thought typer was needed if we wanted to mess about with these type hints, I was wrong and I closed that PR - I am wondering though, maybe dask is using a different configuration of standards, or no mypy? Lemme have a look too

@schlunma
Copy link
Contributor

I don't understand how pinning the Python version of mypy is supposed to solve this. Code like

MyType = list[int] | dict

is simply not valid code in Python<3.10 and will always raise these errors, no mypy involved whatsoever.

@valeriupredoi
Copy link
Contributor

valeriupredoi commented Jan 19, 2023

that's why one needs to import _future shtuff, Manu. But, looking at dask's setup.cfg - the mypy section, it looks like they are setting it to be for python=3.9 (like Bouwe did here), but with a whole lot more bells and whistles in the opts section - some stuff that I don't even know what they do

@schlunma
Copy link
Contributor

But there is no __future__ stuff in this PR, is there? On the other hand, dask uses that:

https://github.com/dask/dask/blob/81f771e05f57cab2838534c319a9b81f6e5a00cd/dask/highlevelgraph.py#L1

@valeriupredoi
Copy link
Contributor

But there is no __future__ stuff in this PR, is there? On the other hand, dask uses that:

https://github.com/dask/dask/blob/81f771e05f57cab2838534c319a9b81f6e5a00cd/dask/highlevelgraph.py#L1

not in this PR, Manu, since this a fixer PR - Bouwe put those _futures shtuff already, look at esmvalcore/dataset.py or typing.py

@schlunma
Copy link
Contributor

Ah, yes, that makes sense. Sorry, I didn't check that.

I think I know what the problem is: from __future__ import annotations allows the usage of standard types in variable and function definitions , i.e., something like:

def f(x: list[int]) -> dict[str, float]:
    pass

is allowed and works with Python >= 3.7 when using from __future__ import annotations.

Example in our code:

diagnostics: dict[str, dict[str, Any]] = {}

However, as far as I can tell, it is not possible to use this feature in code that is always executed (e.g., to define custom types) in Python < 3.10 like we do here:

Recipe = dict[str, Any]
Facets = dict[str, Any]

If you look at the error message we get, it's always those two lines. Other code that uses syntax like dict[...] in function and variable definitions does not raise errors.

@valeriupredoi
Copy link
Contributor

Ah, yes, that makes sense. Sorry, I didn't check that.

I think I know what the problem is: from __future__ import annotations allows the usage of standard types in variable and function definitions , i.e., something like:

def f(x: list[int]) -> dict[str, float]:
    pass

is allowed and works with Python >= 3.7 when using from __future__ import annotations.

Example in our code:

diagnostics: dict[str, dict[str, Any]] = {}

However, as far as I can tell, it is not possible to use this feature in code that is always executed (e.g., to define custom types) in Python < 3.10 like we do here:

Recipe = dict[str, Any]
Facets = dict[str, Any]

If you look at the error message we get, it's always those two lines. Other code that uses syntax like dict[...] in function and variable definitions does not raise errors.

@schlunma I think that's a bingo! Since it doesn't seem to be mypy's fault here - let me see if we get the same with a lower mypy pin, if that's the case then we got us a runner

@schlunma
Copy link
Contributor

TLDR; replace syntax like

  • MyType = A | B with MyType = Union[A, B] (e.g., used here)
  • MyType = dict[str, Any] with MyType = Dict[str, Any] (e.g., used here)

after importing from typing import Union, Dict.

@valeriupredoi
Copy link
Contributor

yeah I reckon that's it - just figured it out it's not mypy that's at fault here, unless it's a dormant bug that's not been checked since a few versions ago - @schlunma you wanna make the changes you suggest directly in here and let's have us a test? I don't think @bouweandela would mind, since I've already hacked his PR quite a bit, before getting back to its original state 😁

@valeriupredoi
Copy link
Contributor

@schlunma biutiful 😍

@valeriupredoi valeriupredoi marked this pull request as ready for review January 24, 2023 13:53
@valeriupredoi valeriupredoi self-requested a review as a code owner January 24, 2023 13:53
Copy link
Contributor

@valeriupredoi valeriupredoi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

boom! Looking great, cheers, Manu! @bouweandela I took the liberty make this RfR and approve it while I'm at it too

@valeriupredoi
Copy link
Contributor

@bouweandela got a bit of time to look at this, buds?

@bouweandela bouweandela changed the title Use Python 3.10 style type hints Fix type hints for Python 3.8 Feb 2, 2023
@bouweandela bouweandela changed the title Fix type hints for Python 3.8 Fix type hints for Python versions < 3.10 Feb 2, 2023
@bouweandela bouweandela merged commit 684e7ea into main Feb 2, 2023
@bouweandela bouweandela deleted the mypy-python-version branch February 2, 2023 08:18
@remi-kazeroni remi-kazeroni added the bug Something isn't working label Mar 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants