-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
BUG : np.sum silently drops keepdims for sub-classes of ndarray #4619
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
Should probably replace this with a mechanism of |
Huh, seems I broke a bunch of matrix tests |
You can't know if a subclass implements |
Are there existing sub-classes that don't support It looks like a whole bunch of similar functions ( Still having a bit of trouble squaring what you are saying with my (probably wrong) mental model of how this is working underneath, and the errors from the test suite. |
@tacaswell, the thing is, we cannot know that since any third party library could subclass ndarray. What I mean is:
|
@seberg's snippet might be better written kwargs = {}
|
keepdims is a boolean so it should be and I think we do need to add this to all functions were we are currently wrapping subclasses |
Slowly starting to understand. This is going to involve touching a large number of the functions in I am using @njsmith 's pattern. When I have all the tests passing locally I will replace this branch. |
I think I have it working. If people are happy with this method of addressing the issue I will add tests for all of the functions I changed + update the documentation. |
@tcaswell needs a rebase. |
I wish all rebases were that easy |
why is keepdims changed to |
if type(a) is not mu.ndarray: | ||
try: | ||
amax = a.max | ||
except AttributeError: | ||
return _methods._amax(a, axis=axis, | ||
out=out, keepdims=keepdims) | ||
out=out, **kwargs) | ||
# NOTE: Dropping the keepdims parameter |
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 comment is obsolete now
I wonder if we shoud inspect the subclass and check if it really supports keepdims |
The default value is changed to In either case now the result of |
Aside the fact that it might seem weird that a subclass should override the default. |
I don't really like changing an argument type for this, aren't array subclasses almost always python classes? then you can get the default the class uses for the function:
we can also use this to warn when a subclass does not support the argument but the user passed the non-default |
I don't like trying to use introspection for this, but I agree that changing the public API is a bit nasty. Maybe it would be better to use an internal |
What is the advantage of using |
The idea is to make it an implementation detail and minimize the API Actually I'm not sure why we shouldn't just use **kwargs for keepdims, out,
|
I am still not convinced about I do like the idea of changing to using |
Please no
|
What's wrong with kwargs? I agree that we should try to avoid it in Note that passing keepdims=None here does not mean to call the delegatee On Thu, Apr 24, 2014 at 7:03 AM, Ralf Gommers notifications@github.comwrote:
Nathaniel J. Smith |
How bad is dropping introspection support when using kwargs? With kwargs, I would want an error right away though if there is anything but EDIT: So to say, I would be for just doing |
It seems the consensus is to create a I will get to this sometime today. |
@njsmith you know why we need to avoid kwargs in general. Adding it to 18 functions (if I counted correctly) is therefore 18x doing something that is best avoided.
|
I'm fine with _NotGiven, but it's basically just an ad hoc reimplementation The real problem is that we have 18 different functions that are just Maybe at some point we can replace most of these by thin wrappers around On Thu, Apr 24, 2014 at 5:36 PM, Ralf Gommers notifications@github.comwrote:
Nathaniel J. Smith |
whats wrong with using can one check the type of an argument fast if it is a python object and no c-extension object? I'm thinking about improving the argument parsing speed of ufunc reductions which would require fast default checks. If not I would prefer
|
|
@juliantaylor agree that the |
That's what I was thinking. There were a few other failures on AppVeyor and I have put them in this issue ( #6991 ). |
1d80259
to
75db4e0
Compare
Commits squashed and made the special case in |
I think the "documentation" was just adding a short mention in the compatibility section of the release notes probably. They are in doc/release/. Did not read the code, but seems a bit of a shame that we stalled this for so long. |
@@ -1826,15 +1835,14 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=False): | |||
sum = a.sum | |||
except AttributeError: | |||
return _methods._sum(a, axis=axis, dtype=dtype, |
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.
Sorry to raise a stylistic point at this late stage, but since the return _methods._sum
call is now identical to the one at the end, I would suggest rewriting this (as well as other occurrences further down) as:
# no need to elif here; always returned output above
if type(a) is not mu.ndarray:
try:
sum = a.sum
except AttributeError:
pass
else:
return sum(axis=axis, dtype=dtype, out=out, **kwargs)
return _methods._sum(a, axis=axis, dtype=dtype, out=out, **kwargs)
f0fac00
to
a08f94c
Compare
Two tests are failing on the above which I suspect is un-related to these changes. |
@charris do you want to backport this? While I like it, I think the default is probably no backport, which would mean that it should be in the 1.12 release notes. Don't worry about those test failures, some setuptools stuff I don't even want to know about :). |
Yeah, let's leave this for 1.12 -- it probably won't create any surprises On Fri, Feb 5, 2016 at 11:52 AM, seberg notifications@github.com wrote:
Nathaniel J. Smith -- https://vorpus.org http://vorpus.org |
a08f94c
to
7b6c143
Compare
done |
☔ The latest upstream changes (presumably #7181) made this pull request unmergeable. Please resolve the merge conflicts. |
change test from `type(a) is not mu.ndarray` to `not isinstance(a, mu.ndarray)` Because every sub-class of ndarray is not guaranteed to implement `keepdims` as a kwarg, when wrapping these methods care must be taken. The previous behavior was to silently eat the kwarg when dealing with a sub-class of ndarray. Now, if `keepdims=np._NoValue` (the new default) it is not passed through to the underlying function call (so the default value of `keepdims` is now controlled by the sub-class). If `keepdims` is not `np._NoValue` then it is passed through and will raise an exception if the sub-class does not support the kwarg. A special case in nanvar was required to deal with `matrix` that previously relied on `fromnumeric` silently dropping `keepdims`.
Move the calls to user-provided versions of std, var, and mean on non mu.ndarray objects out of the `try` block so that numpy will not mask AttributeError raised during the execution of the function rather than due to the object not having the required method.
In sum, amax, amin, and prod simplify the logic to remove an identical return statement / call to `_methods._xxx`. This removes several elif/else pairs and reduces the number of exit points from the functions but makes the code path a bit more complicated to trace.
7b6c143
to
e1621a9
Compare
@@ -163,9 +164,14 @@ def nanmin(a, axis=None, out=None, keepdims=False): | |||
|
|||
.. versionadded:: 1.8.0 | |||
keepdims : bool, optional | |||
If this is set to True, the axes which are reduced are left in the |
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 is due to line wrap changes in #7181
BUG : np.sum silently drops keepdims for sub-classes of ndarray
Backported for 1.11.1. |
change test from
type(a) is not mu.ndarray
tonot isinstance(a, mu.ndarray)
This bug can be demonstrated by: