Skip to content

BUG: fix compatibility with numpy 2.0 for ndarray suclasses overriding ndarray.sort and ndarray.argsort#15929

Merged
pllim merged 2 commits intoastropy:mainfrom
neutrinoceros:tst/numpy2/ma_sort_stable
Jan 25, 2024
Merged

BUG: fix compatibility with numpy 2.0 for ndarray suclasses overriding ndarray.sort and ndarray.argsort#15929
pllim merged 2 commits intoastropy:mainfrom
neutrinoceros:tst/numpy2/ma_sort_stable

Conversation

@neutrinoceros
Copy link
Copy Markdown
Contributor

@neutrinoceros neutrinoceros commented Jan 23, 2024

Description

This pull request is to address one of the three failures reported in #15926
This is currently based atop #15925

xref numpy/numpy#25437

  • By checking this box, the PR author has requested that maintainers do NOT use the "Squash and Merge" button. Maintainers should respect this when possible; however, the final decision is at the discretion of the maintainer that merges the PR.

@neutrinoceros neutrinoceros changed the title TST: fix deprecation warnings from numpy dev's __array_wrap__ signature BUG: fix compatibility with numpy 2.0 for MaskedNDarray.sort Jan 23, 2024
@github-actions
Copy link
Copy Markdown
Contributor

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.

  • 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 instructions for rebase and squash.
  • 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 we cannot check for it on Actions; 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.

@github-actions
Copy link
Copy Markdown
Contributor

👋 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?

@neutrinoceros neutrinoceros force-pushed the tst/numpy2/ma_sort_stable branch from 627c294 to 7e5678a Compare January 23, 2024 07:59
@neutrinoceros neutrinoceros force-pushed the tst/numpy2/ma_sort_stable branch from 7e5678a to d55d0cf Compare January 23, 2024 08:57
@neutrinoceros neutrinoceros changed the title BUG: fix compatibility with numpy 2.0 for MaskedNDarray.sort BUG: fix compatibility with numpy 2.0 for ndarray suclasses overriding ndarray.sort and ndarray.argsort Jan 23, 2024
# ensure we do not return indices as quantities
def argsort(self, axis=-1, kind="quicksort", order=None):
return self.view(np.ndarray).argsort(axis=axis, kind=kind, order=order)
def argsort(self, axis=-1, kind=None, order=None, *, stable=False):
Copy link
Copy Markdown
Contributor

@mhvk mhvk Jan 23, 2024

Choose a reason for hiding this comment

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

For previous cases of signature changes, we did

if NUMPY_LT_2_0:
    def argsort(old-signature):
       ...
else:
    def argsort(new-signature):
        ...

I think that is preferable, since it means the signature is correct for the given numpy version, and there is no slowdown.

I guess an alternative would be to just pass *args, **kwargs? Especially given that "quicksort" is the default anyway.

Copy link
Copy Markdown
Contributor Author

@neutrinoceros neutrinoceros Jan 23, 2024

Choose a reason for hiding this comment

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

Oh I didn't realise that kind=None implied "quicksort". In that case, might as well 100% stick to numpy's signature.

@neutrinoceros neutrinoceros force-pushed the tst/numpy2/ma_sort_stable branch from 93ed82c to 56b8f0f Compare January 24, 2024 06:53
@neutrinoceros neutrinoceros marked this pull request as ready for review January 24, 2024 07:12
@pllim
Copy link
Copy Markdown
Member

pllim commented Jan 24, 2024

Is this the only one left that would make devdeps green again? 🤞

Thanks for all your help!

@neutrinoceros
Copy link
Copy Markdown
Contributor Author

Is this the only one left that would make devdeps green again?

Yes and no: it is the only one left so far, but don't get your hopes too high: there are still a couple issues with numpy dev that require we don't have solutions to at the moment.

@pllim
Copy link
Copy Markdown
Member

pllim commented Jan 24, 2024

In that case, are you able to rebase and at least fix the argsort stuff in this PR? Less traceback in the log would ease the rest of the fix. Thanks!

@neutrinoceros neutrinoceros force-pushed the tst/numpy2/ma_sort_stable branch from 56b8f0f to 42d9b57 Compare January 24, 2024 17:12
@neutrinoceros
Copy link
Copy Markdown
Contributor Author

rebased !

@pllim
Copy link
Copy Markdown
Member

pllim commented Jan 24, 2024

Now I am confused about the CircleCI jobs. The jobs here are green but they ran with pluggy 1.4.0 too. Are the failures not appearing all the time? 🤯

@pllim
Copy link
Copy Markdown
Member

pllim commented Jan 24, 2024

But back to the devdeps job, can you please confirm that the remaining 18 failures in https://github.com/astropy/astropy/actions/runs/7643754025/job/20826541495?pr=15929 are unrelated? Thanks!

@neutrinoceros
Copy link
Copy Markdown
Contributor Author

I don't get it either. My immediate instinct is to assume that pytest itself isn't fully deterministic 🤷🏻‍♂️ ?

@neutrinoceros
Copy link
Copy Markdown
Contributor Author

