`space.eq_w` and NaN
Created originally on Bitbucket by Yannick_Jadoul (Yannick Jadoul)
Investigating the failure of a test in lib-python/3/test/test_array.py
, I noticed that the only reason it’s only failing on the py3.7
branch is because the test (comparing two array.array
s containing each one float('nan')
) was added in CPython 3.7 (see https://bugs.python.org/issue24700 & https://github.com/python/cpython/pull/3009). The same bug is present in py3.6
and default
.
Even more worryingly, the problem seems to be that space.eq_w
is used in pypy/module/array/interp_array.py
's function compare_arrays
:
# ...
if comp_op == EQ:
res = space.eq_w(w_elem1, w_elem2)
if not res:
return space.w_False
elif comp_op == NE:
res = space.is_true(space.ne(w_elem1, w_elem2))
if res:
return space.w_True
# ...
When space.eq_w(w_elem1, w_elem2)
is replaced by space.is_true(space.eq(w_elem1, w_elem2))
, the test succeeds, and the two array.array
s of one NaN are not compared to be equal anymore.
The problem seems to be that space.eq_w
is defined as return self.is_w(w_obj1, w_obj2) or self.is_true(self.eq(w_obj1, w_obj2))
, and that the evalutation of is
works as a shortcut for most types and instances, but not for NaN float
s or classes that define a weird kind of equality operator.
Rather than fixing array.array
by replacing eq_w(...)
with is_true(eq(...))
, I thought I’d report the issue, as this might affect a whole bunch of other things?