Fix assertion failures in mp_obj_new_type

Fixes the following assertion failures when the arguments to type()
were not of valid types:
micropython: ../../py/objtype.c:984: mp_obj_new_type: Assertion `MP_OBJ_IS_TYPE(bases_tuple, &mp_type_tuple)' failed.
micropython: ../../py/objtype.c:994: mp_obj_new_type: Assertion `MP_OBJ_IS_TYPE(items[i], &mp_type_type)' failed.

e.g., when making calls like
    type("", (), 3)
    type("", 3, {})
This commit is contained in:
Jeff Epler 2018-03-25 16:05:32 -05:00 committed by Jeff Epler
parent a55988a547
commit 6da8d7c465
2 changed files with 31 additions and 3 deletions

View File

@ -981,8 +981,14 @@ const mp_obj_type_t mp_type_type = {
};
mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) {
assert(MP_OBJ_IS_TYPE(bases_tuple, &mp_type_tuple)); // MicroPython restriction, for now
assert(MP_OBJ_IS_TYPE(locals_dict, &mp_type_dict)); // MicroPython restriction, for now
if(!MP_OBJ_IS_TYPE(bases_tuple, &mp_type_tuple)) {
// MicroPython restriction, for now
mp_raise_TypeError("type() argument 2 must be tuple");
}
if(!MP_OBJ_IS_TYPE(locals_dict, &mp_type_dict)) {
// MicroPython restriction, for now
mp_raise_TypeError("type() argument 3 must be dict");
}
// TODO might need to make a copy of locals_dict; at least that's how CPython does it
@ -991,7 +997,9 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
mp_obj_t *items;
mp_obj_tuple_get(bases_tuple, &len, &items);
for (size_t i = 0; i < len; i++) {
assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type));
if(!MP_OBJ_IS_TYPE(items[i], &mp_type_type)) {
mp_raise_TypeError("type is not an acceptable base type");
}
mp_obj_type_t *t = MP_OBJ_TO_PTR(items[i]);
// TODO: Verify with CPy, tested on function type
if (t->make_new == NULL) {

20
tests/basics/types3.py Normal file
View File

@ -0,0 +1,20 @@
try:
type('abc', None, None)
except TypeError:
print(True)
else:
print(False)
try:
type('abc', (), None)
except TypeError:
print(True)
else:
print(False)
try:
type('abc', (1,), {})
except TypeError:
print(True)
else:
print(False)