Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Lib/test/test_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,17 @@ def unused_code_at_end():
'RETURN_VALUE',
list(dis.get_instructions(unused_code_at_end))[-1].opname)

@support.cpython_only
def test_slice_folding(self):
def g():
"abcde"[2:4]
gc = g.__code__.co_consts

self.assertIn("cd", gc)
self.assertNotIn("abcde", gc)
self.assertNotIn(2, gc)
self.assertNotIn(4, gc)

def test_dont_merge_constants(self):
# Issue #25843: compile() must not merge constants which are equal
# but have a different type.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Support slices (e.g: ``"abcde"[2:4]``) in constant folding. Patch by
Batuhan Taskaya.
38 changes: 29 additions & 9 deletions Python/ast_opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,26 +305,46 @@ fold_tuple(expr_ty node, PyArena *arena, int optimize)
return make_const(node, newval, arena);
}

#define ENSURE_CONSTANT(NODE) \
if ((NODE) != NULL && (NODE)->kind != Constant_kind) \
return 1;

#define GET_CONSTANT(NODE) (((NODE) != NULL) ? (NODE)->v.Constant.value : NULL)

static int
fold_subscr(expr_ty node, PyArena *arena, int optimize)
{
PyObject *newval;
expr_ty arg, idx;
PyObject *newval, *key;
expr_ty arg;
slice_ty slice;

arg = node->v.Subscript.value;
slice = node->v.Subscript.slice;
if (node->v.Subscript.ctx != Load ||
arg->kind != Constant_kind ||
/* TODO: handle other types of slices */
slice->kind != Index_kind ||
slice->v.Index.value->kind != Constant_kind)
if (node->v.Subscript.ctx != Load)
{
return 1;
}
ENSURE_CONSTANT(arg);
switch (slice->kind) {
case Index_kind:
ENSURE_CONSTANT(slice->v.Index.value);
key = GET_CONSTANT(slice->v.Index.value);
newval = PyObject_GetItem(GET_CONSTANT(arg), key);
break;
case Slice_kind:
ENSURE_CONSTANT(slice->v.Slice.lower);
ENSURE_CONSTANT(slice->v.Slice.upper);
ENSURE_CONSTANT(slice->v.Slice.step);
key = PySlice_New(GET_CONSTANT(slice->v.Slice.lower),
Comment thread
isidentical marked this conversation as resolved.
GET_CONSTANT(slice->v.Slice.upper),
GET_CONSTANT(slice->v.Slice.step));
newval = PyObject_GetItem(GET_CONSTANT(arg), key);
Py_DECREF(key);
break;
default:
return 1;
}

idx = slice->v.Index.value;
newval = PyObject_GetItem(arg->v.Constant.value, idx->v.Constant.value);
return make_const(node, newval, arena);
}

Expand Down