[Numpy-discussion] truthiness of object arrays

Nathaniel Smith njs at pobox.com
Thu Nov 13 13:32:06 EST 2014


On Thu, Nov 13, 2014 at 1:24 PM, Alan G Isaac <alan.isaac at gmail.com> wrote:
> On 11/13/2014 1:19 AM, Antony Lee wrote:
>> "t.__bool__()" also returns True
>
> But t.__nonzero__() is being called in the `if` test.
> The question is: is the difference between `__nonzero__`
> and `__bool__` intentional.

__nonzero__ and __bool__ should be identical; they refer to the same
magic method, it's just that Py2 calls it __nonzero__ and Py3 calls it
__bool__.

bool(t) and 'if t: ...' should always be identical at the interpreter
level; that they aren't is probably because we're someone violating
some invariant in the Python C API (like @seberg suggested). In Py2
they both call __nonzero__, and in Py3 they both call __bool__.

> By the way, there has been a change in behavior.
> For example, in 1.7.1 if you call `t.__bool__()`
> it raised an attribute error -- unless one first
> called `t.__nonzero__()` and then called `t.__bool__()`,
> which was of course very weird and needed to be fixed.
> Maybe (?) not like this.
>
> In fact the oddity probably remains but moved. in 1.9.0 I see this:
>
>  >>> np.__version__
> '1.9.0'
>  >>> t = np.array(None); t[()] = np.array([None, None])
>  >>> t.__nonzero__()
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> AttributeError: 'numpy.ndarray' object has no attribute '__nonzero__'
>  >>> t.__bool__()
> True
>  >>> t.__nonzero__()
> ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I think you're being misled by buggy exception handling weirdness,
where the ValueError raised by calling __bool__ is getting delayed,
and then pre-empting the AttributeError that should be generated by
the call to __nonzero__. Consider:

>>> t.__bool__()
True
>>> 1  # any expression here will do
ValueError: The truth value of an array with more than one element is
ambiguous. Use a.any() or a.all()
>>> t.__nonzero__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'numpy.ndarray' object has no attribute '__nonzero__'

-n

-- 
Nathaniel J. Smith
Postdoctoral researcher - Informatics - University of Edinburgh
http://vorpus.org



More information about the NumPy-Discussion mailing list