File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -146,6 +146,24 @@ def test_folding_of_binops_on_constants(self):
146146 asm = dis_single ('a="x"*1000' )
147147 self .assertTrue ('(1000)' in asm )
148148
149+ def test_binary_subscr_on_unicode (self ):
150+ # valid code get optimized
151+ asm = dis_single ('"foo"[0]' )
152+ self .assertIn ("('f')" , asm )
153+ self .assertNotIn ('BINARY_SUBSCR' , asm )
154+ asm = dis_single ('"\u0061 \uffff "[1]' )
155+ self .assertIn ("('\\ uffff')" , asm )
156+ self .assertNotIn ('BINARY_SUBSCR' , asm )
157+
158+ # invalid code doesn't get optimized
159+ # out of range
160+ asm = dis_single ('"fuu"[10]' )
161+ self .assertIn ('BINARY_SUBSCR' , asm )
162+ # non-BMP char (see #5057)
163+ asm = dis_single ('"\U00012345 "[0]' )
164+ self .assertIn ('BINARY_SUBSCR' , asm )
165+
166+
149167 def test_folding_of_unaryops_on_constants (self ):
150168 for line , elem in (
151169 ('-0.5' , '(-0.5)' ), # unary negative
Original file line number Diff line number Diff line change @@ -10,6 +10,10 @@ What's New in Python 3.1.4?
1010Core and Builtins
1111-----------------
1212
13+ - Issue #5057: fix a bug in the peepholer that led to non-portable pyc files
14+ between narrow and wide builds while optimizing BINARY_SUBSCR on non-BMP
15+ chars (e.g. "\U00012345"[0]).
16+
1317- Issue #11650: PyOS_StdioReadline() retries fgets() if it was interrupted
1418 (EINTR), for example if the program is stopped with CTRL+z on Mac OS X. Patch
1519 written by Charles-Francois Natali.
@@ -51,7 +55,7 @@ Core and Builtins
5155Library
5256-------
5357
54- - Issue #11467: Fix urlparse behavior when handling urls which contains scheme
58+ - Issue #11467: Fix urlparse behavior when handling urls which contains scheme
5559 specific part only digits. Patch by Santoso Wijaya.
5660
5761- Issue #11474: Fix the bug with url2pathname() handling of '/C|/' on Windows.
Original file line number Diff line number Diff line change @@ -124,6 +124,24 @@ fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
124124 break ;
125125 case BINARY_SUBSCR :
126126 newconst = PyObject_GetItem (v , w );
127+ /* #5057: if v is unicode, there might be differences between
128+ wide and narrow builds in cases like '\U00012345'[0].
129+ Wide builds will return a non-BMP char, whereas narrow builds
130+ will return a surrogate. In both the cases skip the
131+ optimization in order to produce compatible pycs.
132+ */
133+ if (newconst != NULL &&
134+ PyUnicode_Check (v ) && PyUnicode_Check (newconst )) {
135+ Py_UNICODE ch = PyUnicode_AS_UNICODE (newconst )[0 ];
136+ #ifdef Py_UNICODE_WIDE
137+ if (ch > 0xFFFF ) {
138+ #else
139+ if (ch >= 0xD800 && ch <= 0xDFFF ) {
140+ #endif
141+ Py_DECREF (newconst );
142+ return 0 ;
143+ }
144+ }
127145 break ;
128146 case BINARY_LSHIFT :
129147 newconst = PyNumber_Lshift (v , w );
You can’t perform that action at this time.
0 commit comments