File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -195,6 +195,24 @@ def test_folding_of_binops_on_constants(self):
195195 asm = dis_single ('a="x"*1000' )
196196 self .assertIn ('(1000)' , asm )
197197
198+ def test_binary_subscr_on_unicode (self ):
199+ # valid code get optimized
200+ asm = dis_single ('"foo"[0]' )
201+ self .assertIn ("('f')" , asm )
202+ self .assertNotIn ('BINARY_SUBSCR' , asm )
203+ asm = dis_single ('"\u0061 \uffff "[1]' )
204+ self .assertIn ("('\\ uffff')" , asm )
205+ self .assertNotIn ('BINARY_SUBSCR' , asm )
206+
207+ # invalid code doesn't get optimized
208+ # out of range
209+ asm = dis_single ('"fuu"[10]' )
210+ self .assertIn ('BINARY_SUBSCR' , asm )
211+ # non-BMP char (see #5057)
212+ asm = dis_single ('"\U00012345 "[0]' )
213+ self .assertIn ('BINARY_SUBSCR' , asm )
214+
215+
198216 def test_folding_of_unaryops_on_constants (self ):
199217 for line , elem in (
200218 ('-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.2.1?
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 #11845: Fix typo in rangeobject.c that caused a crash in
1418 compute_slice_indices. Patch by Daniel Urban.
1519
@@ -56,7 +60,7 @@ Core and Builtins
5660Library
5761-------
5862
59- - Issue #11467: Fix urlparse behavior when handling urls which contains scheme
63+ - Issue #11467: Fix urlparse behavior when handling urls which contains scheme
6064 specific part only digits. Patch by Santoso Wijaya.
6165
6266- Issue #11474: Fix the bug with url2pathname() handling of '/C|/' on Windows.
Original file line number Diff line number Diff line change @@ -133,6 +133,24 @@ fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
133133 break ;
134134 case BINARY_SUBSCR :
135135 newconst = PyObject_GetItem (v , w );
136+ /* #5057: if v is unicode, there might be differences between
137+ wide and narrow builds in cases like '\U00012345'[0].
138+ Wide builds will return a non-BMP char, whereas narrow builds
139+ will return a surrogate. In both the cases skip the
140+ optimization in order to produce compatible pycs.
141+ */
142+ if (newconst != NULL &&
143+ PyUnicode_Check (v ) && PyUnicode_Check (newconst )) {
144+ Py_UNICODE ch = PyUnicode_AS_UNICODE (newconst )[0 ];
145+ #ifdef Py_UNICODE_WIDE
146+ if (ch > 0xFFFF ) {
147+ #else
148+ if (ch >= 0xD800 && ch <= 0xDFFF ) {
149+ #endif
150+ Py_DECREF (newconst );
151+ return 0 ;
152+ }
153+ }
136154 break ;
137155 case BINARY_LSHIFT :
138156 newconst = PyNumber_Lshift (v , w );
You can’t perform that action at this time.
0 commit comments