[pypy-issue] Issue #3138: `space.eq_w` and NaN (pypy/pypy)

Yannick Jadoul issues-reply at bitbucket.org
Mon Dec 30 14:47:35 EST 2019

New issue 3138: `space.eq_w` and NaN

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://bugs.python.org/issue24700) & [https://github.com/python/cpython/pull/3009](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?

More information about the pypy-issue mailing list