@@ -111,26 +111,92 @@ def test_eval_str_invalid_escape(self):
111
111
for b in range (1 , 128 ):
112
112
if b in b"""\n \r "'01234567NU\\ abfnrtuvx""" :
113
113
continue
114
- with self .assertWarns (DeprecationWarning ):
114
+ with self .assertWarns (SyntaxWarning ):
115
115
self .assertEqual (eval (r"'\%c'" % b ), '\\ ' + chr (b ))
116
116
117
117
with warnings .catch_warnings (record = True ) as w :
118
- warnings .simplefilter ('always' , category = DeprecationWarning )
118
+ warnings .simplefilter ('always' , category = SyntaxWarning )
119
119
eval ("'''\n \\ z'''" )
120
120
self .assertEqual (len (w ), 1 )
121
+ self .assertEqual (str (w [0 ].message ), r"invalid escape sequence '\z'" )
121
122
self .assertEqual (w [0 ].filename , '<string>' )
122
- self .assertEqual (w [0 ].lineno , 1 )
123
+ self .assertEqual (w [0 ].lineno , 2 )
123
124
124
125
with warnings .catch_warnings (record = True ) as w :
125
- warnings .simplefilter ('error' , category = DeprecationWarning )
126
+ warnings .simplefilter ('error' , category = SyntaxWarning )
126
127
with self .assertRaises (SyntaxError ) as cm :
127
128
eval ("'''\n \\ z'''" )
128
129
exc = cm .exception
129
130
self .assertEqual (w , [])
131
+ self .assertEqual (exc .msg , r"invalid escape sequence '\z'" )
130
132
self .assertEqual (exc .filename , '<string>' )
131
- self .assertEqual (exc .lineno , 1 )
133
+ self .assertEqual (exc .lineno , 2 )
132
134
self .assertEqual (exc .offset , 1 )
133
135
136
+ # Check that the warning is raised only once if there are syntax errors
137
+
138
+ with warnings .catch_warnings (record = True ) as w :
139
+ warnings .simplefilter ('always' , category = SyntaxWarning )
140
+ with self .assertRaises (SyntaxError ) as cm :
141
+ eval ("'\\ e' $" )
142
+ exc = cm .exception
143
+ self .assertEqual (len (w ), 1 )
144
+ self .assertEqual (w [0 ].category , SyntaxWarning )
145
+ self .assertRegex (str (w [0 ].message ), 'invalid escape sequence' )
146
+ self .assertEqual (w [0 ].filename , '<string>' )
147
+
148
+ # TODO: RUSTPYTHON
149
+ @unittest .expectedFailure
150
+ def test_eval_str_invalid_octal_escape (self ):
151
+ for i in range (0o400 , 0o1000 ):
152
+ with self .assertWarns (SyntaxWarning ):
153
+ self .assertEqual (eval (r"'\%o'" % i ), chr (i ))
154
+
155
+ with warnings .catch_warnings (record = True ) as w :
156
+ warnings .simplefilter ('always' , category = SyntaxWarning )
157
+ eval ("'''\n \\ 407'''" )
158
+ self .assertEqual (len (w ), 1 )
159
+ self .assertEqual (str (w [0 ].message ),
160
+ r"invalid octal escape sequence '\407'" )
161
+ self .assertEqual (w [0 ].filename , '<string>' )
162
+ self .assertEqual (w [0 ].lineno , 2 )
163
+
164
+ with warnings .catch_warnings (record = True ) as w :
165
+ warnings .simplefilter ('error' , category = SyntaxWarning )
166
+ with self .assertRaises (SyntaxError ) as cm :
167
+ eval ("'''\n \\ 407'''" )
168
+ exc = cm .exception
169
+ self .assertEqual (w , [])
170
+ self .assertEqual (exc .msg , r"invalid octal escape sequence '\407'" )
171
+ self .assertEqual (exc .filename , '<string>' )
172
+ self .assertEqual (exc .lineno , 2 )
173
+ self .assertEqual (exc .offset , 1 )
174
+
175
+ # TODO: RUSTPYTHON
176
+ @unittest .expectedFailure
177
+ def test_invalid_escape_locations_with_offset (self ):
178
+ with warnings .catch_warnings (record = True ) as w :
179
+ warnings .simplefilter ('error' , category = SyntaxWarning )
180
+ with self .assertRaises (SyntaxError ) as cm :
181
+ eval ("\" '''''''''''''''''''''invalid\\ Escape\" " )
182
+ exc = cm .exception
183
+ self .assertEqual (w , [])
184
+ self .assertEqual (exc .msg , r"invalid escape sequence '\ '" )
185
+ self .assertEqual (exc .filename , '<string>' )
186
+ self .assertEqual (exc .lineno , 1 )
187
+ self .assertEqual (exc .offset , 30 )
188
+
189
+ with warnings .catch_warnings (record = True ) as w :
190
+ warnings .simplefilter ('error' , category = SyntaxWarning )
191
+ with self .assertRaises (SyntaxError ) as cm :
192
+ eval ("\" ''Incorrect \\ logic?\" " )
193
+ exc = cm .exception
194
+ self .assertEqual (w , [])
195
+ self .assertEqual (exc .msg , r"invalid escape sequence '\ '" )
196
+ self .assertEqual (exc .filename , '<string>' )
197
+ self .assertEqual (exc .lineno , 1 )
198
+ self .assertEqual (exc .offset , 14 )
199
+
134
200
def test_eval_str_raw (self ):
135
201
self .assertEqual (eval (""" r'x' """ ), 'x' )
136
202
self .assertEqual (eval (r""" r'\x01' """ ), '\\ ' + 'x01' )
@@ -163,24 +229,52 @@ def test_eval_bytes_invalid_escape(self):
163
229
for b in range (1 , 128 ):
164
230
if b in b"""\n \r "'01234567\\ abfnrtvx""" :
165
231
continue
166
- with self .assertWarns (DeprecationWarning ):
232
+ with self .assertWarns (SyntaxWarning ):
167
233
self .assertEqual (eval (r"b'\%c'" % b ), b'\\ ' + bytes ([b ]))
168
234
169
235
with warnings .catch_warnings (record = True ) as w :
170
- warnings .simplefilter ('always' , category = DeprecationWarning )
236
+ warnings .simplefilter ('always' , category = SyntaxWarning )
171
237
eval ("b'''\n \\ z'''" )
172
238
self .assertEqual (len (w ), 1 )
239
+ self .assertEqual (str (w [0 ].message ), r"invalid escape sequence '\z'" )
173
240
self .assertEqual (w [0 ].filename , '<string>' )
174
- self .assertEqual (w [0 ].lineno , 1 )
241
+ self .assertEqual (w [0 ].lineno , 2 )
175
242
176
243
with warnings .catch_warnings (record = True ) as w :
177
- warnings .simplefilter ('error' , category = DeprecationWarning )
244
+ warnings .simplefilter ('error' , category = SyntaxWarning )
178
245
with self .assertRaises (SyntaxError ) as cm :
179
246
eval ("b'''\n \\ z'''" )
180
247
exc = cm .exception
181
248
self .assertEqual (w , [])
249
+ self .assertEqual (exc .msg , r"invalid escape sequence '\z'" )
182
250
self .assertEqual (exc .filename , '<string>' )
183
- self .assertEqual (exc .lineno , 1 )
251
+ self .assertEqual (exc .lineno , 2 )
252
+
253
+ # TODO: RUSTPYTHON
254
+ @unittest .expectedFailure
255
+ def test_eval_bytes_invalid_octal_escape (self ):
256
+ for i in range (0o400 , 0o1000 ):
257
+ with self .assertWarns (SyntaxWarning ):
258
+ self .assertEqual (eval (r"b'\%o'" % i ), bytes ([i & 0o377 ]))
259
+
260
+ with warnings .catch_warnings (record = True ) as w :
261
+ warnings .simplefilter ('always' , category = SyntaxWarning )
262
+ eval ("b'''\n \\ 407'''" )
263
+ self .assertEqual (len (w ), 1 )
264
+ self .assertEqual (str (w [0 ].message ),
265
+ r"invalid octal escape sequence '\407'" )
266
+ self .assertEqual (w [0 ].filename , '<string>' )
267
+ self .assertEqual (w [0 ].lineno , 2 )
268
+
269
+ with warnings .catch_warnings (record = True ) as w :
270
+ warnings .simplefilter ('error' , category = SyntaxWarning )
271
+ with self .assertRaises (SyntaxError ) as cm :
272
+ eval ("b'''\n \\ 407'''" )
273
+ exc = cm .exception
274
+ self .assertEqual (w , [])
275
+ self .assertEqual (exc .msg , r"invalid octal escape sequence '\407'" )
276
+ self .assertEqual (exc .filename , '<string>' )
277
+ self .assertEqual (exc .lineno , 2 )
184
278
185
279
def test_eval_bytes_raw (self ):
186
280
self .assertEqual (eval (""" br'x' """ ), b'x' )
@@ -217,6 +311,13 @@ def test_eval_str_u(self):
217
311
self .assertRaises (SyntaxError , eval , """ bu'' """ )
218
312
self .assertRaises (SyntaxError , eval , """ ub'' """ )
219
313
314
+ def test_uppercase_prefixes (self ):
315
+ self .assertEqual (eval (""" B'x' """ ), b'x' )
316
+ self .assertEqual (eval (r""" R'\x01' """ ), r'\x01' )
317
+ self .assertEqual (eval (r""" BR'\x01' """ ), br'\x01' )
318
+ self .assertEqual (eval (""" F'{1+1}' """ ), f'{ 1 + 1 } ' )
319
+ self .assertEqual (eval (r""" U'\U0001d120' """ ), u'\U0001d120 ' )
320
+
220
321
def check_encoding (self , encoding , extra = "" ):
221
322
modname = "xx_" + encoding .replace ("-" , "_" )
222
323
fn = os .path .join (self .tmpdir , modname + ".py" )
0 commit comments