BUG: use __index__ in integer argument parsing - #32680
Conversation
|
Thanks for working on this! The CI failures are real, use |
|
The CI failures are real but they're my fault 🙃. See #32682. Once that's merged you can merge with main or rebase. |
|
@shbhmbnsl1 the CI failure has been fixed on main. Either rebase or merge main to your branch to get a proper CI run here. |
aaf31a5 to
99a9b79
Compare
This comment was marked as low quality.
This comment was marked as low quality.
seberg
left a comment
There was a problem hiding this comment.
Thanks, LGTM, was briefly wondering if we should try to not de-duplicate the PyLong_AsLong, but I suspect there is no nice way.
What this still needs, is a test. There is no point in covering all functions, but please do cover a few random users of this converter in test_deprecations.py (that file follows a specific, if a bit outdated, pattern to make sure we both test the warning and if the warning is turned into an error).
Ignore @sylvesterkaczmarek I have banned it.
|
Just a random thought which may be bad actually. Would it be good or bad to put the error message the index conversion raised in the warning if the legacy conversion works? Like the warning infrorming about why |
|
I dunno, I think we could do that as an |
|
Yeah I was thinking it from the perspective that normal things that are convertible to integers in python nowadays should support @shbhmbnsl1 this looks good from my side as well so feel free to deal with Sebastian's comment and just take it out of draft :) |
|
Thanks @seberg and @ikrommyd for you comments.
So I added a test covering some public users of this converter, using a Thoughts @seberg @ikrommyd ? |
There was a problem hiding this comment.
Unfortunately I think the bot Sebastian banned made a point actually 🤣
Indeed in cpython PyLong_AsLong calls PyLong_AsLongAndOverflow which calls
PyNumber_Index. See here: https://github.com/python/cpython/blob/b62e0286858fcd9345b8ec40f490754a306a2186/Objects/longobject.c#L612
So if I'm reading cpython code correctly, we will just hit the error, then clear it, then hit it in the fallback again.
So I don't think the fallback is reachable in reality.
Somebody please tell me if I'm being stupid here.
But its a bot, so... 🤣 |
I think we both were looking into the exact same thing at the exact same time. See my comment 1 minute ago LOL. |
|
Just because the bot mentioned something that was tangential related doens't mean it had a point, because it didn't (it talked about statefulness which doesn't matter). That doesn't mean that the whole thing wasn't a red-herring, though :(, sorry @shbhmbnsl1! On the original agent thread Nathan's agent found that The only thing that "changed" is the explicit float check which only matters for crazy cases like the agent pointed out. Which is, honestly, also ridiculously unimportant. However: There is still something to do here @shbhmbnsl1, if much reduced: Since we require Python 3.12, we can delete the |
|
I believe the function can just be something around the lines of NPY_NO_EXPORT int
PyArray_PythonPyIntFromInt(PyObject *obj, int *value)
{
long result = PyLong_AsLong(obj);
if (NPY_UNLIKELY((result == -1) && PyErr_Occurred())) {
return NPY_FAIL;
}
if (NPY_UNLIKELY((result > INT_MAX) || (result < INT_MIN))) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large to convert to C int");
return NPY_FAIL;
}
*value = (int)result;
return NPY_SUCCEED;
} |
e6f35e2 to
272429a
Compare
|
@seberg @ikrommyd Thank you for your comments. I agree with the approach here and have updated the function accordingly. Also I decided to remove the test that I added to showcase that |
Yap, looks good, but tests are failing and need to be adapted. |
ikrommyd
left a comment
There was a problem hiding this comment.
LGTM as long as all the tests are fine. Thanks!
|
All tests pass now! |
seberg
left a comment
There was a problem hiding this comment.
Perfect, thanks! Always nice to delete code :).
Historically, we had to reject floats to match Python. But Python now always converts via `__index__` which makes this unnecessary. So we live in the future now where a float check is unnecessary to match Python `"i"` argparse behavior.
PR summary
PyArray_PythonPyIntFromIntcurrently uses legacy behavior to parse python objects to integers. This PR starts using the PyNumber_Index method which is the modern python way of parsing as it rejects all non-integers and not just floats. It will use the current behavior if the conversion with index fails to preserve backward compatibility.This should close gh-32590
First time contributor introduction
I am a new contributor who has used NumPy in the past. I am here to contribute as part of the NumFOCUS Volunteer Sprints Fall 2026 cohort. I recently got my first contribution merged in (#32596). I think with the first contribution I got more understanding of how python and C work together.
AI Disclosure
I used AI (OpenAI Codex specifically 5.6-Sol) to get deeper understanding of the issue. Also used AI to understand some functions which I didn't know about like PyNumber_Index and NPY_UNLIKELY. I used AI to then review my draft changes and suggest any changes necessary.