[Numpy-discussion] truthiness of object arrays
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(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__
> >>> 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__()
> >>> 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:
>>> 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()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'numpy.ndarray' object has no attribute '__nonzero__'
Nathaniel J. Smith
Postdoctoral researcher - Informatics - University of Edinburgh
More information about the NumPy-Discussion