Skip to content

Commit d585b1d

Browse files
authored
Merge pull request #10653 from dhalbert/subclass-deque
Allow subclassing deque
2 parents 64b32f6 + ea15d74 commit d585b1d

File tree

2 files changed

+65
-11
lines changed

2 files changed

+65
-11
lines changed

py/objdeque.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ static mp_obj_t mp_obj_deque_extend(mp_obj_t self_in, mp_obj_t arg_in);
4646
static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque, mp_obj_iter_buf_t *iter_buf);
4747
#endif
4848

49+
// CIRCUITPY-CHANGE
50+
static mp_obj_deque_t *native_deque(mp_obj_t self_in) {
51+
return MP_OBJ_TO_PTR(mp_obj_cast_to_native_base(self_in, MP_OBJ_FROM_PTR(&mp_type_deque)));
52+
}
53+
4954
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) {
5055
mp_arg_check_num(n_args, n_kw, 2, 3, false);
5156

@@ -79,7 +84,8 @@ static size_t deque_len(mp_obj_deque_t *self) {
7984
}
8085

8186
static mp_obj_t deque_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
82-
mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in);
87+
// CIRCUITPY-CHANGE
88+
mp_obj_deque_t *self = native_deque(self_in);
8389
switch (op) {
8490
case MP_UNARY_OP_BOOL:
8591
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) {
98104
}
99105

100106
static mp_obj_t mp_obj_deque_append(mp_obj_t self_in, mp_obj_t arg) {
101-
mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in);
107+
// CIRCUITPY-CHANGE
108+
mp_obj_deque_t *self = native_deque(self_in);
102109

103110
size_t new_i_put = self->i_put + 1;
104111
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) {
123130
static MP_DEFINE_CONST_FUN_OBJ_2(deque_append_obj, mp_obj_deque_append);
124131

125132
static mp_obj_t mp_obj_deque_appendleft(mp_obj_t self_in, mp_obj_t arg) {
126-
mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in);
133+
// CIRCUITPY-CHANGE
134+
mp_obj_deque_t *self = native_deque(self_in);
127135

128136
size_t new_i_get = self->i_get - 1;
129137
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) {
162170
static MP_DEFINE_CONST_FUN_OBJ_2(deque_extend_obj, mp_obj_deque_extend);
163171

164172
static mp_obj_t deque_popleft(mp_obj_t self_in) {
165-
mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in);
173+
// CIRCUITPY-CHANGE
174+
mp_obj_deque_t *self = native_deque(self_in);
166175

167176
if (self->i_get == self->i_put) {
168177
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) {
180189
static MP_DEFINE_CONST_FUN_OBJ_1(deque_popleft_obj, deque_popleft);
181190

182191
static mp_obj_t deque_pop(mp_obj_t self_in) {
183-
mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in);
192+
// CIRCUITPY-CHANGE
193+
mp_obj_deque_t *self = native_deque(self_in);
184194

185195
if (self->i_get == self->i_put) {
186196
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) {
205215
// delete not supported, fall back to mp_obj_subscr() error message
206216
return MP_OBJ_NULL;
207217
}
208-
mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in);
218+
// CIRCUITPY-CHANGE
219+
mp_obj_deque_t *self = native_deque(self_in);
209220

210221
size_t offset = mp_get_index(self->base.type, deque_len(self), index, false);
211222
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) {
226237

227238
#if 0
228239
static mp_obj_t deque_clear(mp_obj_t self_in) {
229-
mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in);
240+
// CIRCUITPY-CHANGE
241+
mp_obj_deque_t *self = native_deque(self_in);
230242
self->i_get = self->i_put = 0;
231243
mp_seq_clear(self->items, 0, self->alloc, sizeof(*self->items));
232244
return mp_const_none;
@@ -286,7 +298,8 @@ typedef struct _mp_obj_deque_it_t {
286298

287299
static mp_obj_t deque_it_iternext(mp_obj_t self_in) {
288300
mp_obj_deque_it_t *self = MP_OBJ_TO_PTR(self_in);
289-
mp_obj_deque_t *deque = MP_OBJ_TO_PTR(self->deque);
301+
// CIRCUITPY-CHANGE
302+
mp_obj_deque_t *deque = native_deque(self->deque);
290303
if (self->cur != deque->i_put) {
291304
mp_obj_t o_out = deque->items[self->cur];
292305
if (++self->cur == deque->alloc) {
@@ -298,9 +311,10 @@ static mp_obj_t deque_it_iternext(mp_obj_t self_in) {
298311
}
299312
}
300313

301-
static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque, mp_obj_iter_buf_t *iter_buf) {
302-
mp_obj_deque_t *deque_ = MP_OBJ_TO_PTR(deque);
303-
size_t i_get = deque_->i_get;
314+
static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque_in, mp_obj_iter_buf_t *iter_buf) {
315+
// CIRCUITPY-CHANGE
316+
mp_obj_deque_t *deque = native_deque(deque_in);
317+
size_t i_get = deque->i_get;
304318
assert(sizeof(mp_obj_deque_it_t) <= sizeof(mp_obj_iter_buf_t));
305319
mp_obj_deque_it_t *o = (mp_obj_deque_it_t *)iter_buf;
306320
o->base.type = &mp_type_polymorph_iter;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
try:
2+
from collections import deque
3+
except ImportError:
4+
print("SKIP")
5+
raise SystemExit
6+
7+
8+
class DequeSubclass(deque):
9+
def __init__(self, values, maxlen):
10+
super().__init__(values, maxlen)
11+
12+
def pop(self):
13+
print("pop")
14+
return super().pop()
15+
16+
def popleft(self):
17+
print("popleft")
18+
return super().popleft()
19+
20+
def append(self, value):
21+
print("append")
22+
return super().append(value)
23+
24+
def appendleft(self, value):
25+
print("appendleft")
26+
return super().appendleft(value)
27+
28+
def extend(self, value):
29+
print("extend")
30+
return super().extend(value)
31+
32+
33+
d = DequeSubclass([1, 2, 3], 10)
34+
print(d.append(4))
35+
print(d.appendleft(0))
36+
print(d.pop())
37+
print(d.popleft())
38+
d.extend([6, 7])
39+
# calling list() tests iteration.
40+
print(list(d))

0 commit comments

Comments
 (0)