Skip to content

Commit f7cddcc

Browse files
committed
Narrow the return type of _BINARY_OP_SUBSCR_STR_INT
1 parent 0a10b45 commit f7cddcc

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

Lib/test/test_capi/test_opt.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,6 +1646,27 @@ def f(n):
16461646
self.assertIn("_TO_BOOL_STR", uops)
16471647
self.assertNotIn("_GUARD_TOS_UNICODE", uops)
16481648

1649+
def test_binary_subcsr_str_int_narrows_to_str(self):
1650+
def testfunc(n):
1651+
x = 0
1652+
s = "foo"
1653+
z = ""
1654+
for _ in range(n):
1655+
y = s[0] # _BINARY_OP_SUBSCR_STR_INT
1656+
z = "bar" + y # (_GUARD_TOS_UNICODE) + _BINARY_OP_ADD_UNICODE
1657+
x += 1
1658+
return x
1659+
1660+
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
1661+
self.assertEqual(res, TIER2_THRESHOLD)
1662+
self.assertIsNotNone(ex)
1663+
uops = get_opnames(ex)
1664+
self.assertIn("_BINARY_OP_SUBSCR_STR_INT", uops)
1665+
# _BINARY_OP_SUBSCR_STR_INT narrows the result to 'str' so
1666+
# the unicode guard before _BINARY_OP_ADD_UNICODE is removed.
1667+
self.assertNotIn("_GUARD_TOS_UNICODE", uops)
1668+
self.assertIn("_BINARY_OP_ADD_UNICODE", uops)
1669+
16491670

16501671
def global_identity(x):
16511672
return x

Python/optimizer_bytecodes.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,10 @@ dummy_func(void) {
366366
ctx->done = true;
367367
}
368368

369+
op(_BINARY_OP_SUBSCR_STR_INT, (left, right -- res)) {
370+
res = sym_new_type(ctx, &PyUnicode_Type);
371+
}
372+
369373
op(_TO_BOOL, (value -- res)) {
370374
int already_bool = optimize_to_bool(this_instr, ctx, value, &res);
371375
if (!already_bool) {

Python/optimizer_cases.c.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)