Skip to content

Commit 80b648c

Browse files
committed
deque working
Signed-off-by: Matthew A Johnson <matjoh@microsoft.com>
1 parent d52b222 commit 80b648c

3 files changed

Lines changed: 75 additions & 8 deletions

File tree

Lib/test/test_freeze.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ def test_remove(self):
9595
with self.assertRaises(NotWriteableError):
9696
self.obj.remove(1)
9797

98+
def test_delete(self):
99+
with self.assertRaises(NotWriteableError):
100+
del self.obj[0]
101+
98102
def test_reverse(self):
99103
with self.assertRaises(NotWriteableError):
100104
self.obj.reverse()
@@ -128,10 +132,6 @@ def test_set_item(self):
128132
with self.assertRaises(NotWriteableError):
129133
self.obj[0] = None
130134

131-
def test_set_slice(self):
132-
with self.assertRaises(NotWriteableError):
133-
self.obj[1:3] = [None, None]
134-
135135
def test_append(self):
136136
with self.assertRaises(NotWriteableError):
137137
self.obj.append(TestList.C())
@@ -164,6 +164,10 @@ def test_remove(self):
164164
with self.assertRaises(NotWriteableError):
165165
self.obj.remove(1)
166166

167+
def test_delete(self):
168+
with self.assertRaises(NotWriteableError):
169+
del self.obj[0]
170+
167171
def test_inplace_repeat(self):
168172
with self.assertRaises(NotWriteableError):
169173
self.obj *= 2
@@ -176,13 +180,13 @@ def test_reverse(self):
176180
with self.assertRaises(NotWriteableError):
177181
self.obj.reverse()
178182

179-
def test_clear(self):
183+
def test_rotate(self):
180184
with self.assertRaises(NotWriteableError):
181-
self.obj.clear()
185+
self.obj.rotate(1)
182186

183-
def test_sort(self):
187+
def test_clear(self):
184188
with self.assertRaises(NotWriteableError):
185-
self.obj.sort()
189+
self.obj.clear()
186190

187191

188192
class TestDict(BaseObjectTest):

Modules/_collectionsmodule.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "pycore_long.h" // _PyLong_GetZero()
44
#include "pycore_moduleobject.h" // _PyModule_GetState()
55
#include "pycore_typeobject.h" // _PyType_GetModuleState()
6+
#include "pycore_object.h" // Py_CHECKWRITE
67
#include "structmember.h" // PyMemberDef
78
#include <stddef.h>
89

@@ -224,6 +225,10 @@ deque_pop(dequeobject *deque, PyObject *unused)
224225
PyObject *item;
225226
block *prevblock;
226227

