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

structured unit / quantity stuff #13676

Merged
merged 2 commits into from Sep 21, 2022

Conversation

nstarman
Copy link
Member

@nstarman nstarman commented Sep 15, 2022

Signed-off-by: Nathaniel Starkman (@nstarman) nstarkman@protonmail.com

Necessary for #13669

  • Quantity now builds a structured unit if unit=None in the constructor and the value is structured.

TODO:

  • changelog
  • tests

Checklist for package maintainer(s)

This checklist is meant to remind the package maintainer(s) who will review this pull request of some common things to look for. This list is not exhaustive.

  • Do the proposed changes actually accomplish desired goals?
  • Do the proposed changes follow the Astropy coding guidelines?
  • Are tests added/updated as required? If so, do they follow the Astropy testing guidelines?
  • Are docs added/updated as required? If so, do they follow the Astropy documentation guidelines?
  • Is rebase and/or squash necessary? If so, please provide the author with appropriate instructions. Also see "When to rebase and squash commits".
  • Did the CI pass? If no, are the failures related? If you need to run daily and weekly cron jobs as part of the PR, please apply the Extra CI label. Codestyle issues can be fixed by the bot.
  • Is a change log needed? If yes, did the change log check pass? If no, add the no-changelog-entry-needed label. If this is a manual backport, use the skip-changelog-checks label unless special changelog handling is necessary.
  • Is this a big PR that makes a "What's new?" entry worthwhile and if so, is (1) a "what's new" entry included in this PR and (2) the "whatsnew-needed" label applied?
  • Is a milestone set? Milestone must be set but astropy-bot check might be missing; do not let the green checkmark fool you.
  • At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate backport-X.Y.x label(s) before merge.

@nstarman nstarman added this to the v5.2 milestone Sep 15, 2022
@nstarman nstarman requested a review from mhvk September 15, 2022 19:20
@github-actions github-actions bot added the units label Sep 15, 2022
@github-actions
Copy link

👋 Thank you for your draft pull request! Do you know that you can use [ci skip] or [skip ci] in your commit messages to skip running continuous integration tests until you are ready?

astropy/units/quantity.py Outdated Show resolved Hide resolved
astropy/units/structured.py Outdated Show resolved Hide resolved
astropy/units/structured.py Outdated Show resolved Hide resolved
astropy/units/quantity.py Outdated Show resolved Hide resolved
astropy/units/quantity.py Outdated Show resolved Hide resolved
@nstarman nstarman force-pushed the units-structured-unit-default branch 2 times, most recently from 0fc4711 to 3b6abc3 Compare September 15, 2022 19:58
Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

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

Yes, just changing the default would certainly seem fine!

A suggestion for making this easier, although that changes API slightly. But I think it is fine.

astropy/units/quantity.py Outdated Show resolved Hide resolved
astropy/units/structured.py Outdated Show resolved Hide resolved
astropy/units/quantity.py Outdated Show resolved Hide resolved
@nstarman nstarman force-pushed the units-structured-unit-default branch 3 times, most recently from 3efa533 to 083797b Compare September 16, 2022 15:14
astropy/units/quantity.py Outdated Show resolved Hide resolved
@@ -3,6 +3,8 @@
This module defines structured units and quantities.
"""

from __future__ import annotations
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there an associated version of python when this will no longer be needed?

Copy link
Member Author

@nstarman nstarman Sep 16, 2022

Choose a reason for hiding this comment

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

Yes. The nice thing is that pyupgrade in pre-commit should remove this when its obsolete and we bump the minimum version and run pre-commit on the repository.
Maybe that should be a step in the release process...

Copy link
Member

Choose a reason for hiding this comment

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

Is the line here just to avoid importing typing.Union?

Copy link
Member Author

Choose a reason for hiding this comment

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

Currently, yes.

Copy link
Member

Choose a reason for hiding this comment

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

PEP 563 has been postponed indefinitely, so I wouldn't expect pyupgrade to remove the line in question any time soon. However, writing union types as X | Y instead of Union[X, Y] proposed by PEP 604 was adopted in Python 3.10, so if the import is only needed for that then it could be removed when support for Python 3.9 is dropped.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for clearing up the timeline!

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe mark with a comment # For python < 3.10.?

Copy link
Member Author

Choose a reason for hiding this comment

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

-------
StructuredUnit
"""
# Make sure dtype is structured
Copy link
Contributor

Choose a reason for hiding this comment

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

I think for a private function we should be able to assume that the input is correct (i.e., just let the AttributeError or whatever else happen if not). python is not LBYL.

Copy link
Member Author

@nstarman nstarman Sep 16, 2022

Choose a reason for hiding this comment

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

I stuck this in for type narrowing since type hints are LBYL. There's no way to indicate that a dtype is structured except by checking. My editor is configured to check on type hints (Astropy makes it very unhappy). Hopefully NumPy will parametrize dtype as a Generic[...] or have a StructuredDtype protocol.

We could add that protocol...

@runtime_checkable
class StructuredDtype(Protocol):
    @property
    def names(self) -> tuple: ...
    @property
    def fields(self) -> Mapping: ...

Copy link
Contributor

Choose a reason for hiding this comment

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

Understood, but can you nevertheless remove it? It is one thing to label things to help people and computers understand intent, quite another to make the code slower and more complex... I find it a beauty of python that one does not presume to know beforehand all possible input one might get.

Copy link
Member Author

Choose a reason for hiding this comment

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

Probably more typing than Astropy wants right now, but the suggested Protocol should solve both problems. This function knows that the dtype is structured and there's no checks necessary.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, having that Protocol would indeed solve it. And could live in separate typing files, where it wouldn't bug me 😺 More seriously, something to suggest to numpy?

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Forgot it does not do ANY signature checking. The protocol will not work.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's a pity. But let's leave all of this out of this PR. As is, this private function is only called with well-defined input so no checks should be necessary.

Copy link
Member Author

Choose a reason for hiding this comment

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

astropy/units/structured.py Outdated Show resolved Hide resolved
@nstarman nstarman force-pushed the units-structured-unit-default branch 2 times, most recently from b10d6d5 to 466ee33 Compare September 16, 2022 22:01
@nstarman nstarman marked this pull request as ready for review September 17, 2022 21:19
Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

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

Looks all great. Approving since what remains is just a question of use of case.

@@ -481,13 +481,15 @@ def __new__(cls, value, unit=None, dtype=np.inexact, copy=True, order=None,
# structured dtype of the value.
dtype = unit._recursively_get_dtype(value)

USING_DEFAULT_UNIT = False
Copy link
Contributor

Choose a reason for hiding this comment

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

Rereading this, I wonder why you use all-caps here. I tended to treat those as "environment variables", i.e., the caps indicate that the variable is defined outside of the scope. But that is not the case here, so maybe one should use lower case?

Copy link
Member Author

Choose a reason for hiding this comment

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

SGTM. I'll repush and merge on pass.

Signed-off-by: Nathaniel Starkman (@nstarman) <nstarkman@protonmail.com>
Signed-off-by: Nathaniel Starkman (@nstarman) <nstarkman@protonmail.com>
@nstarman nstarman added the 💤 merge-when-ci-passes Do not use: We have auto-merge option now. label Sep 21, 2022
@nstarman nstarman merged commit 513b9d9 into astropy:main Sep 21, 2022
@nstarman nstarman deleted the units-structured-unit-default branch September 21, 2022 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
units 💤 merge-when-ci-passes Do not use: We have auto-merge option now.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants