Skip to content

Exorcise deprecated sparse matrix (scipy 2.0) - #20167

Open
pllim wants to merge 3 commits into
astropy:mainfrom
pllim:scipy-took-red-pill
Open

Exorcise deprecated sparse matrix (scipy 2.0)#20167
pllim wants to merge 3 commits into
astropy:mainfrom
pllim:scipy-took-red-pill

Conversation

@pllim

@pllim pllim commented Jul 30, 2026

Copy link
Copy Markdown
Member

Description

This pull request would need someone familiar with the nddata code and also who has time to read https://docs.scipy.org/doc/scipy/reference/sparse.migration_to_sparray.html carefully to review.

Reviewers should ignore the one ufunc failure in devdeps that is being handled separately in #20132

Fixes #20164

  • 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.

@pllim pllim added this to the v7.2.3 milestone Jul 30, 2026
@pllim pllim added no-changelog-entry-needed numpy-dev backport-v7.2.x on-merge: backport to v7.2.x backport-v8.0.x on-merge: backport to v8.0.x labels Jul 30, 2026
@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?
  • 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.

@pllim
pllim requested review from bmorris3 and mwcraig July 30, 2026 16:14
@pllim
pllim marked this pull request as ready for review July 30, 2026 16:26
@pllim
pllim requested review from eteq and kbwestfall July 30, 2026 16:27
@pllim

This comment was marked as outdated.

Comment thread astropy/nddata/covariance.py Outdated
Comment thread astropy/nddata/tests/test_covariance.py Outdated
Comment thread astropy/nddata/covariance.py Outdated
@pllim

This comment was marked as resolved.

@kbwestfall kbwestfall left a comment

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.

This comes with the caveat that I've only briefly looked at the migration page. I can dig in more later.

Do we know when this deprecation will actually happen? The warning at the top of this page just says it will be done "in the next few releases".

Comment thread astropy/nddata/covariance.py Outdated
Comment thread astropy/nddata/covariance.py Outdated
@neutrinoceros

Copy link
Copy Markdown
Contributor

Do we know when this deprecation will actually happen? The warning at the top of this page just says it will be done "in the next few releases".

Scipy usually removes deprecated APIs after just a couple minor releases.

@pllim
pllim force-pushed the scipy-took-red-pill branch 2 times, most recently from 2ef79cb to ec1d1fd Compare July 30, 2026 17:52
@pllim

pllim commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

scipy might also change more API than this but we can only react to what we see in CI.

@pllim
pllim dismissed neutrinoceros’s stale review July 30, 2026 17:57

Code of concern no longer exist

@pllim
pllim force-pushed the scipy-took-red-pill branch from ec1d1fd to 113b589 Compare July 30, 2026 18:13
@pllim

This comment was marked as outdated.

Comment thread astropy/nddata/covariance.py Outdated
if SCIPY_LT_2_0:
from scipy.sparse import coo_matrix, csr_matrix, find, isspmatrix_csr, triu
else:
from scipy.sparse import coo_array as coo_matrix

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.

This indeed should be checked by the nddata folks, most importantly to check no multiplication is used as matrix multiplication, but FWIW, I would tend to flip this around, i.e., turn towards the future by replacing coo_matrix with coo_array in the code and above import coo_matrix as coo_array.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I was trying to keep the diff to a minimal but I can flip the naming if y'all want. More code to review though.

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.

Yeah, I had the same thought as Marten. Up to you, but I'm happy to review the changes either way.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

OK sure, I can flip the naming

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

OK I flipped names in the code, but I left the in-code comments and docstrings alone. Cannot really touch the docstring or intersphinx would break.

@pllim
pllim force-pushed the scipy-took-red-pill branch 2 times, most recently from 2c76831 to b3bae88 Compare August 3, 2026 18:46
@pllim

pllim commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

Any chance someone can read the guide carefully soon (in a few days)? If not, I will temporarily ignore these warnings instead so we don't let even more failures creep into devdeps. Thanks!

@neutrinoceros

Copy link
Copy Markdown
Contributor

I'm paying close attention to devdeps and will be careful not to let new ones through. I can also take over this PR if you like.

@pllim

