8000 py/objfloat: Fix binary ops with incompatible objects. · guidebee/micropython@9950865 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9950865

Browse files
committed
py/objfloat: Fix binary ops with incompatible objects.
These are now returned as "operation not supported" instead of raising TypeError. In particular, this fixes equality for float vs incompatible types, which now properly results in False instead of exception. This also paves the road to support reverse operation (e.g. __radd__) with float objects. This is achieved by introducing mp_obj_get_float_maybe(), similar to existing mp_obj_get_int_maybe().
1 parent dd376a2 commit 9950865

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
lines changed

py/obj.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,27 +264,42 @@ bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value) {
264264
}
265265

266266
#if MICROPY_PY_BUILTINS_FLOAT
267-
mp_float_t mp_obj_get_float(mp_obj_t arg) {
267+
bool mp_obj_get_float_maybe(mp_obj_t arg, mp_float_t *value) {
268+
mp_float_t val;
269+
268270
if (arg == mp_const_false) {
269-
return 0;
271+
val = 0;
270272
} else if (arg == mp_const_true) {
271-
return 1;
273+
val = 1;
272274
} else if (MP_OBJ_IS_SMALL_INT(arg)) {
273-
return MP_OBJ_SMALL_INT_VALUE(arg);
275+
val = MP_OBJ_SMALL_INT_VALUE(arg);
274276
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
275277
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) {
276-
return mp_obj_int_as_float_impl(arg);
278+
val = mp_obj_int_as_float_impl(arg);
277279
#endif
278280
} else if (mp_obj_is_float(arg)) {
279-
return mp_obj_float_get(arg);
281+
val = mp_obj_float_get(arg);
280282
} else {
283+
return false;
284+
}
285+
286+
*value = val;
287+
return true;
288+
}
289+
290+
mp_float_t mp_obj_get_float(mp_obj_t arg) {
291+
mp_float_t val;
292+
293+
if (!mp_obj_get_float_maybe(arg, &val)) {
281294
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
282295
mp_raise_TypeError("can't convert to float");
283296
} else {
284297
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
285298
"can't convert %s to float", mp_obj_get_type_str(arg)));
286299
}
287300
}
301+
302+
return val;
288303
}
289304

290305
#if MICROPY_PY_BUILTINS_COMPLEX

py/obj.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ mp_int_t mp_obj_get_int_truncated(mp_const_obj_t arg);
686686
bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value);
687687
#if MICROPY_PY_BUILTINS_FLOAT
688688
mp_float_t mp_obj_get_float(mp_obj_t self_in);
689+
bool mp_obj_get_float_maybe(mp_obj_t arg, mp_float_t *value);
689690
void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
690691
#endif
691692
//qstr mp_obj_get_qstr(mp_obj_t arg);

py/objfloat.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,11 @@ STATIC void mp_obj_float_divmod(mp_float_t *x, mp_float_t *y) {
240240
}
241241

242242
mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t rhs_in) {
243-
mp_float_t rhs_val = mp_obj_get_float(rhs_in); // can be any type, this function will convert to float (if possible)
243+
mp_float_t rhs_val;
244+
if (!mp_obj_get_float_maybe(rhs_in, &rhs_val)) {
245+
return MP_OBJ_NULL; // op not supported
246+
}
247+
244248
switch (op) {
245249
case MP_BINARY_OP_ADD:
246250
case MP_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break;

tests/float/float_compare.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Extended float comparisons
2+
3+
class Foo:
4+
pass
5+
6+
foo = Foo()
7+
8+
print(foo == 1.0)
9+
print(1.0 == foo)
10+
print(1.0 == Foo)
11+
print(1.0 == [])
12+
print(1.0 == {})
13+
14+
try:
15+
print(foo < 1.0)
16+
except TypeError:
17+
print("TypeError")
18+
19+
try:
20+
print(1.0 < foo)
21+
except TypeError:
22+
print("TypeError")

0 commit comments

Comments
 (0)
0