@@ -111,26 +111,92 @@ def test_eval_str_invalid_escape(self):
111111 for b in range (1 , 128 ):
112112 if b in b"""\n \r "'01234567NU\\ abfnrtuvx""" :
113113 continue
114- with self .assertWarns (DeprecationWarning ):
114+ with self .assertWarns (SyntaxWarning ):
115115 self .assertEqual (eval (r"'\%c'" % b ), '\\ ' + chr (b ))
116116
117117 with warnings .catch_warnings (record = True ) as w :
118- warnings .simplefilter ('always' , category = DeprecationWarning )
118+ warnings .simplefilter ('always' , category = SyntaxWarning )
119119 eval ("'''\n \\ z'''" )
120120 self .assertEqual (len (w ), 1 )
121+ self .assertEqual (str (w [0 ].message ), r"invalid escape sequence '\z'" )
121122 self .assertEqual (w [0 ].filename , '<string>' )
122- self .assertEqual (w [0 ].lineno , 1 )
123+ self .assertEqual (w [0 ].lineno , 2 )
123124
124125 with warnings .catch_warnings (record = True ) as w :
125- warnings .simplefilter ('error' , category = DeprecationWarning )
126+ warnings .simplefilter ('error' , category = SyntaxWarning )
126127 with self .assertRaises (SyntaxError ) as cm :
127128 eval ("'''\n \\ z'''" )
128129 exc = cm .exception
129130 self .assertEqual (w , [])
131+ self .assertEqual (exc .msg , r"invalid escape sequence '\z'" )
130132 self .assertEqual (exc .filename , '<string>' )
131- self .assertEqual (exc .lineno , 1 )
133+ self .assertEqual (exc .lineno , 2 )
132134 self .assertEqual (exc .offset , 1 )
133135
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+
134200 def test_eval_str_raw (self ):
135201 self .assertEqual (eval (""" r'x' """ ), 'x' )
136202 self .assertEqual (eval (r""" r'\x01' """ ), '\\ ' + 'x01' )
@@ -163,24 +229,52 @@ def test_eval_bytes_invalid_escape(self):
163229 for b in range (1 , 128 ):
164230 if b in b"""\n \r "'01234567\\ abfnrtvx""" :
165231 continue
166- with self .assertWarns (DeprecationWarning ):
232+ with self .assertWarns (SyntaxWarning ):
167233 self .assertEqual (eval (r"b'\%c'" % b ), b'\\ ' + bytes ([b ]))
168234
169235 with warnings .catch_warnings (record = True ) as w :
170- warnings .simplefilter ('always' , category = DeprecationWarning )
236+ warnings .simplefilter ('always' , category = SyntaxWarning )
171237 eval ("b'''\n \\ z'''" )
172238 self .assertEqual (len (w ), 1 )
239+ self .assertEqual (str (w [0 ].message ), r"invalid escape sequence '\z'" )
173240 self .assertEqual (w [0 ].filename , '<string>' )
174- self .assertEqual (w [0 ].lineno , 1 )
241+ self .assertEqual (w [0 ].lineno , 2 )
175242
176243 with warnings .catch_warnings (record = True ) as w :
177- warnings .simplefilter ('error' , category = DeprecationWarning )
244+ warnings .simplefilter ('error' , category = SyntaxWarning )
178245 with self .assertRaises (SyntaxError ) as cm :
179246 eval ("b'''\n \\ z'''" )
180247 exc = cm .exception
181248 self .assertEqual (w , [])
249+ self .assertEqual (exc .msg , r"invalid escape sequence '\z'" )
182250 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 )
184278
185279 def test_eval_bytes_raw (self ):
186280 self .assertEqual (eval (""" br'x' """ ), b'x' )
@@ -217,6 +311,13 @@ def test_eval_str_u(self):
217311 self .assertRaises (SyntaxError , eval , """ bu'' """ )
218312 self .assertRaises (SyntaxError , eval , """ ub'' """ )
219313
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+
220321 def check_encoding (self , encoding , extra = "" ):
221322 modname = "xx_" + encoding .replace ("-" , "_" )
222323 fn = os .path .join (self .tmpdir , modname + ".py" )
0 commit comments