Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eadee9a

Browse files
committed
Fix SF bug #1448804 and ad a test to ensure that all subscript operations continue to be handled correctly
1 parent bfa8bd7 commit eadee9a

2 files changed

Lines changed: 101 additions & 24 deletions

File tree

Lib/test/test_compile.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,78 @@ def f():
284284
f1, f2 = f()
285285
self.assertNotEqual(id(f1.func_code), id(f2.func_code))
286286

287+
def test_subscripts(self):
288+
# SF bug 1448804
289+
# Class to make testing subscript results easy
290+
class str_map(object):
291+
def __init__(self):
292+
self.data = {}
293+
def __getitem__(self, key):
294+
return self.data[str(key)]
295+
def __setitem__(self, key, value):
296+
self.data[str(key)] = value
297+
def __delitem__(self, key):
298+
del self.data[str(key)]
299+
def __contains__(self, key):
300+
return str(key) in self.data
301+
d = str_map()
302+
# Index
303+
d[1] = 1
304+
self.assertEqual(d[1], 1)
305+
d[1] += 1
306+
self.assertEqual(d[1], 2)
307+
del d[1]
308+
self.assertEqual(1 in d, False)
309+
# Tuple of indices
310+
d[1, 1] = 1
311+
self.assertEqual(d[1, 1], 1)
312+
d[1, 1] += 1
313+
self.assertEqual(d[1, 1], 2)
314+
del d[1, 1]
315+
self.assertEqual((1, 1) in d, False)
316+
# Simple slice
317+
d[1:2] = 1
318+
self.assertEqual(d[1:2], 1)
319+
d[1:2] += 1
320+
self.assertEqual(d[1:2], 2)
321+
del d[1:2]
322+
self.assertEqual(slice(1, 2) in d, False)
323+
# Tuple of simple slices
324+
d[1:2, 1:2] = 1
325+
self.assertEqual(d[1:2, 1:2], 1)
326+
d[1:2, 1:2] += 1
327+
self.assertEqual(d[1:2, 1:2], 2)
328+
del d[1:2, 1:2]
329+
self.assertEqual((slice(1, 2), slice(1, 2)) in d, False)
330+
# Extended slice
331+
d[1:2:3] = 1
332+
self.assertEqual(d[1:2:3], 1)
333+
d[1:2:3] += 1
334+
self.assertEqual(d[1:2:3], 2)
335+
del d[1:2:3]
336+
self.assertEqual(slice(1, 2, 3) in d, False)
337+
# Tuple of extended slices
338+
d[1:2:3, 1:2:3] = 1
339+
self.assertEqual(d[1:2:3, 1:2:3], 1)
340+
d[1:2:3, 1:2:3] += 1
341+
self.assertEqual(d[1:2:3, 1:2:3], 2)
342+
del d[1:2:3, 1:2:3]
343+
self.assertEqual((slice(1, 2, 3), slice(1, 2, 3)) in d, False)
344+
# Ellipsis
345+
d[...] = 1
346+
self.assertEqual(d[...], 1)
347+
d[...] += 1
348+
self.assertEqual(d[...], 2)
349+
del d[...]
350+
self.assertEqual(Ellipsis in d, False)
351+
# Tuple of Ellipses
352+
d[..., ...] = 1
353+
self.assertEqual(d[..., ...], 1)
354+
d[..., ...] += 1
355+
self.assertEqual(d[..., ...], 2)
356+
del d[..., ...]
357+
self.assertEqual((Ellipsis, Ellipsis) in d, False)
358+
287359
def test_main():
288360
test_support.run_unittest(TestSpecifics)
289361

Python/compile.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3853,42 +3853,47 @@ compiler_visit_nested_slice(struct compiler *c, slice_ty s,
38533853
static int
38543854
compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
38553855
{
3856+
char * kindname = NULL;
38563857
switch (s->kind) {
3858+
case Index_kind:
3859+
kindname = "index";
3860+
if (ctx != AugStore) {
3861+
VISIT(c, expr, s->v.Index.value);
3862+
}
3863+
break;
38573864
case Ellipsis_kind:
3858-
ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);
3865+
kindname = "ellipsis";
3866+
if (ctx != AugStore) {
3867+
ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);
3868+
}
38593869
break;
38603870
case Slice_kind:
3871+
kindname = "slice";
38613872
if (!s->v.Slice.step)
38623873
return compiler_simple_slice(c, s, ctx);
3863-
if (!compiler_slice(c, s, ctx))
3864-
return 0;
3865-
if (ctx == AugLoad) {
3866-
ADDOP_I(c, DUP_TOPX, 2);
3867-
}
3868-
else if (ctx == AugStore) {
3869-
ADDOP(c, ROT_THREE);
3870-
}
3871-
return compiler_handle_subscr(c, "slice", ctx);
3872-
case ExtSlice_kind: {
3873-
int i, n = asdl_seq_LEN(s->v.ExtSlice.dims);
3874-
for (i = 0; i < n; i++) {
3875-
slice_ty sub = asdl_seq_GET(s->v.ExtSlice.dims, i);
3876-
if (!compiler_visit_nested_slice(c, sub, ctx))
3874+
if (ctx != AugStore) {
3875+
if (!compiler_slice(c, s, ctx))
38773876
return 0;
38783877
}
3879-
ADDOP_I(c, BUILD_TUPLE, n);
3880-
return compiler_handle_subscr(c, "extended slice", ctx);
3881-
}
3882-
case Index_kind:
3883-
if (ctx != AugStore)
3884-
VISIT(c, expr, s->v.Index.value);
3885-
return compiler_handle_subscr(c, "index", ctx);
3878+
break;
3879+
case ExtSlice_kind:
3880+
kindname = "extended slice";
3881+
if (ctx != AugStore) {
3882+
int i, n = asdl_seq_LEN(s->v.ExtSlice.dims);
3883+
for (i = 0; i < n; i++) {
3884+
slice_ty sub = asdl_seq_GET(s->v.ExtSlice.dims, i);
3885+
if (!compiler_visit_nested_slice(c, sub, ctx))
3886+
return 0;
3887+
}
3888+
ADDOP_I(c, BUILD_TUPLE, n);
3889+
}
3890+
break;
38863891
default:
38873892
PyErr_Format(PyExc_SystemError,
3888-
"invalid slice %d", s->kind);
3893+
"invalid subscript kind %d", s->kind);
38893894
return 0;
38903895
}
3891-
return 1;
3896+
return compiler_handle_subscr(c, kindname, ctx);
38923897
}
38933898

38943899
/* do depth-first search of basic block graph, starting with block.

0 commit comments

Comments
 (0)