diff --git a/py/objdeque.c b/py/objdeque.c index 264c795801ba4..4e1ee82e9d4de 100644 --- a/py/objdeque.c +++ b/py/objdeque.c @@ -46,6 +46,11 @@ static mp_obj_t mp_obj_deque_extend(mp_obj_t self_in, mp_obj_t arg_in); static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque, mp_obj_iter_buf_t *iter_buf); #endif +// CIRCUITPY-CHANGE +static mp_obj_deque_t *native_deque(mp_obj_t self_in) { + return MP_OBJ_TO_PTR(mp_obj_cast_to_native_base(self_in, MP_OBJ_FROM_PTR(&mp_type_deque))); +} + static mp_obj_t deque_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 2, 3, false); @@ -79,7 +84,8 @@ static size_t deque_len(mp_obj_deque_t *self) { } static mp_obj_t deque_unary_op(mp_unary_op_t op, mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); switch (op) { case MP_UNARY_OP_BOOL: return mp_obj_new_bool(self->i_get != self->i_put); @@ -98,7 +104,8 @@ static mp_obj_t deque_unary_op(mp_unary_op_t op, mp_obj_t self_in) { } static mp_obj_t mp_obj_deque_append(mp_obj_t self_in, mp_obj_t arg) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); size_t new_i_put = self->i_put + 1; if (new_i_put == self->alloc) { @@ -123,7 +130,8 @@ static mp_obj_t mp_obj_deque_append(mp_obj_t self_in, mp_obj_t arg) { static MP_DEFINE_CONST_FUN_OBJ_2(deque_append_obj, mp_obj_deque_append); static mp_obj_t mp_obj_deque_appendleft(mp_obj_t self_in, mp_obj_t arg) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); size_t new_i_get = self->i_get - 1; if (self->i_get == 0) { @@ -162,7 +170,8 @@ static mp_obj_t mp_obj_deque_extend(mp_obj_t self_in, mp_obj_t arg_in) { static MP_DEFINE_CONST_FUN_OBJ_2(deque_extend_obj, mp_obj_deque_extend); static mp_obj_t deque_popleft(mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); if (self->i_get == self->i_put) { mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty")); @@ -180,7 +189,8 @@ static mp_obj_t deque_popleft(mp_obj_t self_in) { static MP_DEFINE_CONST_FUN_OBJ_1(deque_popleft_obj, deque_popleft); static mp_obj_t deque_pop(mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); if (self->i_get == self->i_put) { mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty")); @@ -205,7 +215,8 @@ static mp_obj_t deque_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { // delete not supported, fall back to mp_obj_subscr() error message return MP_OBJ_NULL; } - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); size_t offset = mp_get_index(self->base.type, deque_len(self), index, false); size_t index_val = self->i_get + offset; @@ -226,7 +237,8 @@ static mp_obj_t deque_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { #if 0 static mp_obj_t deque_clear(mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); self->i_get = self->i_put = 0; mp_seq_clear(self->items, 0, self->alloc, sizeof(*self->items)); return mp_const_none; @@ -286,7 +298,8 @@ typedef struct _mp_obj_deque_it_t { static mp_obj_t deque_it_iternext(mp_obj_t self_in) { mp_obj_deque_it_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_deque_t *deque = MP_OBJ_TO_PTR(self->deque); + // CIRCUITPY-CHANGE + mp_obj_deque_t *deque = native_deque(self->deque); if (self->cur != deque->i_put) { mp_obj_t o_out = deque->items[self->cur]; if (++self->cur == deque->alloc) { @@ -298,9 +311,10 @@ static mp_obj_t deque_it_iternext(mp_obj_t self_in) { } } -static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque, mp_obj_iter_buf_t *iter_buf) { - mp_obj_deque_t *deque_ = MP_OBJ_TO_PTR(deque); - size_t i_get = deque_->i_get; +static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque_in, mp_obj_iter_buf_t *iter_buf) { + // CIRCUITPY-CHANGE + mp_obj_deque_t *deque = native_deque(deque_in); + size_t i_get = deque->i_get; assert(sizeof(mp_obj_deque_it_t) <= sizeof(mp_obj_iter_buf_t)); mp_obj_deque_it_t *o = (mp_obj_deque_it_t *)iter_buf; o->base.type = &mp_type_polymorph_iter; diff --git a/tests/circuitpython/deque_subclass.py b/tests/circuitpython/deque_subclass.py new file mode 100644 index 0000000000000..5708407a9b630 --- /dev/null +++ b/tests/circuitpython/deque_subclass.py @@ -0,0 +1,40 @@ +try: + from collections import deque +except ImportError: + print("SKIP") + raise SystemExit + + +class DequeSubclass(deque): + def __init__(self, values, maxlen): + super().__init__(values, maxlen) + + def pop(self): + print("pop") + return super().pop() + + def popleft(self): + print("popleft") + return super().popleft() + + def append(self, value): + print("append") + return super().append(value) + + def appendleft(self, value): + print("appendleft") + return super().appendleft(value) + + def extend(self, value): + print("extend") + return super().extend(value) + + +d = DequeSubclass([1, 2, 3], 10) +print(d.append(4)) +print(d.appendleft(0)) +print(d.pop()) +print(d.popleft()) +d.extend([6, 7]) +# calling list() tests iteration. +print(list(d))