summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2017-09-04 14:16:27 +1000
committerDamien George <damien.p.george@gmail.com>2017-09-04 14:16:27 +1000
commitd4b75f6b6822885e331c69a74e56e23af40a6264 (patch)
treeab0d1c7d77cb366abc9379b00b22cee07aa9a9c1 /py
parent9950865c39044e9fef295d0676af7c5fd55289ea (diff)
py/obj: Fix comparison of float/complex NaN with itself.
IEEE floating point is specified such that a comparison of NaN with itself returns false, and Python respects these semantics. This patch makes uPy also have these semantics. The fix has a minor impact on the speed of the object-equality fast-path, but that seems to be unavoidable and it's much more important to have correct behaviour (especially in this case where the wrong answer for nan==nan is silently returned).
Diffstat (limited to 'py')
-rw-r--r--py/obj.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/py/obj.c b/py/obj.c
index 90ce47e8f..857fe373f 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -162,7 +162,16 @@ bool mp_obj_is_callable(mp_obj_t o_in) {
// comparison returns NotImplemented, == and != are decided by comparing the object
// pointer."
bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
- if (o1 == o2) {
+ // Float (and complex) NaN is never equal to anything, not even itself,
+ // so we must have a special check here to cover those cases.
+ if (o1 == o2
+ #if MICROPY_PY_BUILTINS_FLOAT
+ && !mp_obj_is_float(o1)
+ #endif
+ #if MICROPY_PY_BUILTINS_COMPLEX
+ && !MP_OBJ_IS_TYPE(o1, &mp_type_complex)
+ #endif
+ ) {
return true;
}
if (o1 == mp_const_none || o2 == mp_const_none) {