This comment was marked as resolved.

@neutrinoceros

Copy link
Copy Markdown
Contributor

I mean pick up where you left off and conduct following iterations. I thought that's what you were asking for. Maybe I misunderstood ?

@pllim

pllim commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

I am waiting for @kbwestfall to do a careful read of the migration guide, since he wrote the original code. :D

@neutrinoceros

Copy link
Copy Markdown
Contributor

FWIW I'm used to ready migration guides for code I didn't write, so I should be comfortable filling in for Kyle if need be :)

@pllim

pllim commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

@neutrinoceros do you want to review then? Feel free. Thanks!

@neutrinoceros

Copy link
Copy Markdown
Contributor

sign me up. I'll do this in the morning.

@neutrinoceros
neutrinoceros self-requested a review August 5, 2026 19:33

@neutrinoceros neutrinoceros left a comment

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.

The current approach doesn't seem internally consistent to me.
We're immediately dropping coo_matrix as a re-exported API but we're also adding an entirely new wrapper for issparse, just to alias a now deprecated function without the deprecation.

Overall think it's crucial we choose one strategy and apply it everywhere, otherwise we'll just end up with an even messier situation vis-à-vis our own users.

Personally I think the easiest path forward would be to preserve all re-exports as they are, just maybe hide them behind a module level __getattr__ so they don't warn eagerly.
Alternatively, we could wrap all of them with the old API names, and immediately deprecated them all.
I don't think the maintenance burden is justified, but that would at least be consistent, and slightly easier on any downstream user relying on these re-exports. Long term, I think this deprecation is proof that blindly re-exporting foreign APIs isn't worth the effort, which is why I'm suggesting to cut our looses now.

SCIPY_LT_2_0 = not minversion(scipy, "2.0.0.dev")

if SCIPY_LT_2_0:
from scipy.sparse import coo_matrix as coo_array

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.

This is not a drop-in replacement. This would lead to inconsistent behavior depending on the scipy version installed.

ref: https://docs.scipy.org/doc/scipy/reference/sparse.migration_to_sparray.html#details-shape-changes-and-reductions

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't have time to deep dive into this module, unfortunately. Do you want to open an alternate PR and close this one?

For now, maybe we should ignore the warnings.

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.

I can propose my solution in another PR, yes.

@kbwestfall

Copy link
Copy Markdown
Contributor

Sorry that I dropped off the map for this one. Two quick responses (which may be too hasty...):

  • I'm not sure I agree that the new approach is not internally consistent. Eventually, we would deprecate the use of old versions of scipy that provide, e.g., coo_matrix. And I expect this will include the new bespoke definition of isspmatrix_csr or some version of it. So everything currently in the relevant else block would be kept.
  • I was hoping to dig more into the differences between csr_matrix and csr_array to propose a solution, but I'm happy for @neutrinoceros to do this in a different PR.

@neutrinoceros

Copy link
Copy Markdown
Contributor

Eventually, we would deprecate the use of old versions of scipy that provide, e.g., coo_matrix

that's my point though: here it's dropped immediately, without a deprecation cycle, so it's a breaking change instead of a backward compatibility layer

@pllim

This comment was marked as resolved.

@neutrinoceros

Copy link
Copy Markdown
Contributor

Then why does test_scipy_funcs exist ?

@kbwestfall

kbwestfall commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Eventually, we would deprecate the use of old versions of scipy that provide, e.g., coo_matrix

that's my point though: here it's dropped immediately, without a deprecation cycle, so it's a breaking change instead of a backward compatibility layer

Maybe I'm misunderstanding, but I don't think this is dropping anything that the user's scipy version supports. I.e., if they have scipy < 2.0, the code will import and use coo_matrix but alias it to coo_array.

The test_scipy_funcs is just to ensure that the code succeeds or fails as expected. I.e., the scipy aliases should always be callable functions whether or not scipy is available, but they should report ModuleNotFoundError if scipy is not installed. I don't understand how this connects to the deprecation issue. Are you worried that users might have been doing something like from astropy.nddata.covariance import coo_matrix? (I would hope users are not doing this...)

I think it's more important to understand whether or not coo_matrix and coo_array can be treated as interchangeable within the context of this module.

@neutrinoceros

Copy link
Copy Markdown
Contributor

Are you worried that users might have been doing something like from astropy.nddata.covariance import coo_matrix?

Yes. The fact that we have a test exercising it seems to indicate that this is a supported use case. If that is in fact not its purpose, I don't understand what it's there for.

(I would hope users are not doing this...)

Me too, but the existing code seems ambiguous wether this was intentionally supported or not, especially because there are 0 indications that these functions are considered private.

@kbwestfall

Copy link
Copy Markdown
Contributor

Are you worried that users might have been doing something like from astropy.nddata.covariance import coo_matrix?

Yes. The fact that we have a test exercising it seems to indicate that this is a supported use case. If that is in fact not its purpose, I don't understand what it's there for.

This is a low-level test to ensure that the scipy imports within the covariance module are appropriately dealt with, not a test that exercises user-facing functionality. If that means it's not a test that we should have, I'm fine with removing it.

(I would hope users are not doing this...)

Me too, but the existing code seems ambiguous wether this was intentionally supported or not, especially because there are 0 indications that these functions are considered private.

To me, this is like having a foo.py file that includes import numpy as np, and then someone doing from foo import np. Do we need to guard against that? If removing test_scipy_funcs avoids this question, then that's another reason I would be happy to remove it.

@neutrinoceros

Copy link
Copy Markdown
Contributor

If that means it's not a test that we should have, I'm fine with removing it.

I don't think it's worth having, but having an inline explanation would solve the biggest problem I have with it: confusion.

To me, this is like having a foo.py file that includes import numpy as np, and then someone doing from foo import np.

I think you're implying that it's a bad idea, and I agree ! Nonetheless, it is sometimes done deliberately and I was under the impression that it was the case here.

Do we need to guard against that?

we can't really guard against it, though a module level __all__ (and possibly a module level __export__ (PEP 842, on going discussion) would clarify the intent.

If removing test_scipy_funcs avoids this question, then that's another reason I would be happy to remove it.

kill it with fire then 🔥

@pllim

pllim commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

I am getting confused. Are we staying with this PR or moving to a new one by @neutrinoceros ?

@kbwestfall

Copy link
Copy Markdown
Contributor

I am getting confused. Are we staying with this PR or moving to a new one by @neutrinoceros ?

My understanding is that we're sticking with this one. The remaining items (as far as I understand) are:

  • I still need to understand the differences between, e.g., csr_matrix and csr_array. Or, @neutrinoceros, do you already have a handle on this?
  • We want to remove the test_scipy_funcs test function. @pllim , can you do that in your branch?

@pllim
pllim force-pushed the scipy-took-red-pill branch from b3bae88 to a1640e8 Compare August 10, 2026 21:48
@pllim

pllim commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

I have rebased and removed test_scipy_funcs. Thanks, all!

@pllim
pllim dismissed neutrinoceros’s stale review August 10, 2026 21:52

The test of concern is removed

@pllim

pllim commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

OK now devdeps only have 1 failure from #20231 that is unrelated to scipy

@neutrinoceros

Copy link
Copy Markdown
Contributor

I still need to understand the differences between, e.g., csr_matrix and csr_array. Or, @neutrinoceros, do you already have a handle on this?

Not yet. I'm not on vacation but still traveling so my capacity is limited these days (but I'm hoping to ramp it up in the next couple days). I can prioritize this on request, but until then it's only somewhat near the top of my list.

pllim and others added 3 commits August 15, 2026 11:26
but did not read conversion guide carefully

Co-authored-by: Kyle Westfall <westfall@ucolick.org>
but leave in-code comments and docstrings alone
because it is confusing to test API of another library as our own
@neutrinoceros

Copy link
Copy Markdown
Contributor

I rebased your branch. I think it now addresses the only remaining failures on allowed-deps, so we should be able to see what's up with just the global status on this job now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-v7.2.x on-merge: backport to v7.2.x backport-v8.0.x on-merge: backport to v8.0.x nddata no-changelog-entry-needed numpy-dev

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TST: isspmatrix_csr is deprecated in scipy-dev

4 participants