...
 
Commits (5)
1.0 1.0
-1.0 1.0
0.0 0.0
-0.0 0.0
nan nan
-nan nan
inf inf
-inf inf
# test builtin abs function with float args
for val in (
'1.0',
'-1.0',
'0.0',
'-0.0',
'nan',
'-nan',
'inf',
'-inf',
):
print(val, abs(float(val)))
ValueError
ValueError
ValueError
ValueError
ValueError
ValueError
bytearray(b'\x00\x01')
ValueError
# test passing in out-of-bounds bytes to bytearray
try:
bytearray([-1])
except ValueError:
print('ValueError')
try:
bytearray([256])
except ValueError:
print('ValueError')
try:
bytearray(1)[0] = -1
except ValueError:
print('ValueError')
try:
bytearray(1)[0] = 256
except ValueError:
print('ValueError')
try:
bytearray().append(-1)
except ValueError:
print('ValueError')
try:
bytearray().append(256)
except ValueError:
print('ValueError')
# bigint values should be ok if they are in bounds
big = 1 << 70
big_zero = big - big
big_one = big >> 70
print(bytearray([big_zero, big_one]))
try:
bytearray([-big_one])
except ValueError:
print('ValueError')
......@@ -324,6 +324,16 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **
void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t val_in) {
switch (typecode) {
// Special case for bytearray to check bounds
case BYTEARRAY_TYPECODE: {
mp_int_t val = mp_obj_get_int(val_in);
if (val < 0 || val > 255) {
mp_raise_msg(&mp_type_ValueError, "byte out of range");
}
((uint8_t*)p)[index] = val & 0xff;
break;
}
#if MICROPY_PY_BUILTINS_FLOAT
case 'f':
((float*)p)[index] = mp_obj_get_float(val_in);
......
......@@ -231,7 +231,6 @@ STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, size_t n_args, c
}
STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) {
// TODO: "The arguments must match the values required by the format exactly."
mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0]));
vstr_t vstr;
vstr_init_len(&vstr, size);
......
......@@ -161,8 +161,7 @@ STATIC mp_obj_t float_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
case MP_UNARY_OP_POSITIVE: return o_in;
case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-val);
case MP_UNARY_OP_ABS: {
// TODO check for NaN etc
if (val < 0) {
if (signbit(val)) {
return mp_obj_new_float(-val);
} else {
return o_in;
......
......@@ -136,8 +136,6 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_
// Explicitly mark generator as completed. If we don't do this,
// subsequent next() may re-execute statements after last yield
// again and again, leading to side effects.
// TODO: check how return with value behaves under such conditions
// in CPython.
self->code_state.ip = 0;
*ret_val = *self->code_state.sp;
break;
......
......@@ -69,7 +69,6 @@ STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args,
case 2:
default: {
// should be a string, parse it
// TODO proper error checking of argument types
size_t l;
const char *s = mp_obj_str_get_data(args[0], &l);
return mp_parse_num_integer(s, l, mp_obj_get_int(args[1]), NULL);
......
......@@ -84,7 +84,6 @@ STATIC void module_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
mp_obj_dict_delete(MP_OBJ_FROM_PTR(dict), MP_OBJ_NEW_QSTR(attr));
} else {
// store attribute
// TODO CPython allows STORE_ATTR to a module, but is this the correct implementation?
mp_obj_dict_store(MP_OBJ_FROM_PTR(dict), MP_OBJ_NEW_QSTR(attr), dest[1]);
}
dest[0] = MP_OBJ_NULL; // indicate success
......
......@@ -34,8 +34,6 @@
#if MICROPY_PY_BUILTINS_SLICE
// TODO: This implements only variant of slice with 2 integer args only.
// CPython supports 3rd arg (step), plus args can be arbitrary Python objects.
typedef struct _mp_obj_slice_t {
mp_obj_base_t base;
mp_obj_t start;
......
......@@ -568,7 +568,6 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des
mp_map_elem_t *elem = mp_map_lookup(&self->members, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
if (elem != NULL) {
// object member, always treated as a value
// TODO should we check for properties?
dest[0] = elem->value;
return;
}
......@@ -976,8 +975,6 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
} else {
// delete/store attribute
// TODO CPython allows STORE_ATTR to a class, but is this the correct implementation?
if (self->locals_dict != NULL) {
assert(self->locals_dict->base.type == &mp_type_dict); // MicroPython restriction, for now
mp_map_t *locals_map = &self->locals_dict->map;
......
......@@ -1512,7 +1512,7 @@ unwind_loop:
#endif
} else {
// propagate exception to higher level
// TODO what to do about ip and sp? they don't really make sense at this point
// Note: ip and sp don't have usable values at this point
fastn[0] = MP_OBJ_FROM_PTR(nlr.ret_val); // must put exception here because sp is invalid
return MP_VM_RETURN_EXCEPTION;
}
......
# test builtin abs function with float args
for val in (
'1.0',
'-1.0',
'0.0',
'-0.0',
'nan',
'-nan',
'inf',
'-inf',
):
print(val, abs(float(val)))