[Numpy-discussion] Numpy 'None' comparison FutureWarning
Sebastian Berg
sebastian at sipsolutions.net
Sat Jan 31 16:59:08 EST 2015
On Sa, 2015-01-31 at 09:02 -0500, Benjamin Root wrote:
> Finally got off my butt and hunted down an example, and it was right
> under my nose in mplot3d.
>
> lib/python2.7/site-packages/mpl_toolkits/mplot3d/axes3d.py:1094: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
> if self.button_pressed in self._rotate_btn:
> self._rotate_btn is the 1d numpy array, and self.button_pressed
> usually will have an integer (for which mouse button), but could be
> None if no mouse button was pressed. I have no clue why the "in"
> operator is triggering this future warning. Is this intentional?
If I remember right, the in operator just does `np.any(arr == other)` in
C-code (which is actually a bit broken, in more ways then just this….).
So in this case the FutureWarning is admittingly bogus, since the result
won't actually change unless your array really *does* include None, and
then I hope you want that change ;).
- Sebastian
> Ben Root
>
>
> On Sun, Sep 21, 2014 at 10:53 PM, Nathaniel Smith <njs at pobox.com>
> wrote:
> On 22 Sep 2014 03:02, "Demitri Muna" <demitri.muna at gmail.com>
> wrote:
> >
> >
> > On Sep 21, 2014, at 5:19 PM, Eric Firing
> <efiring at hawaii.edu> wrote:
> >
> >> I think what you are missing is that the standard Python
> idiom for this
> >> use case is "if self._some_array is None:". This will
> continue to work,
> >> regardless of whether the object being checked is an
> ndarray or any
> >> other Python object.
> >
> >
> > That's an alternative, but I think it's a subtle distinction
> that will be lost on many users. I still think that this is
> something that can easily trip up many people; it's not clear
> from looking at the code that this is the behavior; it's
> "hidden". At the very least, I strongly suggest that the
> warning point this out, e.g.
> >
> > "FutureWarning: comparison to `None` will result in an
> elementwise object comparison in the future; use 'value is
> None' as an alternative."
>
> Making messages clearer is always welcome, and we devs aren't
> always in the best position to do so because we're to close to
> the issues to see which parts are confusing to outsiders -
> perhaps you'd like to submit a pull request with this?
>
> > Assume:
> >
> > a = np.array([1, 2, 3, 4])
> > b = np.array([None, None, None, None])
> >
> > What is the result of "a == None"? Is it "np.array([False,
> False, False, False])"?
>
> After this change, yes.
>
> > What about the second case? Is the result of "b == None" ->
> np.array([True, True, True, True])?
>
> Yes again.
>
> (Notice that this is also a subtle and confusing point for
> many users - how many people realize that if they want to get
> the latter result they have to write np.equal(b, None)?)
>
> > If so, then
> >
> > if (b == None):
> > ...
> >
> > will always evaluate to "True" if b is "None" or *any* Numpy
> array, and that's clearly unexpected behavior.
>
> No, that's not how numpy arrays interact with if statements.
> This is independent of the handling of 'arr == None': 'if
> multi_element_array' is always an error, because an if
> statement by definition requires a single true/false decision
> (it can't execute both branches after all!), but a
> multi-element array by definition contains multiple values
> that might have contradictory truthiness.
>
> Currently, 'b == x' returns an array in every situation
> *except* when x happens to be 'None'. After this change, 'b ==
> x' will *always* return an array, so 'if b == x' will always
> raise an error.
>
> >
> > On Sep 21, 2014, at 9:30 PM, Benjamin Root <ben.root at ou.edu>
> wrote:
> >
> >> That being said, I do wonder about related situations where
> the lhs of the equal sign might be an array, or it might be a
> None and you are comparing against another numpy array. In
> those situations, you aren't trying to compare against None,
> you are just checking if two objects are equivalent.
>
> Benjamin, can you give a more concrete example? Right now the
> *only* time == on arrays checks for equivalence is when the
> object being compared against is None, in which case ==
> pretends to be 'is' because of this mysterious special case.
> In every other case it does a broadcasted ==, which is very
> different.
>
> > Right. With this change, using "==" with numpy arrays now
> sometimes means "are these equivalent" and other times
> "element-wise comparison".
>
> Err, you have this backwards :-). Right now == means
> element-wise comparison except in this one special case, where
> it doesn't. After the change, it will mean element-wise
> comparison consistently in all cases.
>
> > The potential for inadvertent bugs is far greater than what
> convenience this redefinition of a very basic operator might
> offer. Any scenario where
> >
> > (a == b) != (b == a)
> >
> > is asking for trouble.
>
> That would be unfortunate, yes, but fortunately it doesn't
> apply here :-). 'a == b' and 'b == a' currently always return
> the same thing, and there are no plans to change this - we'll
> be changing what both of them mean at the same time.
>
> -n
>
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
>
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20150131/60d12a8a/attachment.sig>
More information about the NumPy-Discussion
mailing list