-
-
Notifications
You must be signed in to change notification settings - Fork 11k
DOC: Update subclassing doc regarding downstream compatibility #7491
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
@jreback: I tested the current state of this PR against my budding PR for |
Isn't the original only in the master branch? Backporting of this seems a no-go to me in any case.... |
Can somebody take a look at this? This PR is important for the |
@@ -52,6 +52,25 @@ def _wrapit(obj, method, *args, **kwds): | |||
return result | |||
|
|||
|
|||
def _is_compat_error(e, method): |
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.
Could you add a docstring here explaining what the function does? Usual docstring format would be good. I know that some of the other functions are lacking in complete documentation, but they are old...
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.
Done.
@gfyoung I'm going to be traveling for a few days, but now that 1.11.1 is on its way I'll be spending more time on getting 1.12 branched. |
@charris : 👍 thanks for letting me know! |
Where do functions in fromnumeric get called from the ndarray implementation?
It appears to me that we have code organization problems if that is the case. |
The ndarray implementation points to the C implementation, which is what is called in fromnumeric. Ctrl+F any function that uses this wrapper, remove the check, and then call the function. You should get a recursion depth exceeded error. |
I believe there is a problem, but trace it for me, say for |
Hmmm...can't seem to reproduce now. I took out the check. |
@charris : I removed the checks, and Travis + Appveyor are still passing. I also checked that this doesn't break anything on |
Why not something lik 8000 e
Note that the function needs to be passed as EDIT: The function never gets called for ndarrays here, nor in your original. In the 1.11 version going through the method for ndarrays was avoided. I don't know what the timing difference is. EDIT: I don't like the big string searches, they add a lot of call overhead. |
@charris : The reason why I have all of the Also, I don't quite follow your point about big string searches and call overhead. IINM |
Let me start by saying that I won't put this in as is and trying to be compatible with everything downstream is a losing proposition. That said, it might be worth making some limited exceptions for bits of pandas. Let's look at Series.sum
We can't support all of that, only the The simplest construct for the
Which is only three lines and might should be in the function definition. Note that it calls direct into |
@charris : I don't think you are fully understanding the point of this PR IMHO. This is not about accommodating to |
All of these functions continue to check if the object being passed in has a corresponding method (e.g. |
@charris : What exactly is the issue that you have with my changes at the moment? You have been proposing all of these alternatives, and I fail to see what you are disagreeing with here. |
except AttributeError: | ||
# Because the putting is done in-place, we need to enforce | ||
# that the object being passed in is an instance of ndarray | ||
if not isinstance(a, mu.ndarray): |
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.
Is there really no way to currently call np.put
on a non-ndarray and get a correct results? If not, this is a breaking API change that we need to be extreme cautious about.
My understanding is that the reason why pandas accepts @gfyoung I appreciate your efforts but, like @charris, don't agree with the direction in this PR. Matching strings in error messages is slow and fragile, and the logic in I think the current approach used by these functions (calling the method if it exists, with keyword arguments as fixed by your PR #7325) is about as far as we can reasonably take duck typing. If the author of a duck array class wishes to be compatible with future signature changes to NumPy functions, they can include |
@shoyer : Given the push-back, fair enough. Where should this be documented? |
I don't see a really obvious best fit, but maybe either of these pages: http://docs.scipy.org/doc/numpy/reference/arrays.classes.html The other obvious place would simply be in the docstring of methods such as |
+1 for documenting this in the subclassing doc, not in docstrings (not directly relevant for most |
@@ -555,6 +555,21 @@ def __array_wrap__(self, arr, context=None): | |||
how this can work, have a look at the ``memmap`` class in | |||
``numpy.core``. | |||
|
|||
Subclassing and Downstream Compatibility |
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.
This section should focus on concrete examples of how NumPy accommodates subclasses and duck-type arrays in its API. For example, the way that numpy functions like np.sum
attempt to call object methods, and what signature your sum
method needs to have for this to work. Without context, it's not clear what it means to be "compatible with numpy's method".
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.
Sure thing, done.
@gfyoung thanks for bearing with me, the doc page looks great to me now. Anyone else have feedback? |
Thanks @gfyoung |
Yet another fun journey for me down compatibility lane forfromnumeric.py
. Closes #7460. As was the case in #7325, this PR does not destroy any old functionality or compatibility, only improves it.Updates documentation regarding
numpy
's responsibility to ensure downstream compatibility.Closes #7460.