228+
if(!Py_CHECKWRITE(deque)){
229+
return PyErr_WriteToImmutable(deque);
230+
}
231+
227232
if (Py_SIZE(deque) == 0) {
228233
PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
229234
return NULL;
@@ -261,6 +266,10 @@ deque_popleft(dequeobject *deque, PyObject *unused)
261266
PyObject *item;
262267
block *prevblock;
263268

269+
if(!Py_CHECKWRITE(deque)){
270+
return PyErr_WriteToImmutable(deque);
271+
}
272+
264273
if (Py_SIZE(deque) == 0) {
265274
PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
266275
return NULL;
@@ -336,6 +345,10 @@ deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
336345
static PyObject *
337346
deque_append(dequeobject *deque, PyObject *item)
338347
{
348+
if(!Py_CHECKWRITE(deque)){
349+
return PyErr_WriteToImmutable(deque);
350+
}
351+
339352
if (deque_append_internal(deque, Py_NewRef(item), deque->maxlen) < 0)
340353
return NULL;
341354
Py_RETURN_NONE;
@@ -372,6 +385,10 @@ deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
372385
static PyObject *
373386
deque_appendleft(dequeobject *deque, PyObject *item)
374387
{
388+
if(!Py_CHECKWRITE(deque)){
389+
return PyErr_WriteToImmutable(deque);
390+
}
391+
375392
if (deque_appendleft_internal(deque, Py_NewRef(item), deque->maxlen) < 0)
376393
return NULL;
377394
Py_RETURN_NONE;
@@ -416,6 +433,10 @@ deque_extend(dequeobject *deque, PyObject *iterable)
416433
PyObject *(*iternext)(PyObject *);
417434
Py_ssize_t maxlen = deque->maxlen;
418435

436+
if(!Py_CHECKWRITE(deque)){
437+
return PyErr_WriteToImmutable(deque);
438+
}
439+
419440
/* Handle case where id(deque) == id(iterable) */
420441
if ((PyObject *)deque == iterable) {
421442
PyObject *result;
@@ -463,6 +484,10 @@ deque_extendleft(dequeobject *deque, PyObject *iterable)
463484
PyObject *(*iternext)(PyObject *);
464485
Py_ssize_t maxlen = deque->maxlen;
465486

487+
if(!Py_CHECKWRITE(deque)){
488+
return PyErr_WriteToImmutable(deque);
489+
}
490+
466491
/* Handle case where id(deque) == id(iterable) */
467492
if ((PyObject *)deque == iterable) {
468493
PyObject *result;
@@ -508,6 +533,10 @@ deque_inplace_concat(dequeobject *deque, PyObject *other)
508533
{
509534
PyObject *result;
510535

536+
if(!Py_CHECKWRITE(deque)){
537+
return PyErr_WriteToImmutable(deque);
538+
}
539+
511540
result = deque_extend(deque, other);
512541
if (result == NULL)
513542
return result;
@@ -678,6 +707,10 @@ deque_clear(dequeobject *deque)
678707
static PyObject *
679708
deque_clearmethod(dequeobject *deque, PyObject *Py_UNUSED(ignored))
680709
{
710+
if(!Py_CHECKWRITE(deque)){
711+
return PyErr_WriteToImmutable(deque);
712+
}
713+
681714
deque_clear(deque);
682715
Py_RETURN_NONE;
683716
}
@@ -691,6 +724,10 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n)
691724
PyObject *seq;
692725
PyObject *rv;
693726

727+
if(!Py_CHECKWRITE(deque)){
728+
return PyErr_WriteToImmutable(deque);
729+
}
730+
694731
size = Py_SIZE(deque);
695732
if (size == 0 || n == 1) {
696733
return Py_NewRef(deque);
@@ -929,6 +966,10 @@ deque_rotate(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
929966
{
930967
Py_ssize_t n=1;
931968

969+
if(!Py_CHECKWRITE(deque)){
970+
return PyErr_WriteToImmutable(deque);
971+
}
972+
932973
if (!_PyArg_CheckPositional("deque.rotate", nargs, 0, 1)) {
933974
return NULL;
934975
}
@@ -962,6 +1003,10 @@ deque_reverse(dequeobject *deque, PyObject *unused)
9621003
Py_ssize_t n = Py_SIZE(deque) >> 1;
9631004
PyObject *tmp;
9641005

1006+
if(!Py_CHECKWRITE(deque)){
1007+
return PyErr_WriteToImmutable(deque);
1008+
}
1009+
9651010
while (--n >= 0) {
9661011
/* Validate that pointers haven't met in the middle */
9671012
assert(leftblock != rightblock || leftindex < rightindex);
@@ -1157,6 +1202,10 @@ deque_insert(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
11571202
PyObject *value;
11581203
PyObject *rv;
11591204

1205+
if(!Py_CHECKWRITE(deque)){
1206+
return PyErr_WriteToImmutable(deque);
1207+
}
1208+
11601209
if (!_PyArg_ParseStack(args, nargs, "nO:insert", &index, &value)) {
11611210
return NULL;
11621211
}
@@ -1261,6 +1310,10 @@ deque_remove(dequeobject *deque, PyObject *value)
12611310
size_t start_state = deque->state;
12621311
int cmp, rv;
12631312

1313+
if(!Py_CHECKWRITE(deque)){
1314+
return PyErr_WriteToImmutable(deque);
1315+
}
1316+
12641317
for (i = 0 ; i < n; i++) {
12651318
item = Py_NewRef(b->data[index]);
12661319
cmp = PyObject_RichCompareBool(item, value, Py_EQ);
@@ -1299,6 +1352,11 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
12991352
block *b;
13001353
Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i;
13011354

1355+
if(!Py_CHECKWRITE(deque)){
1356+
PyErr_WriteToImmutable(deque);
1357+
return -1;
1358+
}
1359+
13021360
if (!valid_index(i, len)) {
13031361
PyErr_SetString(PyExc_IndexError, "deque index out of range");
13041362
return -1;

Objects/typeobject.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5251,9 +5251,14 @@ type_traverse(PyTypeObject *type, visitproc visit, void *arg)
52515251
Py_VISIT(type->tp_mro);
52525252
Py_VISIT(type->tp_bases);
52535253
Py_VISIT(type->tp_base);
5254+
5255+
/*
5256+
TODO Do we need to visit the module? This can potentially freeze the entire
5257+
standard library. What do we gain?
52545258
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
52555259
Py_VISIT(((PyHeapTypeObject *)type)->ht_module);
52565260
}
5261+
*/
52575262

52585263
/* There's no need to visit others because they can't be involved
52595264
in cycles:

0 commit comments

Comments
 (0)