@@ -176,6 +176,56 @@ def test_string_continuation(self, symbol, prefix):
176176 with self .assertRaises (_IncompleteInputError ):
177177 Compile ()(source , '<input>' , symbol )
178178
179+ @subTests ('symbol' , ('single' , 'exec' , 'eval' ))
180+ @subTests ('prefix' , ('f' , 't' ))
181+ @subTests ('quote' , ('"' , '"""' ))
182+ def test_invalid_escape_in_incomplete_string (self , symbol , prefix , quote ):
183+ for escape in (r'\xZZ' , r'\uZZZZ' , r'\U00110000' , r'\x' , r'\u12' ):
184+ for body in (escape , escape + '{0}' , '{0}' + escape ,
185+ '{0:' + escape ):
186+ source = prefix + quote + body + '\\ '
187+ for compiler in COMPILERS :
188+ with self .subTest (source = source , compiler = compiler ):
189+ with self .assertRaises (SyntaxError ) as cm :
190+ compiler (source , '<input>' , symbol )
191+ self .assertNotIsInstance (cm .exception , _IncompleteInputError )
192+
193+ @subTests ('symbol' , ('single' , 'exec' , 'eval' ))
194+ @subTests ('prefix' , ('f' , 't' ))
195+ @subTests ('quote' , ('"' , '"""' ))
196+ def test_valid_escape_in_incomplete_string (self , symbol , prefix , quote ):
197+ for escape in (r'\x41' , r'\u00e9' , r'\U0001f600' , r'\\xZZ' ):
198+ source = prefix + quote + escape + '\\ '
199+ with self .subTest (escape = escape ):
200+ self .assertIsNone (compile_command (source , symbol = symbol ))
201+ with self .assertRaises (_IncompleteInputError ):
202+ Compile ()(source , '<input>' , symbol )
203+ for compiler in COMPILERS :
204+ self .assertValid (source + '\n ' + quote , symbol ,
205+ compiler = compiler )
206+
207+ source = 'r' + prefix + quote + r'\xZZ' + '\\ '
208+ self .assertIsNone (compile_command (source , symbol = symbol ))
209+ with self .assertRaises (_IncompleteInputError ):
210+ Compile ()(source , '<input>' , symbol )
211+ for compiler in COMPILERS :
212+ self .assertValid (source + '\n ' + quote , symbol , compiler = compiler )
213+
214+ @subTests ('symbol' , ('single' , 'exec' , 'eval' ))
215+ @subTests ('prefix' , ('f' , 't' ))
216+ def test_unfinished_escape_in_incomplete_string (self , symbol , prefix ):
217+ for escape , suffix in ((r'\x' , '41' ), (r'\u12' , '34' ),
218+ (r'\U0001' , 'f600' ),
219+ (r'\N{LATIN' , ' SMALL LETTER A}' )):
220+ source = prefix + '"""' + escape
221+ with self .subTest (escape = escape ):
222+ self .assertIsNone (compile_command (source , symbol = symbol ))
223+ with self .assertRaises (_IncompleteInputError ):
224+ Compile ()(source , '<input>' , symbol )
225+ for compiler in COMPILERS :
226+ self .assertValid (source + suffix + '"""' , symbol ,
227+ compiler = compiler )
228+
179229 @subTests ('symbol' , ('single' , 'exec' , 'eval' ))
180230 @subTests ('newline' , ('\n ' , '\r ' , '\r \n ' ))
181231 def test_continued_final_line (self , symbol , newline ):
0 commit comments