-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
BUG: fix handling of copy keyword argument when calling __array__ #25922
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
Conversation
@oscarbenjamin it looks like there are still some sympy test failures with this PR applied, but I think they'll be fixed once scipy is updated (the failures have tracebacks that end in scipy).
(although not sure what's up with I tried testing scipy with this PR applied, but it looks like scipy isn't buildable at the moment because of the |
Thanks @ngoldbaum. If changes are needed on SymPy's end then that's fine and I can make them. For now though perhaps the test failures in sympy are some measure of potential breakage that could be caused for other code. |
Not clear what is going on with the |
I can't reproduce that failure locally, but I see that it's running on python |
Hmm, nope. I just tried running python 3.12.1 and I can reproduce this there though. I guess an API changed... |
b86aabf
to
b847453
Compare
It looks like on Python 3.12, the exception object you get back from |
(we should probably add more CI coverage on python 3.12 if that's the only runner on that version) |
Thanks Nathan, good sleuthing.
Nasty. But I guess we can understand :) |
Thanks a lot for the quick fix Nathan! |
return NULL; | ||
} | ||
} | ||
|
||
Py_DECREF(kwargs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have Py_DECREF(args);
next to kwargs
? Similarly to:
Py_DECREF(args); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this is the only comment that I have.
NumPy will pass ``copy`` to the ``__array__`` special method in situations where | ||
it would be set to a non-default value (e.g. in a call to | ||
``np.asarray(some_object, copy=False)``). Currently, if an | ||
unexpected keyword argument error is raised after this, NumPy will print a | ||
warning and re-try without the ``copy`` keyword argument. Implementations of | ||
objects implementing the ``__array__`` protocol should accept a ``copy`` keyword | ||
argument with the same meaning as when passed to `numpy.array` or | ||
`numpy.asarray`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to move it to a new issue, but thinking through how to update some __array__
implementations, I am wondering: what are the expectations from numpy how an __array__
implementations handles this keyword fully or partially?
When copy=True
is being passed, does numpy assume that the __array__
implementation already made that copy? But what if the implementation defers dtype casting to numpy (which is currently possible), then it might be a waste to already copy up front?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great question. Worth a new issue indeed I think.
But what if the implementation defers dtype casting to numpy (which is currently possible)
Deprecated though, right? The signature should already have included the dtype
keyword, even though it was still working to not have that.
then it might be a waste to already copy up front?
What we want to achieve I think is that only a single copy is ever made. We can have two now in many cases, because the other library may copy from its internal implementation into an array, and then numpy will make another copy. The only way to get it right is for the other library to do the copy if copy=True
, and for numpy not to do so if the method call including copy=True
succeeded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created #25941, in case you want to move over your comments as well
Closes #25916.
This applies @rgommers draft changes from the issue description and adds a couple more fixes on top.
Replaces internal usages of
never_copy
withcopy
that can be-1
(corresponding toNone
),0
(False
), and1
(True
). This allows the array coercion machinery andPyArray_FromArrayAttr_int
to support passingcopy=True
(although right now that will never happen).Only passes a copy keyword if copy is not the default value.
Fixes a bug in checking for the error message
Removes an incorrect usage of
Py_SetRef
(sorry about suggesting that in the first place 😬 )Fixes some reference counting issues
Tests that the old deprecated calling convention still works.