Repository navigation
Add script to make type stub for units - #18547
Conversation
|
Thank you for your contribution to Astropy! 🌌 This checklist is meant to remind the package maintainers who will review this pull request of some common things to look for.
|
|
Note: ruff check seems to be a false positive. There's only one "real" import. |
|
I like the idea to generate type stubs and to tie it into CI in some way.
|
|
@nstarman: Thanks for the quick reply. If I understand your comment correctly: this stub iterates through astropy.units.all, but then makes a selection as for what types to import. This is in the spirit of "good enough". Sorting through the long tail will require some time and this way we get 98% of the types with little effort. |
|
I think we want to import everything that's in |
|
@nstarman: Thank you clarifying and pointing out |
|
Great. The generation LGTM. |
|
The main objection to #17902 was the size of the generated files, and this pull request must have the same problem. |
|
I think the difference being the focus on autogen.
I think @mikez's script is a good contribution. |
|
@eerovaher Thanks for the pointer to your commit. I missed that one. I agree with @nstarman here; for maintenance reasons, these files should be auto-generated by a bot – then file sizes aren't an issue. I'm glad we both had the same intuition that generating stub files are a good idea. :) @nstarman I like your route. CI helps with maintenance, I had two additional thoughts:
|
pllim
left a comment
There was a problem hiding this comment.
Should this PR be converted to draft for now?
How does this tie into dev workflow? The dev docs need to be updated if we proceed.
Thanks!
| @@ -0,0 +1,77 @@ | |||
| """ | |||
| Simple stub generator. Focussed on `astropy.units` for now. | |||
There was a problem hiding this comment.
| Simple stub generator. Focussed on `astropy.units` for now. | |
| Simple stub generator. Focused on `astropy.units` for now. |
There was a problem hiding this comment.
British spelling... will fix. :)
There was a problem hiding this comment.
@pllim If we take the [project.scripts] route, then we can add this right away and think about the CI part at a later stage.
|
@nstarman If we take the [project.scripts] route, what would be a good home for the script? If so, I'll move it there, update |
|
Thanks for the ping. I like the approach here, and like even more the idea to put this in I also really like how this separates concerns: after this PR providing the script, we can add automated tests that ensure that whatever it produces is up to date (probably mostly the unit test that is to be included here), and then find out how best to ensure the On the home for the script, given the precedent by the other sub-packages in |
|
@mhvk I like your approach. I moved the script to astropy/units/scripts and renamed it to |
mhvk
left a comment
There was a problem hiding this comment.
Super! To do still is a test. Note also my comment about possible arguments for the script - if we go the route of allowing an alternate path, testing would be even easier.
@mhvk What did you have in mind in terms of testing? I'd prefer not to over-complicate this for maintenance reasons. |
|
Responding to #18547 (comment)
What difference does it make if the stubs are generated in CI or not? The size of the stub files depends on how many objects need to be annotated and that is the same either way.
Git documentation makes it clear that "A Responding to #18547 (comment)
The standard way of distributing optional stubs annotations is by publishing them as a stub-only package. I sounds like you are attempting to invent a custom way of distributing optional type stubs, but you haven't justified why the standard way isn't good enough.
It would be simplest to use
Why was the size of the stub files a problem for #17902 but not here? |
|
ruff side-remark: |
|
@eerovaher All your remarks make sense to me, thank you for looking into this and helping me understand stubs better! Maybe we can split the CI/.gitignore-related issues into a separate discussion, since this PR will only handle adding the script and putting it in pyproject.toml.
Wonderful remark. Thank you! This seems to be the method chosen by pandas, see here. They also keep some internal stubs for development here. As far as I understood, this approach can lead to a significant maintenance burden and double-maintenance (since two repos need to be kept in sync). In that respect, I think we'd be clever here to choose a lightweight solution that auto-generates only astropy.units for now so as not to make the same mistake. (Also, as you suggested, use other development strategies like inline annotations and rethinking the
I see pandas uses that approach for their internal stubs here. However, if I understood you correctly, their stubtests approach won't work here. So we'd need to figure out another clever solution if we want to test this at all. I'd be happy to handle this testing in another PR, so we can give units stubs to everyone who needs them... and if the approach turns out to be the wrong one, it's an easy fix.. just delete one line in pyproject.toml and the file in units/scripts/. In short: experience has taught me, it's good to have a simple fix for now that's good enough for daily work (for those that want it) and then in parallel work on a more long-term solution that keeps our maintenance burden low. |
|
My main wish would be not to have auto-generated stubs in the git parts (I'd like to similarly get rid of the auto-generated lextab, parstab files). I mind much less if the stubs are distributed along with the package on pypi, but a separate package is arguably better, so if that is the standard, that's great. Anyway, as noted by @mikez, the nice part of the present approach is that for this PR, we do not have to worry about the details of how the stubs are distributed. Though obviously we should not do something that precludes standard methods. |
|
As for tests, maybe spot checks that the types are present and work. @nstarman seems to have had a more concrete idea in #18547 (comment) |
|
Thank you @eerovaher, for your patience. I didn't understand you at first, but now it clicked. I hope, for my health and teeth grinding, we can all agree on this version as a first step. 😅 |
mhvk
left a comment
There was a problem hiding this comment.
This looks good to me. The test using @eerovaher's example would require adding mypy as an optional dependency, which I think is better done in follow-up.
My remaining question is how to advertise this, while at the same time making clear that this is a temporary solution. My suggestion would be to have changelog and what's-new entries, and add something along the following lines to docs/units/type_hints.rst, at l.77 (before "Type Annotations Module"):
.. _typestubs_for_units:
Script for Creating Unit Type Stubs
===================================
While the main classes in `astropy.units` have type hints, the individual
units do not. These are autogenerated, which makes adding hints more
difficult. In astropy 7.2, we have experimental support for adding
appropriate type hint ``.pyi`` files in your astropy installation, using
the ``typestubs_for_units`` script, which can be called from the
command line.
.. warning:: This script is meant to gain information about whether the
type hints provided this way are sufficient. Once a better, automatic
solution has been identified, the script will be removed. In the
meantime, we welcome feedback.
(I think the text of the what's-new entry could be very similar, and the changelog entry a shortened version of it.)
I'm happy to just push the above to your branch, as long as there is agreement this makes sense. (But let's not let this keep us from getting something good in!)
|
@mhvk Thank you, again, for your guidance here. Much appreciate it. I slightly reworded the changelog and added it to the commit. |
mhvk
left a comment
There was a problem hiding this comment.
Super, that text is much better than what I suggested!
I think we still need a formal changelog entry (you'add a file docs/changes/units/18547.feature.rst) as well as a description in docs/whatsnew/7.2.rst -- but maybe hold off just a bit to see what @nstarman and @eerovaher think; I want to be sure that we don't have too much to and fro, and the text you added now to the docs would be the basis of those anyway.
|
Generating type stubs should not be the responsibility of the users and the reason why the three options for distributing type stubs I listed in #18547 (comment) are the only ones worth considering is that those are the three options that don't make type stubs the user's problem. With options 1) or 2) type stubs would be the responsibility of astropy/docs/development/ccython.rst Lines 65 to 70 in 62bc4dc That means a separate astropy-stubs package is the only reasonable method for distributing astropy type stubs. It is self-evident that it is much simpler for astropy to not implement any machinery for generating or testing stubs if astropy-stubs can do it instead. And it is much simpler for astropy-stubs if it is free to do whatever it needs to do without having to worry about compatibility with the astropy machinery. More importantly, from the users point of view installing astropy-stubs is as simple as installing any other package, and if astropy-stubs is specified as a dependency of another package users don't even have to install the stubs explicitly. All astropy would have to do would be to add a sentence or two referring to astropy-stubs in its documentation and possibly the README, and optionally a What's New entry. astropy-stubs can take care of implementing, testing and documenting itself and there is no good reason why astropy should interfere with any of that.
#17902 isn't good enough and this pull request isn't any better. The very best outcome from this pull request would be that it does not cause any confusion, but it already has. @mikez, if you want to improve |
@eerovaher I'd like you to hear me differently. My aim was not to improve annotations... my aim was to make using astropy easier for beginners like myself without seeing all those type checker errors on @mhvk @nstarman Maybe you can help me take it from here since it seems @eerovaher isn't willing to meet in the middle. I tried my best, but I only have so much energy. |
There was a problem hiding this comment.
Ok. Putting on my astropy.units maintainer hat for a second.
Thank you @mikez for your contribution and patience in this process! We are all invested in improving the user experience for Astropy, e.g. all those annoying type check errors in IDEs that motivated you to make this PR.
It seems that @mhvk and I are in consensus that this PR is good. IMO this is for 3 reasons:
- For devs and motivated users it alleviates a pain point.
- It gives us a concrete starting point towards our intended end goal: a painless inclusion of in-line typing and type files for
unitsthat users shouldn't have to manage themselves. - It's not public API and not scoped as such, leaving us room to iterate and improve. More complete solutions, like a separate stubs library, have their own bureaucratic complications, making this PR an appropriate stopgap.
Thanks again @mikez!
|
Introducing a script that the users are supposed to run to generate the type stubs is fundamentally a bad idea and, independently from the above, the script here does not address any of the shortcomings #17902 had. This pull request would have been very valuable if it had been opened before #17902, but it was instead opened 5 months after #17902 came to a better conclusion. |
mhvk
left a comment
There was a problem hiding this comment.
I agree that this is only a step towards a better solution, but I think it is a good one, as whatever the solution is, a script like this will be needed. So, I think we should go for it.
As I indicated earlier, I did feel it needed a changelog and what's-new as well, so added those directly. I will approve now, but it would be good if @nstarman had a quick look at my additions before merging.
On the path forward, conceptually, I think there are actually three possibilities:
- Generate the stubs upon packaging (it seems that should be possible, though I don't think we have discussed this yet).
- Generate them upon installation. Here, our documentation states that
setup_packageshould not import from the package, but that almost certainly had in mind its most common (only?) use within astropy, which is to compile libraries. For those, importing parts is obviously risky or even impossible (since it would require importing the library that is still to be compiled), but it is much less clear there is a problem for units. - Provide a separate type stubs package. This of course is fine too, if there is interest, and would free those interested in typing from being held back by those, like me, who feel typing takes away too much time from improving the code. I note that it is not that difficult to get a new repository set up under astropy.
Finally, @mikez, thanks very much for taking this on. I think between all the wondering about the longer term, the discussion helped improve the script very much, so that it is now in fact a good basis to work from!
| ] | ||
|
|
||
| # ignore deprecation warnings triggered by accessing units in deprecated.py | ||
| warnings.simplefilter("ignore", AstropyDeprecationWarning) |
There was a problem hiding this comment.
This won't make the whole test run globally ignore the warning even for unrelated tests, will it?
There was a problem hiding this comment.
I don't think so during runtime because typestubs_for_units isn't imported normally.
But it is for tests... so it might have an impact during tests 🤦.
There was a problem hiding this comment.
so it might have an impact during tests
That is no good. Is @mikez able to open a follow-up PR to localize the ignore with context manager somehow? Or just not care about deprecated.py
There was a problem hiding this comment.
Post mortem review (sorry for taking so long to get to this) I think this new dir has no buisiness being "public" (even if it's considered private by convention). We should mark it as explicitly private before it goes published.
Description
This pull request is to address #15808.
Advice is requested as for desired way to trigger this. (/cc @neutrinoceros)
Some options include: