Repository navigation
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.
|
There was a problem hiding this comment.
We shouldn't bother with annotations for deprecated units, but despite the name of the module the units it defines are not actually deprecated.
There was a problem hiding this comment.
I think this is great. And I think having the stubs within Astropy is the correct place.
My one comment is that there's some maybe-public (🤷 IDK it's hard to tell (and if a maintainer can't easily tell, then how can a user?)) stuff that aren't units in these modules, like the bases set in si.py. if these are public then they should be in the pyi file.
|
I also think that these stubs belong in astropy itself. The generation script should probably be included in the repo (if not distributed) too. |
| @@ -0,0 +1,656 @@ | |||
| # Licensed under a 3-clause BSD style license - see LICENSE.rst | |||
|
|
|||
| # ruff: noqa: PLC2401 | |||
There was a problem hiding this comment.
I would suggest adding the human readable lint id (non-ascii-name) to this noqa comment to save future readers from looking it up
mhvk
left a comment
There was a problem hiding this comment.
It still seems somewhat stupid that it would not be possible to annotate a module that all entries are of a given by (ideally, by default) , so I raised an issue over at mypy: python/mypy#18813
If we do go this route, then we definitely need to include the scripts that generate the files, as well as a test that the stubs are complete (which may mean running the generator code with output to temporary files and checking for differences).
Another question, more for us: is it really not possible to generate these files on the user side (on first import)?
(Noting request changes only because for sure tests are needed, so this shouldn't be merged as is, yet there are already approvals.)
This sounds like a build step, I do not see the benefit of deferring it to import time. |
To me, it is more similar to how |
pyc files are system specific. stub files are not. It's more like how the unit lexers are built. |
With an important differences that we would be responsible for maintaining this mechanism, and that it could make installation less reproducible and harder to debug. I'd much prefer we ship identical stub files to everyone and avoid uncertainty in that area. |
|
OK, makes sense to not "roll our own" -- though the lexers have moved away from pre-generated files to just reconstructing them on the fly (we just haven't caught up). My real issue remains with mypy (or other type checkers) not being able to provide a default type. But perhaps my issue will lead to someone answering that there is actually a mechanism that we're simply not aware of. Isn't it true that if we always got units from a Anyway, this may be unlikely, and I don't want to hold us all up waiting for a magical answer. For sure, though, we need the generator functions included and have tests for them. |
|
Somewhat of an aside, but relevant: I've been wondering whether it wouldn't make sense to create the In part, this comes about because of something @cdeil mentioned way back, that he generally uses the string versions of units. I.e., perhaps the recommended way of using units should be to do EDIT: another reason was that for a little while, it seemed like it might become possible to define one's own string types, so one could have |
Do you mean that whenever type checkers encounter some attribute they don't know about they should assume it has some default type? If that would be the case then type checkers would not be able to raise errors when an invalid attribute is accessed (e.g. because of a typo).
Type checkers would indeed know about the types of the values of the dictionary, but they would lose the ability to check the keys. Unless you use
Have thought about how Sphinx would know what units to include in the documentation? It should be pointed out that the stub files are not just for type checkers. They also tell IDEs what units exist so that IDEs can provide autocompletion. Dynamic approaches do not allow for that.
What's the problem with using unit instances? Is it that the leading >>> from astropy.units import km, s
>>> km / s**2
Unit("km / s2")
I don't like the idea of generating the stubs on first import, but I did consider generating the stubs during installation. In particular, I thought that we could introduce astropy/docs/development/ccython.rst Lines 68 to 70 in e7f827a I don't know how we could automatically generate the stubs if we can't use setup_package.py for it.
|
|
Is an answer on my mypy issue (see python/mypy#18813 (comment)) something that might work?
I can see one could annotate that appropriately, if everything else that could possibly come from the module is already defined. And it would basically implement my "on demand" suggestion. But I'm not by any means well-versed enough in the typing stuff to be sure. EDIT: really asking just about the typing now, i.e., leaving aside for now how to deal with sphinx, or whether this is super practical in general. |
|
Hmm, this seems very useful!!! on Mar 18, 2025 You can lie in the stub and have a getattr in the .pyi file even if that's not the strategy you take to creating attributes at runtime in the .py file |
|
Thinking more about this PR, which is moving well beyond just annotating (which is useful independently of whether the typing is 100% correct), I think it and similar ones should start meeting the bar for code contributions, i.e., they should come with proper typing test cases and documentation. This is particularly important since it seems there are multiple ways to implement the typing for all units, and we should be able to make changes knowing we don't break things. As a point of reference, I noticed that in numpy, they have a specific Anyway, bottom line, I think this PR will need to wait on #16312 (or an equivalent) |
I think it might work if we went with something like the units definition file that |
That seems very useful! |
Not sure it is that useful. Importing a unit that does not exist should give a type error. Similar to documentation: "wrong documentation is worse than no documenation" |
I guess the converse is really that the (current!) type system is not advanced enough to autogenerate files on the fly, so one gets stuck with shipping 100kB files just for the typing. But surely that will come, and in the meantime perhaps we can keep things simple for modules where we know exactly what is possible. |
What do you mean by the current type system: python type hints in general or type system of astropy |
|
The point is that with E.g. (pseudocode) So this is potentially immensely useful for reducing 5k lines of code diff down to a much smaller number. |
AFAIK So basically, every import from that module (except explicit definitions with a different type) will be considered valid But I could be wrong and would be happy to learn that there is a way. |
|
@fritz1005 - I think you right that we cannot do any type of calculations in the Anyway, personally I think for our initial goal of getting typing more or less set up, it is fine to not worry about |
|
We are using type hints for about 3 years now in the company I work at, and I think it is essential for large codebases worked on by many developers. Basically everyone has the same experience, at first some reservation, then the learning curve and at the end nobody could live without it anymore with everyone contributing to add type hints wherever possible. So sure, it has its limitations, but it also already has so many substantial benefits. Some of its limitiations are really the same as in statically typed languages, so they are only limitations because we are used to the dynamic nature of python. While that is useful in many instances, in my experience it is best to have short distances of dynamic types between anchors of static types, to not have to go to far up or down the stack to know what type we are actually looking at. That being said, I think having the (prefixed) unit instances addressed by a static And I understand the concern about bloating the library with type hints. Maybe an alternative could be to move the autogenerated type hints to https://github.com/python/typeshed for now? Anyways, thx for the discussion |
|
Offtopic but a bit more context: |
|
Or could we revisit generating the pyi files as part of the release process? It should be automatable with @eerovaher's script. |
|
Given @eerovaher's very pessimistic #17918 (comment), I now really see no point in adding stub files to either the repository or to releases and all the more reason for just adding a stub (EDIT: with |
|
If the main problem with these stubs is their size then why don't we create the |
|
I'm fine with a separate package, which, say, |
|
Just to be clear here, I still think we should use inline annotations as much as possible. The |
|
Hi humans 👋 - this pull request hasn't had any new commits for approximately 4 months. I plan to close this in 30 days if the pull request doesn't have any new commits by then. In lieu of a stalled pull request, please consider closing this and open an issue instead if a reminder is needed to revisit in the future. Maintainers may also choose to add keep-open label to keep this PR open but it is discouraged unless absolutely necessary. If this PR still needs to be reviewed, as an author, you can rebase it to reset the clock. If you believe I commented on this pull request incorrectly, please report this here. |
|
I'm going to close this pull request as per my previous message. If you think what is being added/fixed here is still important, please remember to open an issue to keep track of it. Thanks! If this is the first time I am commenting on this issue, or if you believe I closed this issue incorrectly, please report this here. |
Description
astropydefines too many units for their definitions to be written out conventionally. Instead we have adef_unit()function that creates the units dynamically. However,def_unit()is completely opaque to static code analysis tools such as type checkers or IDEs. We can help out such tools by generating stub files that list which units are defined and what their types are. We have two options for distributing the stub files - we could include them inastropylike is being done here, or we could create a separateastropy-stubspackage. I would be fine with either option. The main reason for opening the pull request inastropywas that I can't open a pull request inastropy-stubsbecause it doesn't exist yet.The stub files were all generated with