@@ -243,6 +243,33 @@ impl CpythonDiagnostic {
243243 }
244244}
245245
246+ /// Parser-driven tokenization reports the first failure. A later prefix
247+ /// scan must not override an earlier number or bracket diagnostic.
248+ struct RankedOverride {
249+ diagnostic : CpythonDiagnostic ,
250+ unclosed_bracket : bool ,
251+ }
252+
253+ fn consider_override ( best : & mut Option < RankedOverride > , diagnostic : CpythonDiagnostic ) {
254+ consider_override_bracket ( best, diagnostic, false ) ;
255+ }
256+
257+ fn consider_override_bracket (
258+ best : & mut Option < RankedOverride > ,
259+ diagnostic : CpythonDiagnostic ,
260+ unclosed_bracket : bool ,
261+ ) {
262+ if best
263+ . as_ref ( )
264+ . is_none_or ( |current| diagnostic. range . start ( ) < current. diagnostic . range . start ( ) )
265+ {
266+ * best = Some ( RankedOverride {
267+ diagnostic,
268+ unclosed_bracket,
269+ } ) ;
270+ }
271+ }
272+
246273fn cpython_parse_diagnostic_override (
247274 error : & parser:: ParseError ,
248275 source_file : & SourceFile ,
@@ -258,18 +285,35 @@ fn cpython_parse_diagnostic_override(
258285 } ;
259286 }
260287
261- source_error ! ( invalid_number_literal_error( source_text) ) ;
262- source_error ! ( invalid_legacy_statement_error( source_text) ) ;
263- source_error ! ( incompatible_string_prefix_error( source_text) ) ;
264- source_error ! ( malformed_unicode_n_escape_error( source_text) ) ;
265- source_error ! ( non_printable_character_error( source_text) ) ;
266- source_error ! ( invalid_interpolated_string_error( source_text) ) ;
267- source_error ! ( mixed_tstring_literal_error( error, source_text) ) ;
268-
288+ let mut earliest: Option < RankedOverride > = None ;
289+ if let Some ( diagnostic) = invalid_number_literal_error ( source_text) {
290+ consider_override ( & mut earliest, diagnostic) ;
291+ }
292+ if let Some ( diagnostic) = invalid_legacy_statement_error ( source_text) {
293+ consider_override ( & mut earliest, diagnostic) ;
294+ }
295+ if let Some ( diagnostic) = incompatible_string_prefix_error ( source_text) {
296+ consider_override ( & mut earliest, diagnostic) ;
297+ }
298+ if let Some ( diagnostic) = malformed_unicode_n_escape_error ( source_text) {
299+ consider_override ( & mut earliest, diagnostic) ;
300+ }
301+ if let Some ( diagnostic) = non_printable_character_error ( source_text) {
302+ consider_override ( & mut earliest, diagnostic) ;
303+ }
304+ if let Some ( diagnostic) = invalid_interpolated_string_error ( source_text) {
305+ consider_override ( & mut earliest, diagnostic) ;
306+ }
307+ if let Some ( diagnostic) = mixed_tstring_literal_error ( error, source_text) {
308+ consider_override ( & mut earliest, diagnostic) ;
309+ }
269310 if let Some ( bracket) = bracket_syntax_error ( source_text) {
311+ consider_override_bracket ( & mut earliest, bracket. diagnostic , bracket. unclosed ) ;
312+ }
313+ if let Some ( override_diag) = earliest {
270314 return Some (
271- NormalizedParseDiagnostic :: other ( source_file, bracket . diagnostic )
272- . with_unclosed_bracket ( bracket . unclosed ) ,
315+ NormalizedParseDiagnostic :: other ( source_file, override_diag . diagnostic )
316+ . with_unclosed_bracket ( override_diag . unclosed_bracket ) ,
273317 ) ;
274318 }
275319
@@ -7467,6 +7511,11 @@ mod tests {
74677511 ( "fu''" , "'u' and 'f' prefixes are incompatible" ) ,
74687512 ( "fb''" , "'b' and 'f' prefixes are incompatible" ) ,
74697513 ( "ufr''" , "'u' and 'r' prefixes are incompatible" ) ,
7514+ (
7515+ "(]\n bu'x'" ,
7516+ "closing parenthesis ']' does not match opening parenthesis '('" ,
7517+ ) ,
7518+ ( "0x\n bu'x'" , "invalid hexadecimal literal" ) ,
74707519 (
74717520 r"'\N'" ,
74727521 "(unicode error) 'unicodeescape' codec can't decode bytes in position 0-1: malformed \\ N character escape" ,
0 commit comments