can you please confirm that the remaining 18 failures in astropy/astropy/actions/runs/7643754025/job/20826541495?pr=15929 are unrelated?

they are. I have them all on my radar:

@pllim
Copy link
Copy Markdown
Member

pllim commented Jan 24, 2024

Great! Hopefully @mhvk can review soon though the diff LGTM at a glance. Thanks!

Copy link
Copy Markdown
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.

@neutrinoceros - still some questions/suggestions for simplification...

else:

def argsort(self, axis=-1, kind=None, order=None, *, stable=False):
kwargs = dict(axis=axis, order=order)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we actually need to duplicate this check on the arguments? Why are we not just sending everything upstream?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think you're right, it's not needed now that I've changed the default value for kind ! thanks !

second, etc. A single field can be specified as a string, and not
all fields need be specified, but unspecified fields will still be
used, in dtype order, to break ties.
stable: bool, keyword-only
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since it is not actually used, in this case I think we can get away with just defining argsort for all numpy and just not passing on stable. Then, here write

Only for compatibility with np.sort (for numpy >= 2.0). Ignored.

@neutrinoceros neutrinoceros force-pushed the tst/numpy2/ma_sort_stable branch from 42d9b57 to 930e0dd Compare January 24, 2024 20:46
@neutrinoceros
Copy link
Copy Markdown
Contributor Author

with your suggestions in, the diff is now much smaller. Thanks @mhvk !

Copy link
Copy Markdown
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.

This is nice! Some small comments, partially just to improve it slightly more (with no change in API, so can still backport).

all fields need be specified, but unspecified fields will still be
used, in dtype order, to break ties.
stable: bool, keyword-only
Only for compatibility with np.sort. Ignored.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe phrase just like for kind, i.e.,

        stable: bool, keyword-only, ignored
            Sort stability. Present only to allow subclasses to work.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah that's more consistent with how kind is documented !


Notes
-----
stable is only used with numpy 2.0 and newer, and is ignored otherwise.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, good idea to have a note. But kind is ignored too... How about,

        Masked items will be sorted to the end. The implementation
        is via `np.lexsort` and thus ignores the ``kind`` and ``stable`` arguments;
        they are present only so that subclasses can pass them on.

# TODO: probably possible to do this faster than going through argsort!
indices = self.argsort(axis, kind=kind, order=order)
argsort_kwargs = dict(kind=kind, order=order)
if not NUMPY_LT_2_0:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

By setting the default to np._NoValue, we can change this to

if stable is not np._NoValue:
   argsort_kwargs["stable"] = stable

I do like that you pass them on, since in principle a subclass could override argsort and do something with it.

@neutrinoceros neutrinoceros force-pushed the tst/numpy2/ma_sort_stable branch from 5ddb2ae to ef5748c Compare January 25, 2024 17:22
Copy link
Copy Markdown
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.

OK, let's get it in! Thanks, @neutrinoceros!

Notes
-----
Masked items will be sorted to the end. The implementation
is via `np.lexsort` and thus ignores the ``kind`` and ``stable`` arguments;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Darn, this should have been numpy.lexsort for readthedocs to be happy...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since it must be getting late in Europe, I took the liberty to fix this directly on this branch. Hope you all don't mind!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks @pllim !

@pllim pllim merged commit 74bdf27 into astropy:main Jan 25, 2024
meeseeksmachine pushed a commit to meeseeksmachine/astropy that referenced this pull request Jan 25, 2024
…ndarray suclasses overriding ndarray.sort and ndarray.argsort
@pllim
Copy link
Copy Markdown
Member

pllim commented Jan 25, 2024

Down to 2 failures! 🚀

@pllim
Copy link
Copy Markdown
Member

pllim commented Jan 25, 2024

Let's try again

@meeseeksdev backport to v6.0.x

@lumberbot-app
Copy link
Copy Markdown

lumberbot-app bot commented Jan 25, 2024

Could not push to auto-backport-of-pr-15929-on-v6.0.x due to error, aborting.

@pllim
Copy link
Copy Markdown
Member

pllim commented Jan 25, 2024

C'mone bot. Don't be mad at me.

@meeseeksdev backport to v6.0.x

@lumberbot-app
Copy link
Copy Markdown

lumberbot-app bot commented Jan 25, 2024

Could not push to auto-backport-of-pr-15929-on-v6.0.x due to error, aborting.

pllim added a commit to pllim/astropy that referenced this pull request Jan 25, 2024
…t_stable

BUG: fix compatibility with numpy 2.0 for ndarray suclasses overriding ndarray.sort and ndarray.argsort
pllim added a commit that referenced this pull request Jan 25, 2024
Backport PR #15929 on branch v6.0.x (BUG: fix compatibility with numpy 2.0 for ndarray suclasses overriding ndarray.sort and ndarray.argsort)
@mhvk
Copy link
Copy Markdown
Contributor

mhvk commented Jan 25, 2024

Thanks, @pllim!

@neutrinoceros neutrinoceros deleted the tst/numpy2/ma_sort_stable branch January 25, 2024 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants