diff options
Diffstat (limited to 'py/objtuple.c')
-rw-r--r-- | py/objtuple.c | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/py/objtuple.c b/py/objtuple.c index 9434b418cd..b56c6433f6 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -41,7 +41,7 @@ STATIC mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, int cur); /******************************************************************************/ /* tuple */ -void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { +void mp_obj_tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_tuple_t *o = o_in; print(env, "("); for (int i = 0; i < o->len; i++) { @@ -56,15 +56,16 @@ void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_o print(env, ")"); } -mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // TODO check n_kw == 0 +STATIC mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 0, 1, false); switch (n_args) { case 0: // return a empty tuple return mp_const_empty_tuple; - case 1: { + case 1: + default: { // 1 argument, an iterable from which we make a new tuple if (MP_OBJ_IS_TYPE(args[0], &mp_type_tuple)) { return args[0]; @@ -91,50 +92,53 @@ mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m return tuple; } - - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "tuple takes at most 1 argument, %d given", n_args)); } } // Don't pass MP_BINARY_OP_NOT_EQUAL here STATIC bool tuple_cmp_helper(int op, mp_obj_t self_in, mp_obj_t another_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_tuple)); - if (!MP_OBJ_IS_TYPE(another_in, &mp_type_tuple)) { - return false; + mp_obj_type_t *self_type = mp_obj_get_type(self_in); + if (self_type->getiter != mp_obj_tuple_getiter) { + assert(0); } + mp_obj_type_t *another_type = mp_obj_get_type(another_in); mp_obj_tuple_t *self = self_in; mp_obj_tuple_t *another = another_in; + if (another_type->getiter != mp_obj_tuple_getiter) { + // Slow path for user subclasses + another = mp_instance_cast_to_native_base(another, &mp_type_tuple); + if (another == MP_OBJ_NULL) { + return false; + } + } return mp_seq_cmp_objs(op, self->items, self->len, another->items, another->len); } -mp_obj_t tuple_unary_op(int op, mp_obj_t self_in) { +mp_obj_t mp_obj_tuple_unary_op(int op, mp_obj_t self_in) { mp_obj_tuple_t *self = self_in; switch (op) { case MP_UNARY_OP_BOOL: return MP_BOOL(self->len != 0); case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(self->len); - default: return MP_OBJ_NOT_SUPPORTED; + default: return MP_OBJ_NULL; // op not supported } } -mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { +mp_obj_t mp_obj_tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_tuple_t *o = lhs; switch (op) { - case MP_BINARY_OP_ADD: - { + case MP_BINARY_OP_ADD: { if (!mp_obj_is_subclass_fast(mp_obj_get_type(rhs), (mp_obj_t)&mp_type_tuple)) { - return NULL; + return MP_OBJ_NULL; // op not supported } mp_obj_tuple_t *p = rhs; mp_obj_tuple_t *s = mp_obj_new_tuple(o->len + p->len, NULL); - m_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); + mp_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); return s; } - case MP_BINARY_OP_MULTIPLY: - { + case MP_BINARY_OP_MULTIPLY: { if (!MP_OBJ_IS_SMALL_INT(rhs)) { - return NULL; + return MP_OBJ_NULL; // op not supported } int n = MP_OBJ_SMALL_INT_VALUE(rhs); mp_obj_tuple_t *s = mp_obj_new_tuple(o->len * n, NULL); @@ -149,34 +153,33 @@ mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { return MP_BOOL(tuple_cmp_helper(op, lhs, rhs)); default: - // op not supported - return NULL; + return MP_OBJ_NULL; // op not supported } } -mp_obj_t tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { +mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_SENTINEL) { // load mp_obj_tuple_t *self = self_in; -#if MICROPY_ENABLE_SLICE +#if MICROPY_PY_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { machine_uint_t start, stop; - if (!m_seq_get_fast_slice_indexes(self->len, index, &start, &stop)) { + if (!mp_seq_get_fast_slice_indexes(self->len, index, &start, &stop)) { assert(0); } mp_obj_tuple_t *res = mp_obj_new_tuple(stop - start, NULL); - m_seq_copy(res->items, self->items + start, res->len, mp_obj_t); + mp_seq_copy(res->items, self->items + start, res->len, mp_obj_t); return res; } #endif uint index_value = mp_get_index(self->base.type, self->len, index, false); return self->items[index_value]; } else { - return MP_OBJ_NOT_SUPPORTED; + return MP_OBJ_NULL; // op not supported } } -STATIC mp_obj_t tuple_getiter(mp_obj_t o_in) { +mp_obj_t mp_obj_tuple_getiter(mp_obj_t o_in) { return mp_obj_new_tuple_iterator(o_in, 0); } @@ -204,12 +207,12 @@ STATIC MP_DEFINE_CONST_DICT(tuple_locals_dict, tuple_locals_dict_table); const mp_obj_type_t mp_type_tuple = { { &mp_type_type }, .name = MP_QSTR_tuple, - .print = tuple_print, + .print = mp_obj_tuple_print, .make_new = mp_obj_tuple_make_new, - .unary_op = tuple_unary_op, - .binary_op = tuple_binary_op, - .subscr = tuple_subscr, - .getiter = tuple_getiter, + .unary_op = mp_obj_tuple_unary_op, + .binary_op = mp_obj_tuple_binary_op, + .subscr = mp_obj_tuple_subscr, + .getiter = mp_obj_tuple_getiter, .locals_dict = (mp_obj_t)&tuple_locals_dict, }; |