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

Avoid creating results with numpy scalars (re: NEP 51) #7282

Merged
merged 10 commits into from Mar 1, 2024

Conversation

eriknw
Copy link
Contributor

@eriknw eriknw commented Feb 10, 2024

NEP 51 coming in NumPy 2..0 changes the repr of numpy scalar, and this helps reveal usage of numpy scalars where Python scalars ought to be used. This PR aims to allow the workaround in #6856 to be reverted.

This uses dispatching machinery to perform rigorous inspection of return values. Hence, the blind spots are functions that are not dispatchable. We probably shouldn't keep this code when we merge. Should we look into a more flexible callback machinery to allow this check (and other checks) to be optionally done? Inspecting return values has proven quite useful.

Copy link
Contributor

@rossbar rossbar left a comment

Choose a reason for hiding this comment

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

Overall I'm +1 on making this change - I think it's in line with what most users expect and it's worth the explicit conversions to ensure everything is numpy scalar-free.

On the specifics, there are some cases where the .tolist approach could be replaced with a pattern that makes the intent more explicit, but there are others where tolist seems like the right move (but could perhaps use a comment to explain why it's being called). See individual comments for details + further discussion!

Thanks for finding and sifting through these @eriknw , I had never considered taking the next step and actually getting rid of numpy scalars from return types!

networkx/algorithms/centrality/eigenvector.py Show resolved Hide resolved
networkx/algorithms/centrality/subgraph_alg.py Outdated Show resolved Hide resolved
networkx/algorithms/shortest_paths/generic.py Outdated Show resolved Hide resolved
networkx/conftest.py Outdated Show resolved Hide resolved
networkx/convert_matrix.py Show resolved Hide resolved
networkx/convert_matrix.py Outdated Show resolved Hide resolved
Copy link
Member

@dschult dschult left a comment

Choose a reason for hiding this comment

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

This looks good to me.
I have some comments below -- mostly silly stuff like comments and variable names, etc.
In general, wherever it is not clear why we're using tolist it is probably helpful to have a comment saying that tolist is converting to a python object.

Just a note here of something I learned:
If you have a numpy scalar, but don't know whether to convert to e.g. a python float or int, it looks like np.ndarray.item() is the way to convert 0-d and scalars to python objects. tolist says it uses this to actually do the conversion of the values to python numbers.

I'm approving this because these suggestions are very minor.

networkx/algorithms/centrality/current_flow_betweenness.py Outdated Show resolved Hide resolved
networkx/algorithms/centrality/eigenvector.py Show resolved Hide resolved
networkx/algorithms/centrality/subgraph_alg.py Outdated Show resolved Hide resolved
networkx/algorithms/centrality/katz.py Show resolved Hide resolved
Copy link
Contributor Author

@eriknw eriknw left a comment

Choose a reason for hiding this comment

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

Thanks for reviewing @dschult, I responded to your feedback and made updates.

networkx/algorithms/centrality/eigenvector.py Show resolved Hide resolved
networkx/algorithms/centrality/katz.py Show resolved Hide resolved
networkx/algorithms/centrality/subgraph_alg.py Outdated Show resolved Hide resolved
networkx/algorithms/centrality/current_flow_betweenness.py Outdated Show resolved Hide resolved
Copy link
Member

@dschult dschult left a comment

Choose a reason for hiding this comment

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

Thanks for these comments -- I've replied below to a couple below. Looking good.

Also, just to make sure I have it clear in my head. We are not trying to convert all numpy arrays to python lists. We are only trying to convert numpy scalars to python numbers. No need to answer this unless we are trying to convert numpy arrays to lists. :)

networkx/algorithms/centrality/eigenvector.py Show resolved Hide resolved
networkx/algorithms/centrality/trophic.py Outdated Show resolved Hide resolved
@eriknw
Copy link
Contributor Author

eriknw commented Feb 24, 2024

Updated to use a.item(i) where appropriate. This PR still does e.g. float(s) instead of s.item() for clarity. I'm really glad to have learned about .item!

Also, just to make sure I have it clear in my head. We are not trying to convert all numpy arrays to python lists. We are only trying to convert numpy scalars to python numbers. No need to answer this unless we are trying to convert numpy arrays to lists. :)

I'll answer anyway... correct, we are only converting NumPy scalars to Python objects. NumPy array return types (ndim > 0) remain the same.

Copy link
Contributor

@rossbar rossbar left a comment

Choose a reason for hiding this comment

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

Thanks @dschult for the review + .item idea and @eriknw for the iterations! This LGTM!

@rossbar rossbar merged commit 28f3e9f into networkx:main Mar 1, 2024
41 checks passed
@jarrodmillman jarrodmillman added this to the 3.3 milestone Mar 1, 2024
cvanelteren pushed a commit to cvanelteren/networkx that referenced this pull request Apr 22, 2024
* Avoid creating results with numpy scalars (re: NEP 51)

* Revert changes to `convert_matrix.py` to see what happens

* Unrevert reversion

* Better

* respond to feedback: be more clear and use `x.item()`

* Use `a.item(i)` where appropriate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

None yet

4 participants