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 annotations for get_axis_num (GH 9822) #9827

Merged
merged 4 commits into from
Nov 26, 2024

Conversation

bmerry
Copy link
Contributor

@bmerry bmerry commented Nov 26, 2024

Explicitly annotate that a single str argument leads to an int return, overriding the match against Iterable.

I haven't added tests since I didn't spot any existing tests of type annotations, but let me know if I missed them.

Explicitly annotate that a single `str` argument leads to an `int`
return, overriding the match against Iterable.
Copy link

welcome bot commented Nov 26, 2024

Thank you for opening this pull request! It may take us a few days to respond here, so thank you for being patient.
If you have questions, some answers may be found in our contributing guidelines.

@bmerry
Copy link
Contributor Author

bmerry commented Nov 26, 2024

Hmm, seems mypy isn't liking that in CI, although it didn't complain when I used it to verify my MCVE. I'll investigate and re-open when I've figured out why.

@bmerry bmerry marked this pull request as draft November 26, 2024 06:31
@bmerry
Copy link
Contributor Author

bmerry commented Nov 26, 2024

Ok, the mypy error is explained in more detail here. The problem is that when passing a variable that's statically known to be Iterable[str], you get back either str or tuple[str, ...] depending on the run-time type. Thus, to be technically correct, one should annotate the return type in this case to be str | tuple[str, ...]. However, that's not very pragmatic, because for most practical uses, the argument type will be known more specifically (e.g. list[str] or tuple[str]), and so you know you're getting back a tuple.

So I've done the pragmatic thing and just suppressed the mypy error. The documentation linked above says

Note that in cases where you ignore the overlapping overload error, mypy will usually still infer the types you expect at callsites.

@bmerry bmerry marked this pull request as ready for review November 26, 2024 07:12
Copy link
Collaborator

@headtr1ck headtr1ck left a comment

Choose a reason for hiding this comment

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

Would it not be enough to reverse the order of the existing overloads?

Or will that mess up tuples (which are hashable)?

@bmerry
Copy link
Contributor Author

bmerry commented Nov 26, 2024

Would it not be enough to reverse the order of the existing overloads?

Or will that mess up tuples (which are hashable)?

I haven't tested it, but I assume you'd run into that problem.

@max-sixty
Copy link
Collaborator

Thanks a lot for the contribution @bmerry !

Would it be possible to add a test function which uses these? If the test function is annotated with def test_foo() -> None, then mypy will check it. That way we can test that this fixes the issue, and other can try improving it (like the swapping overload order above) and we can be confident it won't regress.

@bmerry
Copy link
Contributor Author

bmerry commented Nov 26, 2024

Thanks a lot for the contribution @bmerry !

Would it be possible to add a test function which uses these? If the test function is annotated with def test_foo() -> None, then mypy will check it. That way we can test that this fixes the issue, and other can try improving it (like the swapping overload order above) and we can be confident it won't regress.

If I have time I'll give it a go, but to be honest I'm not sure I will. The test itself should be fairly easy to write, but setting up a test environment will have a learning curve since I've not used conda before and I don't want to risk it getting into a fight with pyenv over my PYTHON_PATH.

@max-sixty
Copy link
Collaborator

Yeah that's fair. Being able to make small contributions is important, and I think this is a good enough win that it's worth merging.

If you manage to set up an environment feel free to add a test to immortalize your contribution! (and I use pip to avoid the overhead, you might find it easier...)

@max-sixty max-sixty merged commit f3a65d5 into pydata:main Nov 26, 2024
29 checks passed
Copy link

welcome bot commented Nov 26, 2024

Congratulations on completing your first pull request! Welcome to Xarray! We are proud of you, and hope to see you again! celebration gif

@bmerry bmerry deleted the fix-gh9822 branch November 27, 2024 06:29
@bmerry
Copy link
Contributor Author

bmerry commented Nov 27, 2024

and I use pip to avoid the overhead, you might find it easier...

That sounds good. What arguments are you passing to pip to install all the right dependencies?

@max-sixty
Copy link
Collaborator

That sounds good. What arguments are you passing to pip to install all the right dependencies?

pip install .[dev] works!

@headtr1ck
Copy link
Collaborator

pip install .[dev] works!

Try pip install -e .[dev] if you intend to develop xarray and not just use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DataArray.get_axis_num is incorrectly typed
3 participants