diff --git a/crates/ruff/tests/integration_test.rs b/crates/ruff/tests/integration_test.rs index d692e41f1b..d43ae77b60 100644 --- a/crates/ruff/tests/integration_test.rs +++ b/crates/ruff/tests/integration_test.rs @@ -798,7 +798,7 @@ fn stdin_parse_error() { success: false exit_code: 1 ----- stdout ----- - -:1:16: SyntaxError: Expected one or more symbol names after import + -:1:16: invalid-syntax: Expected one or more symbol names after import | 1 | from foo import | ^ @@ -818,14 +818,14 @@ fn stdin_multiple_parse_error() { success: false exit_code: 1 ----- stdout ----- - -:1:16: SyntaxError: Expected one or more symbol names after import + -:1:16: invalid-syntax: Expected one or more symbol names after import | 1 | from foo import | ^ 2 | bar = | - -:2:6: SyntaxError: Expected an expression + -:2:6: invalid-syntax: Expected an expression | 1 | from foo import 2 | bar = @@ -847,7 +847,7 @@ fn parse_error_not_included() { success: false exit_code: 1 ----- stdout ----- - -:1:6: SyntaxError: Expected an expression + -:1:6: invalid-syntax: Expected an expression | 1 | foo = | ^ diff --git a/crates/ruff/tests/lint.rs b/crates/ruff/tests/lint.rs index 40c1eb4ab7..ccb4ac0809 100644 --- a/crates/ruff/tests/lint.rs +++ b/crates/ruff/tests/lint.rs @@ -5389,7 +5389,7 @@ fn walrus_before_py38() { success: false exit_code: 1 ----- stdout ----- - test.py:1:2: SyntaxError: Cannot use named assignment expression (`:=`) on Python 3.7 (syntax was added in Python 3.8) + test.py:1:2: invalid-syntax: Cannot use named assignment expression (`:=`) on Python 3.7 (syntax was added in Python 3.8) Found 1 error. ----- stderr ----- @@ -5435,15 +5435,15 @@ match 2: print("it's one") "# ), - @r###" + @r" success: false exit_code: 1 ----- stdout ----- - test.py:2:1: SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) + test.py:2:1: invalid-syntax: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) Found 1 error. ----- stderr ----- - "### + " ); // syntax error on 3.9 with preview @@ -5464,7 +5464,7 @@ match 2: success: false exit_code: 1 ----- stdout ----- - test.py:2:1: SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) + test.py:2:1: invalid-syntax: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) Found 1 error. ----- stderr ----- @@ -5492,7 +5492,7 @@ fn cache_syntax_errors() -> Result<()> { success: false exit_code: 1 ----- stdout ----- - main.py:1:1: SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) + main.py:1:1: invalid-syntax: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) ----- stderr ----- " @@ -5505,7 +5505,7 @@ fn cache_syntax_errors() -> Result<()> { success: false exit_code: 1 ----- stdout ----- - main.py:1:1: SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) + main.py:1:1: invalid-syntax: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) ----- stderr ----- " @@ -5618,7 +5618,7 @@ fn semantic_syntax_errors() -> Result<()> { success: false exit_code: 1 ----- stdout ----- - main.py:1:3: SyntaxError: assignment expression cannot rebind comprehension variable + main.py:1:3: invalid-syntax: assignment expression cannot rebind comprehension variable main.py:1:20: F821 Undefined name `foo` ----- stderr ----- @@ -5632,7 +5632,7 @@ fn semantic_syntax_errors() -> Result<()> { success: false exit_code: 1 ----- stdout ----- - main.py:1:3: SyntaxError: assignment expression cannot rebind comprehension variable + main.py:1:3: invalid-syntax: assignment expression cannot rebind comprehension variable main.py:1:20: F821 Undefined name `foo` ----- stderr ----- @@ -5651,7 +5651,7 @@ fn semantic_syntax_errors() -> Result<()> { success: false exit_code: 1 ----- stdout ----- - -:1:3: SyntaxError: assignment expression cannot rebind comprehension variable + -:1:3: invalid-syntax: assignment expression cannot rebind comprehension variable Found 1 error. ----- stderr ----- diff --git a/crates/ruff/tests/snapshots/lint__output_format_azure.snap b/crates/ruff/tests/snapshots/lint__output_format_azure.snap index 36ba1f8790..933cc043b9 100644 --- a/crates/ruff/tests/snapshots/lint__output_format_azure.snap +++ b/crates/ruff/tests/snapshots/lint__output_format_azure.snap @@ -18,6 +18,6 @@ exit_code: 1 ----- stdout ----- ##vso[task.logissue type=error;sourcepath=[TMP]/input.py;linenumber=1;columnnumber=8;code=F401;]`os` imported but unused ##vso[task.logissue type=error;sourcepath=[TMP]/input.py;linenumber=2;columnnumber=5;code=F821;]Undefined name `y` -##vso[task.logissue type=error;sourcepath=[TMP]/input.py;linenumber=3;columnnumber=1;]SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) +##vso[task.logissue type=error;sourcepath=[TMP]/input.py;linenumber=3;columnnumber=1;code=invalid-syntax;]Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) ----- stderr ----- diff --git a/crates/ruff/tests/snapshots/lint__output_format_concise.snap b/crates/ruff/tests/snapshots/lint__output_format_concise.snap index 9b9e4fd0f3..56bb215b25 100644 --- a/crates/ruff/tests/snapshots/lint__output_format_concise.snap +++ b/crates/ruff/tests/snapshots/lint__output_format_concise.snap @@ -18,7 +18,7 @@ exit_code: 1 ----- stdout ----- input.py:1:8: F401 [*] `os` imported but unused input.py:2:5: F821 Undefined name `y` -input.py:3:1: SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) +input.py:3:1: invalid-syntax: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) Found 3 errors. [*] 1 fixable with the `--fix` option. diff --git a/crates/ruff/tests/snapshots/lint__output_format_full.snap b/crates/ruff/tests/snapshots/lint__output_format_full.snap index d9527c596f..81dd0f1263 100644 --- a/crates/ruff/tests/snapshots/lint__output_format_full.snap +++ b/crates/ruff/tests/snapshots/lint__output_format_full.snap @@ -34,7 +34,7 @@ input.py:2:5: F821 Undefined name `y` 4 | case _: ... | -input.py:3:1: SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) +input.py:3:1: invalid-syntax: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) | 1 | import os # F401 2 | x = y # F821 diff --git a/crates/ruff/tests/snapshots/lint__output_format_github.snap b/crates/ruff/tests/snapshots/lint__output_format_github.snap index 3f38f23652..0e7ff40baa 100644 --- a/crates/ruff/tests/snapshots/lint__output_format_github.snap +++ b/crates/ruff/tests/snapshots/lint__output_format_github.snap @@ -18,6 +18,6 @@ exit_code: 1 ----- stdout ----- ::error title=Ruff (F401),file=[TMP]/input.py,line=1,col=8,endLine=1,endColumn=10::input.py:1:8: F401 `os` imported but unused ::error title=Ruff (F821),file=[TMP]/input.py,line=2,col=5,endLine=2,endColumn=6::input.py:2:5: F821 Undefined name `y` -::error title=Ruff,file=[TMP]/input.py,line=3,col=1,endLine=3,endColumn=6::input.py:3:1: SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) +::error title=Ruff (invalid-syntax),file=[TMP]/input.py,line=3,col=1,endLine=3,endColumn=6::input.py:3:1: invalid-syntax: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) ----- stderr ----- diff --git a/crates/ruff/tests/snapshots/lint__output_format_grouped.snap b/crates/ruff/tests/snapshots/lint__output_format_grouped.snap index 378ffe9d37..acf3decff8 100644 --- a/crates/ruff/tests/snapshots/lint__output_format_grouped.snap +++ b/crates/ruff/tests/snapshots/lint__output_format_grouped.snap @@ -19,7 +19,7 @@ exit_code: 1 input.py: 1:8 F401 [*] `os` imported but unused 2:5 F821 Undefined name `y` - 3:1 SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) + 3:1 invalid-syntax: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) Found 3 errors. [*] 1 fixable with the `--fix` option. diff --git a/crates/ruff/tests/snapshots/lint__output_format_json-lines.snap b/crates/ruff/tests/snapshots/lint__output_format_json-lines.snap index efadfd1cbc..868c92c728 100644 --- a/crates/ruff/tests/snapshots/lint__output_format_json-lines.snap +++ b/crates/ruff/tests/snapshots/lint__output_format_json-lines.snap @@ -18,6 +18,6 @@ exit_code: 1 ----- stdout ----- {"cell":null,"code":"F401","end_location":{"column":10,"row":1},"filename":"[TMP]/input.py","fix":{"applicability":"safe","edits":[{"content":"","end_location":{"column":1,"row":2},"location":{"column":1,"row":1}}],"message":"Remove unused import: `os`"},"location":{"column":8,"row":1},"message":"`os` imported but unused","noqa_row":1,"url":"https://docs.astral.sh/ruff/rules/unused-import"} {"cell":null,"code":"F821","end_location":{"column":6,"row":2},"filename":"[TMP]/input.py","fix":null,"location":{"column":5,"row":2},"message":"Undefined name `y`","noqa_row":2,"url":"https://docs.astral.sh/ruff/rules/undefined-name"} -{"cell":null,"code":null,"end_location":{"column":6,"row":3},"filename":"[TMP]/input.py","fix":null,"location":{"column":1,"row":3},"message":"SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)","noqa_row":null,"url":null} +{"cell":null,"code":"invalid-syntax","end_location":{"column":6,"row":3},"filename":"[TMP]/input.py","fix":null,"location":{"column":1,"row":3},"message":"Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)","noqa_row":null,"url":null} ----- stderr ----- diff --git a/crates/ruff/tests/snapshots/lint__output_format_json.snap b/crates/ruff/tests/snapshots/lint__output_format_json.snap index ca01d68600..4b9695a8f4 100644 --- a/crates/ruff/tests/snapshots/lint__output_format_json.snap +++ b/crates/ruff/tests/snapshots/lint__output_format_json.snap @@ -69,7 +69,7 @@ exit_code: 1 }, { "cell": null, - "code": null, + "code": "invalid-syntax", "end_location": { "column": 6, "row": 3 @@ -80,7 +80,7 @@ exit_code: 1 "column": 1, "row": 3 }, - "message": "SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)", + "message": "Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)", "noqa_row": null, "url": null } diff --git a/crates/ruff/tests/snapshots/lint__output_format_junit.snap b/crates/ruff/tests/snapshots/lint__output_format_junit.snap index 9755dedb05..384671431f 100644 --- a/crates/ruff/tests/snapshots/lint__output_format_junit.snap +++ b/crates/ruff/tests/snapshots/lint__output_format_junit.snap @@ -26,7 +26,7 @@ exit_code: 1 line 2, col 5, Undefined name `y` - line 3, col 1, SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) + line 3, col 1, Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) diff --git a/crates/ruff/tests/snapshots/lint__output_format_pylint.snap b/crates/ruff/tests/snapshots/lint__output_format_pylint.snap index 5e813a5c3a..bcedcda242 100644 --- a/crates/ruff/tests/snapshots/lint__output_format_pylint.snap +++ b/crates/ruff/tests/snapshots/lint__output_format_pylint.snap @@ -18,6 +18,6 @@ exit_code: 1 ----- stdout ----- input.py:1: [F401] `os` imported but unused input.py:2: [F821] Undefined name `y` -input.py:3: [invalid-syntax] SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) +input.py:3: [invalid-syntax] Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10) ----- stderr ----- diff --git a/crates/ruff/tests/snapshots/lint__output_format_rdjson.snap b/crates/ruff/tests/snapshots/lint__output_format_rdjson.snap index 2c744ff020..6ee239e2b4 100644 --- a/crates/ruff/tests/snapshots/lint__output_format_rdjson.snap +++ b/crates/ruff/tests/snapshots/lint__output_format_rdjson.snap @@ -90,7 +90,7 @@ exit_code: 1 } } }, - "message": "SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)" + "message": "Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)" } ], "severity": "WARNING", diff --git a/crates/ruff/tests/snapshots/lint__output_format_sarif.snap b/crates/ruff/tests/snapshots/lint__output_format_sarif.snap index 36f426c7ad..28f7438945 100644 --- a/crates/ruff/tests/snapshots/lint__output_format_sarif.snap +++ b/crates/ruff/tests/snapshots/lint__output_format_sarif.snap @@ -83,9 +83,9 @@ exit_code: 1 } ], "message": { - "text": "SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)" + "text": "Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)" }, - "ruleId": null + "ruleId": "invalid-syntax" } ], "tool": { diff --git a/crates/ruff_annotate_snippets/src/renderer/display_list.rs b/crates/ruff_annotate_snippets/src/renderer/display_list.rs index c445c6c898..339484290a 100644 --- a/crates/ruff_annotate_snippets/src/renderer/display_list.rs +++ b/crates/ruff_annotate_snippets/src/renderer/display_list.rs @@ -193,9 +193,14 @@ impl DisplaySet<'_> { stylesheet: &Stylesheet, buffer: &mut StyledBuffer, ) -> fmt::Result { + let hide_severity = annotation.annotation_type.is_none(); let color = get_annotation_style(&annotation.annotation_type, stylesheet); let formatted_len = if let Some(id) = &annotation.id { - 2 + id.len() + annotation_type_len(&annotation.annotation_type) + if hide_severity { + id.len() + } else { + 2 + id.len() + annotation_type_len(&annotation.annotation_type) + } } else { annotation_type_len(&annotation.annotation_type) }; @@ -209,18 +214,62 @@ impl DisplaySet<'_> { if formatted_len == 0 { self.format_label(line_offset, &annotation.label, stylesheet, buffer) } else { - let id = match &annotation.id { - Some(id) => format!("[{id}]"), - None => String::new(), - }; - buffer.append( - line_offset, - &format!("{}{}", annotation_type_str(&annotation.annotation_type), id), - *color, - ); + // TODO(brent) All of this complicated checking of `hide_severity` should be reverted + // once we have real severities in Ruff. This code is trying to account for two + // different cases: + // + // - main diagnostic message + // - subdiagnostic message + // + // In the first case, signaled by `hide_severity = true`, we want to print the ID (the + // noqa code for a ruff lint diagnostic, e.g. `F401`, or `invalid-syntax` for a syntax + // error) without brackets. Instead, for subdiagnostics, we actually want to print the + // severity (usually `help`) regardless of the `hide_severity` setting. This is signaled + // by an ID of `None`. + // + // With real severities these should be reported more like in ty: + // + // ``` + // error[F401]: `math` imported but unused + // error[invalid-syntax]: Cannot use `match` statement on Python 3.9... + // ``` + // + // instead of the current versions intended to mimic the old Ruff output format: + // + // ``` + // F401 `math` imported but unused + // invalid-syntax: Cannot use `match` statement on Python 3.9... + // ``` + // + // Note that the `invalid-syntax` colon is added manually in `ruff_db`, not here. We + // could eventually add a colon to Ruff lint diagnostics (`F401:`) and then make the + // colon below unconditional again. + // + // This also applies to the hard-coded `stylesheet.error()` styling of the + // hidden-severity `id`. This should just be `*color` again later, but for now we don't + // want an unformatted `id`, which is what `get_annotation_style` returns for + // `DisplayAnnotationType::None`. + let annotation_type = annotation_type_str(&annotation.annotation_type); + if let Some(id) = annotation.id { + if hide_severity { + buffer.append(line_offset, &format!("{id} "), *stylesheet.error()); + } else { + buffer.append(line_offset, &format!("{annotation_type}[{id}]"), *color); + } + } else { + buffer.append(line_offset, annotation_type, *color); + } + + if annotation.is_fixable { + buffer.append(line_offset, "[", stylesheet.none); + buffer.append(line_offset, "*", stylesheet.help); + buffer.append(line_offset, "] ", stylesheet.none); + } if !is_annotation_empty(annotation) { - buffer.append(line_offset, ": ", stylesheet.none); + if annotation.id.is_none() || !hide_severity { + buffer.append(line_offset, ": ", stylesheet.none); + } self.format_label(line_offset, &annotation.label, stylesheet, buffer)?; } Ok(()) @@ -768,6 +817,7 @@ pub(crate) struct Annotation<'a> { pub(crate) annotation_type: DisplayAnnotationType, pub(crate) id: Option<&'a str>, pub(crate) label: Vec>, + pub(crate) is_fixable: bool, } /// A single line used in `DisplayList`. @@ -920,6 +970,13 @@ pub(crate) enum DisplayAnnotationType { Help, } +impl DisplayAnnotationType { + #[inline] + const fn is_none(&self) -> bool { + matches!(self, Self::None) + } +} + impl From for DisplayAnnotationType { fn from(at: snippet::Level) -> Self { match at { @@ -1015,11 +1072,12 @@ fn format_message<'m>( title, footer, snippets, + is_fixable, } = message; let mut sets = vec![]; let body = if !snippets.is_empty() || primary { - vec![format_title(level, id, title)] + vec![format_title(level, id, title, is_fixable)] } else { format_footer(level, id, title) }; @@ -1060,12 +1118,18 @@ fn format_message<'m>( sets } -fn format_title<'a>(level: crate::Level, id: Option<&'a str>, label: &'a str) -> DisplayLine<'a> { +fn format_title<'a>( + level: crate::Level, + id: Option<&'a str>, + label: &'a str, + is_fixable: bool, +) -> DisplayLine<'a> { DisplayLine::Raw(DisplayRawLine::Annotation { annotation: Annotation { annotation_type: DisplayAnnotationType::from(level), id, label: format_label(Some(label), Some(DisplayTextStyle::Emphasis)), + is_fixable, }, source_aligned: false, continuation: false, @@ -1084,6 +1148,7 @@ fn format_footer<'a>( annotation_type: DisplayAnnotationType::from(level), id, label: format_label(Some(line), None), + is_fixable: false, }, source_aligned: true, continuation: i != 0, @@ -1472,6 +1537,7 @@ fn format_body<'m>( annotation_type, id: None, label: format_label(annotation.label, None), + is_fixable: false, }, range, annotation_type: DisplayAnnotationType::from(annotation.level), @@ -1511,6 +1577,7 @@ fn format_body<'m>( annotation_type, id: None, label: vec![], + is_fixable: false, }, range, annotation_type: DisplayAnnotationType::from(annotation.level), @@ -1580,6 +1647,7 @@ fn format_body<'m>( annotation_type, id: None, label: format_label(annotation.label, None), + is_fixable: false, }, range, annotation_type: DisplayAnnotationType::from(annotation.level), diff --git a/crates/ruff_annotate_snippets/src/snippet.rs b/crates/ruff_annotate_snippets/src/snippet.rs index 5830a7b5cd..386080e181 100644 --- a/crates/ruff_annotate_snippets/src/snippet.rs +++ b/crates/ruff_annotate_snippets/src/snippet.rs @@ -22,6 +22,7 @@ pub struct Message<'a> { pub(crate) title: &'a str, pub(crate) snippets: Vec>, pub(crate) footer: Vec>, + pub(crate) is_fixable: bool, } impl<'a> Message<'a> { @@ -49,6 +50,15 @@ impl<'a> Message<'a> { self.footer.extend(footer); self } + + /// Whether or not the diagnostic for this message is fixable. + /// + /// This is rendered as a `[*]` indicator after the `id` in an annotation header, if the + /// annotation also has `Level::None`. + pub fn is_fixable(mut self, yes: bool) -> Self { + self.is_fixable = yes; + self + } } /// Structure containing the slice of text to be annotated and @@ -145,6 +155,7 @@ impl Level { title, snippets: vec![], footer: vec![], + is_fixable: false, } } diff --git a/crates/ruff_db/src/diagnostic/mod.rs b/crates/ruff_db/src/diagnostic/mod.rs index 1c08c6781f..13e3bc6a77 100644 --- a/crates/ruff_db/src/diagnostic/mod.rs +++ b/crates/ruff_db/src/diagnostic/mod.rs @@ -366,6 +366,16 @@ impl Diagnostic { self.inner.secondary_code.as_ref() } + /// Returns the secondary code for the diagnostic if it exists, or the lint name otherwise. + /// + /// This is a common pattern for Ruff diagnostics, which want to use the noqa code in general, + /// but fall back on the `invalid-syntax` identifier for syntax errors, which don't have + /// secondary codes. + pub fn secondary_code_or_id(&self) -> &str { + self.secondary_code() + .map_or_else(|| self.inner.id.as_str(), SecondaryCode::as_str) + } + /// Set the secondary code for this diagnostic. pub fn set_secondary_code(&mut self, code: SecondaryCode) { Arc::make_mut(&mut self.inner).secondary_code = Some(code); diff --git a/crates/ruff_db/src/diagnostic/render.rs b/crates/ruff_db/src/diagnostic/render.rs index 5c7e31e7e0..a1794c0533 100644 --- a/crates/ruff_db/src/diagnostic/render.rs +++ b/crates/ruff_db/src/diagnostic/render.rs @@ -135,7 +135,7 @@ impl std::fmt::Display for DisplayDiagnostics<'_> { .none(stylesheet.none); for diag in self.diagnostics { - let resolved = Resolved::new(self.resolver, diag); + let resolved = Resolved::new(self.resolver, diag, self.config); let renderable = resolved.to_renderable(self.config.context); for diag in renderable.diagnostics.iter() { writeln!(f, "{}", renderer.render(diag.to_annotate()))?; @@ -191,9 +191,13 @@ struct Resolved<'a> { impl<'a> Resolved<'a> { /// Creates a new resolved set of diagnostics. - fn new(resolver: &'a dyn FileResolver, diag: &'a Diagnostic) -> Resolved<'a> { + fn new( + resolver: &'a dyn FileResolver, + diag: &'a Diagnostic, + config: &DisplayDiagnosticConfig, + ) -> Resolved<'a> { let mut diagnostics = vec![]; - diagnostics.push(ResolvedDiagnostic::from_diagnostic(resolver, diag)); + diagnostics.push(ResolvedDiagnostic::from_diagnostic(resolver, config, diag)); for sub in &diag.inner.subs { diagnostics.push(ResolvedDiagnostic::from_sub_diagnostic(resolver, sub)); } @@ -223,12 +227,14 @@ struct ResolvedDiagnostic<'a> { id: Option, message: String, annotations: Vec>, + is_fixable: bool, } impl<'a> ResolvedDiagnostic<'a> { /// Resolve a single diagnostic. fn from_diagnostic( resolver: &'a dyn FileResolver, + config: &DisplayDiagnosticConfig, diag: &'a Diagnostic, ) -> ResolvedDiagnostic<'a> { let annotations: Vec<_> = diag @@ -241,13 +247,35 @@ impl<'a> ResolvedDiagnostic<'a> { ResolvedAnnotation::new(path, &diagnostic_source, ann) }) .collect(); - let id = Some(diag.inner.id.to_string()); - let message = diag.inner.message.as_str().to_string(); + + let id = if config.hide_severity { + // Either the rule code alone (e.g. `F401`), or the lint id with a colon (e.g. + // `invalid-syntax:`). When Ruff gets real severities, we should put the colon back in + // `DisplaySet::format_annotation` for both cases, but this is a small hack to improve + // the formatting of syntax errors for now. This should also be kept consistent with the + // concise formatting. + Some(diag.secondary_code().map_or_else( + || format!("{id}:", id = diag.inner.id), + |code| code.to_string(), + )) + } else { + Some(diag.inner.id.to_string()) + }; + + let level = if config.hide_severity { + AnnotateLevel::None + } else { + diag.inner.severity.to_annotate() + }; + ResolvedDiagnostic { - level: diag.inner.severity.to_annotate(), + level, id, - message, + message: diag.inner.message.as_str().to_string(), annotations, + is_fixable: diag + .fix() + .is_some_and(|fix| fix.applies(config.fix_applicability)), } } @@ -271,6 +299,7 @@ impl<'a> ResolvedDiagnostic<'a> { id: None, message: diag.inner.message.as_str().to_string(), annotations, + is_fixable: false, } } @@ -338,6 +367,7 @@ impl<'a> ResolvedDiagnostic<'a> { id: self.id.as_deref(), message: &self.message, snippets_by_input, + is_fixable: self.is_fixable, } } } @@ -436,6 +466,10 @@ struct RenderableDiagnostic<'r> { /// should be from the same file, and none of the snippets inside of a /// collection should overlap with one another or be directly adjacent. snippets_by_input: Vec>, + /// Whether or not the diagnostic is fixable. + /// + /// This is rendered as a `[*]` indicator after the diagnostic ID. + is_fixable: bool, } impl RenderableDiagnostic<'_> { @@ -448,7 +482,7 @@ impl RenderableDiagnostic<'_> { .iter() .map(|snippet| snippet.to_annotate(path)) }); - let mut message = self.level.title(self.message); + let mut message = self.level.title(self.message).is_fixable(self.is_fixable); if let Some(id) = self.id { message = message.id(id); } @@ -2850,10 +2884,10 @@ if call(foo env.format(format); let diagnostics = vec![ - env.invalid_syntax("SyntaxError: Expected one or more symbol names after import") + env.invalid_syntax("Expected one or more symbol names after import") .primary("syntax_errors.py", "1:14", "1:15", "") .build(), - env.invalid_syntax("SyntaxError: Expected ')', found newline") + env.invalid_syntax("Expected ')', found newline") .primary("syntax_errors.py", "3:11", "3:12", "") .build(), ]; diff --git a/crates/ruff_db/src/diagnostic/render/azure.rs b/crates/ruff_db/src/diagnostic/render/azure.rs index d607e08d86..78d8c89dfb 100644 --- a/crates/ruff_db/src/diagnostic/render/azure.rs +++ b/crates/ruff_db/src/diagnostic/render/azure.rs @@ -50,10 +50,8 @@ impl AzureRenderer<'_> { } writeln!( f, - "{code}]{body}", - code = diag - .secondary_code() - .map_or_else(String::new, |code| format!("code={code};")), + "code={code};]{body}", + code = diag.secondary_code_or_id(), body = diag.body(), )?; } diff --git a/crates/ruff_db/src/diagnostic/render/concise.rs b/crates/ruff_db/src/diagnostic/render/concise.rs index 0973b10ddb..fdbbeef59f 100644 --- a/crates/ruff_db/src/diagnostic/render/concise.rs +++ b/crates/ruff_db/src/diagnostic/render/concise.rs @@ -69,6 +69,12 @@ impl<'a> ConciseRenderer<'a> { "{code} ", code = fmt_styled(code, stylesheet.secondary_code) )?; + } else { + write!( + f, + "{id}: ", + id = fmt_styled(diag.inner.id.as_str(), stylesheet.secondary_code) + )?; } if self.config.show_fix_status { if let Some(fix) = diag.fix() { @@ -156,8 +162,8 @@ mod tests { env.show_fix_status(true); env.fix_applicability(Applicability::DisplayOnly); insta::assert_snapshot!(env.render_diagnostics(&diagnostics), @r" - syntax_errors.py:1:15: SyntaxError: Expected one or more symbol names after import - syntax_errors.py:3:12: SyntaxError: Expected ')', found newline + syntax_errors.py:1:15: invalid-syntax: Expected one or more symbol names after import + syntax_errors.py:3:12: invalid-syntax: Expected ')', found newline "); } @@ -165,8 +171,8 @@ mod tests { fn syntax_errors() { let (env, diagnostics) = create_syntax_error_diagnostics(DiagnosticFormat::Concise); insta::assert_snapshot!(env.render_diagnostics(&diagnostics), @r" - syntax_errors.py:1:15: error[invalid-syntax] SyntaxError: Expected one or more symbol names after import - syntax_errors.py:3:12: error[invalid-syntax] SyntaxError: Expected ')', found newline + syntax_errors.py:1:15: error[invalid-syntax] Expected one or more symbol names after import + syntax_errors.py:3:12: error[invalid-syntax] Expected ')', found newline "); } diff --git a/crates/ruff_db/src/diagnostic/render/full.rs b/crates/ruff_db/src/diagnostic/render/full.rs index 5ffa777e69..d4c286291c 100644 --- a/crates/ruff_db/src/diagnostic/render/full.rs +++ b/crates/ruff_db/src/diagnostic/render/full.rs @@ -1,5 +1,7 @@ #[cfg(test)] mod tests { + use ruff_diagnostics::Applicability; + use crate::diagnostic::{ DiagnosticFormat, Severity, render::tests::{TestEnvironment, create_diagnostics, create_syntax_error_diagnostics}, @@ -42,7 +44,7 @@ mod tests { fn syntax_errors() { let (env, diagnostics) = create_syntax_error_diagnostics(DiagnosticFormat::Full); insta::assert_snapshot!(env.render_diagnostics(&diagnostics), @r" - error[invalid-syntax]: SyntaxError: Expected one or more symbol names after import + error[invalid-syntax]: Expected one or more symbol names after import --> syntax_errors.py:1:15 | 1 | from os import @@ -51,7 +53,71 @@ mod tests { 3 | if call(foo | - error[invalid-syntax]: SyntaxError: Expected ')', found newline + error[invalid-syntax]: Expected ')', found newline + --> syntax_errors.py:3:12 + | + 1 | from os import + 2 | + 3 | if call(foo + | ^ + 4 | def bar(): + 5 | pass + | + "); + } + + #[test] + fn hide_severity_output() { + let (mut env, diagnostics) = create_diagnostics(DiagnosticFormat::Full); + env.hide_severity(true); + env.fix_applicability(Applicability::DisplayOnly); + + insta::assert_snapshot!(env.render_diagnostics(&diagnostics), @r#" + F401 [*] `os` imported but unused + --> fib.py:1:8 + | + 1 | import os + | ^^ + | + help: Remove unused import: `os` + + F841 [*] Local variable `x` is assigned to but never used + --> fib.py:6:5 + | + 4 | def fibonacci(n): + 5 | """Compute the nth number in the Fibonacci sequence.""" + 6 | x = 1 + | ^ + 7 | if n == 0: + 8 | return 0 + | + help: Remove assignment to unused variable `x` + + F821 Undefined name `a` + --> undef.py:1:4 + | + 1 | if a == 1: pass + | ^ + | + "#); + } + + #[test] + fn hide_severity_syntax_errors() { + let (mut env, diagnostics) = create_syntax_error_diagnostics(DiagnosticFormat::Full); + env.hide_severity(true); + + insta::assert_snapshot!(env.render_diagnostics(&diagnostics), @r" + invalid-syntax: Expected one or more symbol names after import + --> syntax_errors.py:1:15 + | + 1 | from os import + | ^ + 2 | + 3 | if call(foo + | + + invalid-syntax: Expected ')', found newline --> syntax_errors.py:3:12 | 1 | from os import diff --git a/crates/ruff_db/src/diagnostic/render/json.rs b/crates/ruff_db/src/diagnostic/render/json.rs index 0e7a35b436..e31af45396 100644 --- a/crates/ruff_db/src/diagnostic/render/json.rs +++ b/crates/ruff_db/src/diagnostic/render/json.rs @@ -6,7 +6,7 @@ use ruff_notebook::NotebookIndex; use ruff_source_file::{LineColumn, OneIndexed}; use ruff_text_size::Ranged; -use crate::diagnostic::{Diagnostic, DiagnosticSource, DisplayDiagnosticConfig, SecondaryCode}; +use crate::diagnostic::{Diagnostic, DiagnosticSource, DisplayDiagnosticConfig}; use super::FileResolver; @@ -99,7 +99,7 @@ pub(super) fn diagnostic_to_json<'a>( // In preview, the locations and filename can be optional. if config.preview { JsonDiagnostic { - code: diagnostic.secondary_code(), + code: diagnostic.secondary_code_or_id(), url: diagnostic.to_ruff_url(), message: diagnostic.body(), fix, @@ -111,7 +111,7 @@ pub(super) fn diagnostic_to_json<'a>( } } else { JsonDiagnostic { - code: diagnostic.secondary_code(), + code: diagnostic.secondary_code_or_id(), url: diagnostic.to_ruff_url(), message: diagnostic.body(), fix, @@ -221,7 +221,7 @@ impl Serialize for ExpandedEdits<'_> { #[derive(Serialize)] pub(crate) struct JsonDiagnostic<'a> { cell: Option, - code: Option<&'a SecondaryCode>, + code: &'a str, end_location: Option, filename: Option<&'a str>, fix: Option>, @@ -302,7 +302,7 @@ mod tests { [ { "cell": null, - "code": null, + "code": "test-diagnostic", "end_location": { "column": 1, "row": 1 @@ -336,7 +336,7 @@ mod tests { [ { "cell": null, - "code": null, + "code": "test-diagnostic", "end_location": null, "filename": null, "fix": null, diff --git a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__azure__tests__syntax_errors.snap b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__azure__tests__syntax_errors.snap index 473567c7d1..76cab4e0c1 100644 --- a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__azure__tests__syntax_errors.snap +++ b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__azure__tests__syntax_errors.snap @@ -2,5 +2,5 @@ source: crates/ruff_db/src/diagnostic/render/azure.rs expression: env.render_diagnostics(&diagnostics) --- -##vso[task.logissue type=error;sourcepath=syntax_errors.py;linenumber=1;columnnumber=15;]SyntaxError: Expected one or more symbol names after import -##vso[task.logissue type=error;sourcepath=syntax_errors.py;linenumber=3;columnnumber=12;]SyntaxError: Expected ')', found newline +##vso[task.logissue type=error;sourcepath=syntax_errors.py;linenumber=1;columnnumber=15;code=invalid-syntax;]Expected one or more symbol names after import +##vso[task.logissue type=error;sourcepath=syntax_errors.py;linenumber=3;columnnumber=12;code=invalid-syntax;]Expected ')', found newline diff --git a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__json__tests__syntax_errors.snap b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__json__tests__syntax_errors.snap index 412debffab..131982f428 100644 --- a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__json__tests__syntax_errors.snap +++ b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__json__tests__syntax_errors.snap @@ -5,7 +5,7 @@ expression: env.render_diagnostics(&diagnostics) [ { "cell": null, - "code": null, + "code": "invalid-syntax", "end_location": { "column": 1, "row": 2 @@ -16,13 +16,13 @@ expression: env.render_diagnostics(&diagnostics) "column": 15, "row": 1 }, - "message": "SyntaxError: Expected one or more symbol names after import", + "message": "Expected one or more symbol names after import", "noqa_row": null, "url": null }, { "cell": null, - "code": null, + "code": "invalid-syntax", "end_location": { "column": 1, "row": 4 @@ -33,7 +33,7 @@ expression: env.render_diagnostics(&diagnostics) "column": 12, "row": 3 }, - "message": "SyntaxError: Expected ')', found newline", + "message": "Expected ')', found newline", "noqa_row": null, "url": null } diff --git a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__json_lines__tests__syntax_errors.snap b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__json_lines__tests__syntax_errors.snap index b722248950..b39dd565bf 100644 --- a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__json_lines__tests__syntax_errors.snap +++ b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__json_lines__tests__syntax_errors.snap @@ -2,5 +2,5 @@ source: crates/ruff_db/src/diagnostic/render/json_lines.rs expression: env.render_diagnostics(&diagnostics) --- -{"cell":null,"code":null,"end_location":{"column":1,"row":2},"filename":"syntax_errors.py","fix":null,"location":{"column":15,"row":1},"message":"SyntaxError: Expected one or more symbol names after import","noqa_row":null,"url":null} -{"cell":null,"code":null,"end_location":{"column":1,"row":4},"filename":"syntax_errors.py","fix":null,"location":{"column":12,"row":3},"message":"SyntaxError: Expected ')', found newline","noqa_row":null,"url":null} +{"cell":null,"code":"invalid-syntax","end_location":{"column":1,"row":2},"filename":"syntax_errors.py","fix":null,"location":{"column":15,"row":1},"message":"Expected one or more symbol names after import","noqa_row":null,"url":null} +{"cell":null,"code":"invalid-syntax","end_location":{"column":1,"row":4},"filename":"syntax_errors.py","fix":null,"location":{"column":12,"row":3},"message":"Expected ')', found newline","noqa_row":null,"url":null} diff --git a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__junit__tests__syntax_errors.snap b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__junit__tests__syntax_errors.snap index e44145b0f3..56af372561 100644 --- a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__junit__tests__syntax_errors.snap +++ b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__junit__tests__syntax_errors.snap @@ -6,10 +6,10 @@ expression: env.render_diagnostics(&diagnostics) - line 1, col 15, SyntaxError: Expected one or more symbol names after import + line 1, col 15, Expected one or more symbol names after import - line 3, col 12, SyntaxError: Expected ')', found newline + line 3, col 12, Expected ')', found newline diff --git a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__pylint__tests__syntax_errors.snap b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__pylint__tests__syntax_errors.snap index 179e762066..f6a867fad8 100644 --- a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__pylint__tests__syntax_errors.snap +++ b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__pylint__tests__syntax_errors.snap @@ -2,5 +2,5 @@ source: crates/ruff_db/src/diagnostic/render/pylint.rs expression: env.render_diagnostics(&diagnostics) --- -syntax_errors.py:1: [invalid-syntax] SyntaxError: Expected one or more symbol names after import -syntax_errors.py:3: [invalid-syntax] SyntaxError: Expected ')', found newline +syntax_errors.py:1: [invalid-syntax] Expected one or more symbol names after import +syntax_errors.py:3: [invalid-syntax] Expected ')', found newline diff --git a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__rdjson__tests__syntax_errors.snap b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__rdjson__tests__syntax_errors.snap index 30370c6446..4f740e1d4a 100644 --- a/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__rdjson__tests__syntax_errors.snap +++ b/crates/ruff_db/src/diagnostic/render/snapshots/ruff_db__diagnostic__render__rdjson__tests__syntax_errors.snap @@ -21,7 +21,7 @@ expression: env.render_diagnostics(&diagnostics) } } }, - "message": "SyntaxError: Expected one or more symbol names after import" + "message": "Expected one or more symbol names after import" }, { "code": { @@ -40,7 +40,7 @@ expression: env.render_diagnostics(&diagnostics) } } }, - "message": "SyntaxError: Expected ')', found newline" + "message": "Expected ')', found newline" } ], "severity": "WARNING", diff --git a/crates/ruff_linter/src/message/github.rs b/crates/ruff_linter/src/message/github.rs index 37a384d75e..7c775e17cc 100644 --- a/crates/ruff_linter/src/message/github.rs +++ b/crates/ruff_linter/src/message/github.rs @@ -33,10 +33,8 @@ impl Emitter for GithubEmitter { write!( writer, - "::error title=Ruff{code},file={file},line={row},col={column},endLine={end_row},endColumn={end_column}::", - code = diagnostic - .secondary_code() - .map_or_else(String::new, |code| format!(" ({code})")), + "::error title=Ruff ({code}),file={file},line={row},col={column},endLine={end_row},endColumn={end_column}::", + code = diagnostic.secondary_code_or_id(), file = filename, row = source_location.line, column = source_location.column, @@ -54,6 +52,8 @@ impl Emitter for GithubEmitter { if let Some(code) = diagnostic.secondary_code() { write!(writer, " {code}")?; + } else { + write!(writer, " {id}:", id = diagnostic.id())?; } writeln!(writer, " {}", diagnostic.body())?; diff --git a/crates/ruff_linter/src/message/mod.rs b/crates/ruff_linter/src/message/mod.rs index d49cbe9659..9ef41c4ed4 100644 --- a/crates/ruff_linter/src/message/mod.rs +++ b/crates/ruff_linter/src/message/mod.rs @@ -33,8 +33,7 @@ mod text; /// Creates a `Diagnostic` from a syntax error, with the format expected by Ruff. /// /// This is almost identical to `ruff_db::diagnostic::create_syntax_error_diagnostic`, except the -/// `message` is stored as the primary diagnostic message instead of on the primary annotation, and -/// `SyntaxError: ` is prepended to the message. +/// `message` is stored as the primary diagnostic message instead of on the primary annotation. /// /// TODO(brent) These should be unified at some point, but we keep them separate for now to avoid a /// ton of snapshot changes while combining ruff's diagnostic type with `Diagnostic`. @@ -43,11 +42,7 @@ pub fn create_syntax_error_diagnostic( message: impl std::fmt::Display, range: impl Ranged, ) -> Diagnostic { - let mut diag = Diagnostic::new( - DiagnosticId::InvalidSyntax, - Severity::Error, - format_args!("SyntaxError: {message}"), - ); + let mut diag = Diagnostic::new(DiagnosticId::InvalidSyntax, Severity::Error, message); let span = span.into().with_range(range.range()); diag.annotate(Annotation::primary(span)); diag diff --git a/crates/ruff_linter/src/message/sarif.rs b/crates/ruff_linter/src/message/sarif.rs index 4b7b80e61c..cf738b875d 100644 --- a/crates/ruff_linter/src/message/sarif.rs +++ b/crates/ruff_linter/src/message/sarif.rs @@ -27,7 +27,10 @@ impl Emitter for SarifEmitter { .map(SarifResult::from_message) .collect::>>()?; - let unique_rules: HashSet<_> = results.iter().filter_map(|result| result.code).collect(); + let unique_rules: HashSet<_> = results + .iter() + .filter_map(|result| result.code.as_secondary_code()) + .collect(); let mut rules: Vec = unique_rules.into_iter().map(SarifRule::from).collect(); rules.sort_by(|a, b| a.code.cmp(b.code)); @@ -109,9 +112,40 @@ impl Serialize for SarifRule<'_> { } } +#[derive(Debug)] +enum RuleCode<'a> { + SecondaryCode(&'a SecondaryCode), + LintId(&'a str), +} + +impl RuleCode<'_> { + fn as_secondary_code(&self) -> Option<&SecondaryCode> { + match self { + RuleCode::SecondaryCode(code) => Some(code), + RuleCode::LintId(_) => None, + } + } + + fn as_str(&self) -> &str { + match self { + RuleCode::SecondaryCode(code) => code.as_str(), + RuleCode::LintId(id) => id, + } + } +} + +impl<'a> From<&'a Diagnostic> for RuleCode<'a> { + fn from(code: &'a Diagnostic) -> Self { + match code.secondary_code() { + Some(diagnostic) => Self::SecondaryCode(diagnostic), + None => Self::LintId(code.id().as_str()), + } + } +} + #[derive(Debug)] struct SarifResult<'a> { - code: Option<&'a SecondaryCode>, + code: RuleCode<'a>, level: String, message: String, uri: String, @@ -128,7 +162,7 @@ impl<'a> SarifResult<'a> { let end_location = message.expect_ruff_end_location(); let path = normalize_path(&*message.expect_ruff_filename()); Ok(Self { - code: message.secondary_code(), + code: RuleCode::from(message), level: "error".to_string(), message: message.body().to_string(), uri: url::Url::from_file_path(&path) @@ -148,7 +182,7 @@ impl<'a> SarifResult<'a> { let end_location = message.expect_ruff_end_location(); let path = normalize_path(&*message.expect_ruff_filename()); Ok(Self { - code: message.secondary_code(), + code: RuleCode::from(message), level: "error".to_string(), message: message.body().to_string(), uri: path.display().to_string(), @@ -183,7 +217,7 @@ impl Serialize for SarifResult<'_> { } } }], - "ruleId": self.code, + "ruleId": self.code.as_str(), }) .serialize(serializer) } diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__github__tests__syntax_errors.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__github__tests__syntax_errors.snap index c7e110c715..55436236c1 100644 --- a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__github__tests__syntax_errors.snap +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__github__tests__syntax_errors.snap @@ -1,7 +1,6 @@ --- source: crates/ruff_linter/src/message/github.rs expression: content -snapshot_kind: text --- -::error title=Ruff,file=syntax_errors.py,line=1,col=15,endLine=2,endColumn=1::syntax_errors.py:1:15: SyntaxError: Expected one or more symbol names after import -::error title=Ruff,file=syntax_errors.py,line=3,col=12,endLine=4,endColumn=1::syntax_errors.py:3:12: SyntaxError: Expected ')', found newline +::error title=Ruff (invalid-syntax),file=syntax_errors.py,line=1,col=15,endLine=2,endColumn=1::syntax_errors.py:1:15: invalid-syntax: Expected one or more symbol names after import +::error title=Ruff (invalid-syntax),file=syntax_errors.py,line=3,col=12,endLine=4,endColumn=1::syntax_errors.py:3:12: invalid-syntax: Expected ')', found newline diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__syntax_errors.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__syntax_errors.snap index 52f3c9f822..1d077b7321 100644 --- a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__syntax_errors.snap +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__syntax_errors.snap @@ -1,8 +1,7 @@ --- source: crates/ruff_linter/src/message/grouped.rs expression: content -snapshot_kind: text --- syntax_errors.py: - 1:15 SyntaxError: Expected one or more symbol names after import - 3:12 SyntaxError: Expected ')', found newline + 1:15 invalid-syntax: Expected one or more symbol names after import + 3:12 invalid-syntax: Expected ')', found newline diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__syntax_errors.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__syntax_errors.snap index b0cb408580..7dfac7710a 100644 --- a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__syntax_errors.snap +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__syntax_errors.snap @@ -2,7 +2,7 @@ source: crates/ruff_linter/src/message/text.rs expression: content --- -syntax_errors.py:1:15: SyntaxError: Expected one or more symbol names after import +syntax_errors.py:1:15: invalid-syntax: Expected one or more symbol names after import | 1 | from os import | ^ @@ -11,7 +11,7 @@ syntax_errors.py:1:15: SyntaxError: Expected one or more symbol names after impo 4 | def bar(): | -syntax_errors.py:3:12: SyntaxError: Expected ')', found newline +syntax_errors.py:3:12: invalid-syntax: Expected ')', found newline | 1 | from os import 2 | diff --git a/crates/ruff_linter/src/message/text.rs b/crates/ruff_linter/src/message/text.rs index a04c56bff6..0b9acee50a 100644 --- a/crates/ruff_linter/src/message/text.rs +++ b/crates/ruff_linter/src/message/text.rs @@ -154,7 +154,12 @@ impl Display for RuleCodeAndBody<'_> { body = self.message.body(), ) } else { - f.write_str(self.message.body()) + write!( + f, + "{code}: {body}", + code = self.message.id().as_str().red().bold(), + body = self.message.body(), + ) } } } diff --git a/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__COM81_syntax_error.py.snap b/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__COM81_syntax_error.py.snap index 8105e635a6..f6be9a1954 100644 --- a/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__COM81_syntax_error.py.snap +++ b/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__COM81_syntax_error.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/flake8_commas/mod.rs --- -COM81_syntax_error.py:3:5: SyntaxError: Starred expression cannot be used here +COM81_syntax_error.py:3:5: invalid-syntax: Starred expression cannot be used here | 1 | # Check for `flake8-commas` violation for a file containing syntax errors. 2 | ( @@ -10,7 +10,7 @@ COM81_syntax_error.py:3:5: SyntaxError: Starred expression cannot be used here 4 | ) | -COM81_syntax_error.py:6:9: SyntaxError: Type parameter list cannot be empty +COM81_syntax_error.py:6:9: invalid-syntax: Type parameter list cannot be empty | 4 | ) 5 | diff --git a/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__preview__COM81_syntax_error.py.snap b/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__preview__COM81_syntax_error.py.snap index 8105e635a6..f6be9a1954 100644 --- a/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__preview__COM81_syntax_error.py.snap +++ b/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__preview__COM81_syntax_error.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/flake8_commas/mod.rs --- -COM81_syntax_error.py:3:5: SyntaxError: Starred expression cannot be used here +COM81_syntax_error.py:3:5: invalid-syntax: Starred expression cannot be used here | 1 | # Check for `flake8-commas` violation for a file containing syntax errors. 2 | ( @@ -10,7 +10,7 @@ COM81_syntax_error.py:3:5: SyntaxError: Starred expression cannot be used here 4 | ) | -COM81_syntax_error.py:6:9: SyntaxError: Type parameter list cannot be empty +COM81_syntax_error.py:6:9: invalid-syntax: Type parameter list cannot be empty | 4 | ) 5 | diff --git a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC001_ISC_syntax_error.py.snap b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC001_ISC_syntax_error.py.snap index 0dab8744b5..8449cc6015 100644 --- a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC001_ISC_syntax_error.py.snap +++ b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC001_ISC_syntax_error.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/flake8_implicit_str_concat/mod.rs --- -ISC_syntax_error.py:2:5: SyntaxError: missing closing quote in string literal +ISC_syntax_error.py:2:5: invalid-syntax: missing closing quote in string literal | 1 | # The lexer doesn't emit a string token if it's unterminated 2 | "a" "b @@ -10,7 +10,7 @@ ISC_syntax_error.py:2:5: SyntaxError: missing closing quote in string literal 4 | "a" """b | -ISC_syntax_error.py:2:7: SyntaxError: Expected a statement +ISC_syntax_error.py:2:7: invalid-syntax: Expected a statement | 1 | # The lexer doesn't emit a string token if it's unterminated 2 | "a" "b @@ -31,7 +31,7 @@ ISC_syntax_error.py:3:1: ISC001 Implicitly concatenated string literals on one l | = help: Combine string literals -ISC_syntax_error.py:3:9: SyntaxError: missing closing quote in string literal +ISC_syntax_error.py:3:9: invalid-syntax: missing closing quote in string literal | 1 | # The lexer doesn't emit a string token if it's unterminated 2 | "a" "b @@ -41,7 +41,7 @@ ISC_syntax_error.py:3:9: SyntaxError: missing closing quote in string literal 5 | c""" "d | -ISC_syntax_error.py:3:11: SyntaxError: Expected a statement +ISC_syntax_error.py:3:11: invalid-syntax: Expected a statement | 1 | # The lexer doesn't emit a string token if it's unterminated 2 | "a" "b @@ -63,7 +63,7 @@ ISC_syntax_error.py:4:1: ISC001 Implicitly concatenated string literals on one l | = help: Combine string literals -ISC_syntax_error.py:5:6: SyntaxError: missing closing quote in string literal +ISC_syntax_error.py:5:6: invalid-syntax: missing closing quote in string literal | 3 | "a" "b" "c 4 | "a" """b @@ -73,7 +73,7 @@ ISC_syntax_error.py:5:6: SyntaxError: missing closing quote in string literal 7 | # For f-strings, the `FStringRanges` won't contain the range for | -ISC_syntax_error.py:5:8: SyntaxError: Expected a statement +ISC_syntax_error.py:5:8: invalid-syntax: Expected a statement | 3 | "a" "b" "c 4 | "a" """b @@ -84,7 +84,7 @@ ISC_syntax_error.py:5:8: SyntaxError: Expected a statement 8 | # unterminated f-strings. | -ISC_syntax_error.py:9:8: SyntaxError: f-string: unterminated string +ISC_syntax_error.py:9:8: invalid-syntax: f-string: unterminated string | 7 | # For f-strings, the `FStringRanges` won't contain the range for 8 | # unterminated f-strings. @@ -94,7 +94,7 @@ ISC_syntax_error.py:9:8: SyntaxError: f-string: unterminated string 11 | f"a" f"""b | -ISC_syntax_error.py:9:9: SyntaxError: Expected FStringEnd, found newline +ISC_syntax_error.py:9:9: invalid-syntax: Expected FStringEnd, found newline | 7 | # For f-strings, the `FStringRanges` won't contain the range for 8 | # unterminated f-strings. @@ -116,7 +116,7 @@ ISC_syntax_error.py:10:1: ISC001 Implicitly concatenated string literals on one | = help: Combine string literals -ISC_syntax_error.py:10:13: SyntaxError: f-string: unterminated string +ISC_syntax_error.py:10:13: invalid-syntax: f-string: unterminated string | 8 | # unterminated f-strings. 9 | f"a" f"b @@ -126,7 +126,7 @@ ISC_syntax_error.py:10:13: SyntaxError: f-string: unterminated string 12 | c""" f"d {e | -ISC_syntax_error.py:10:14: SyntaxError: Expected FStringEnd, found newline +ISC_syntax_error.py:10:14: invalid-syntax: Expected FStringEnd, found newline | 8 | # unterminated f-strings. 9 | f"a" f"b @@ -148,7 +148,7 @@ ISC_syntax_error.py:11:1: ISC001 Implicitly concatenated string literals on one | = help: Combine string literals -ISC_syntax_error.py:16:5: SyntaxError: missing closing quote in string literal +ISC_syntax_error.py:16:5: invalid-syntax: missing closing quote in string literal | 14 | ( 15 | "a" @@ -158,7 +158,7 @@ ISC_syntax_error.py:16:5: SyntaxError: missing closing quote in string literal 18 | "d" | -ISC_syntax_error.py:26:9: SyntaxError: f-string: unterminated triple-quoted string +ISC_syntax_error.py:26:9: invalid-syntax: f-string: unterminated triple-quoted string | 24 | ( 25 | """abc""" @@ -170,14 +170,14 @@ ISC_syntax_error.py:26:9: SyntaxError: f-string: unterminated triple-quoted stri | |__^ | -ISC_syntax_error.py:30:1: SyntaxError: unexpected EOF while parsing +ISC_syntax_error.py:30:1: invalid-syntax: unexpected EOF while parsing | 28 | "i" "j" 29 | ) | ^ | -ISC_syntax_error.py:30:1: SyntaxError: f-string: unterminated string +ISC_syntax_error.py:30:1: invalid-syntax: f-string: unterminated string | 28 | "i" "j" 29 | ) diff --git a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC002_ISC_syntax_error.py.snap b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC002_ISC_syntax_error.py.snap index 99f0f7d157..4f200eb841 100644 --- a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC002_ISC_syntax_error.py.snap +++ b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC002_ISC_syntax_error.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/flake8_implicit_str_concat/mod.rs --- -ISC_syntax_error.py:2:5: SyntaxError: missing closing quote in string literal +ISC_syntax_error.py:2:5: invalid-syntax: missing closing quote in string literal | 1 | # The lexer doesn't emit a string token if it's unterminated 2 | "a" "b @@ -10,7 +10,7 @@ ISC_syntax_error.py:2:5: SyntaxError: missing closing quote in string literal 4 | "a" """b | -ISC_syntax_error.py:2:7: SyntaxError: Expected a statement +ISC_syntax_error.py:2:7: invalid-syntax: Expected a statement | 1 | # The lexer doesn't emit a string token if it's unterminated 2 | "a" "b @@ -20,7 +20,7 @@ ISC_syntax_error.py:2:7: SyntaxError: Expected a statement 5 | c""" "d | -ISC_syntax_error.py:3:9: SyntaxError: missing closing quote in string literal +ISC_syntax_error.py:3:9: invalid-syntax: missing closing quote in string literal | 1 | # The lexer doesn't emit a string token if it's unterminated 2 | "a" "b @@ -30,7 +30,7 @@ ISC_syntax_error.py:3:9: SyntaxError: missing closing quote in string literal 5 | c""" "d | -ISC_syntax_error.py:3:11: SyntaxError: Expected a statement +ISC_syntax_error.py:3:11: invalid-syntax: Expected a statement | 1 | # The lexer doesn't emit a string token if it's unterminated 2 | "a" "b @@ -40,7 +40,7 @@ ISC_syntax_error.py:3:11: SyntaxError: Expected a statement 5 | c""" "d | -ISC_syntax_error.py:5:6: SyntaxError: missing closing quote in string literal +ISC_syntax_error.py:5:6: invalid-syntax: missing closing quote in string literal | 3 | "a" "b" "c 4 | "a" """b @@ -50,7 +50,7 @@ ISC_syntax_error.py:5:6: SyntaxError: missing closing quote in string literal 7 | # For f-strings, the `FStringRanges` won't contain the range for | -ISC_syntax_error.py:5:8: SyntaxError: Expected a statement +ISC_syntax_error.py:5:8: invalid-syntax: Expected a statement | 3 | "a" "b" "c 4 | "a" """b @@ -61,7 +61,7 @@ ISC_syntax_error.py:5:8: SyntaxError: Expected a statement 8 | # unterminated f-strings. | -ISC_syntax_error.py:9:8: SyntaxError: f-string: unterminated string +ISC_syntax_error.py:9:8: invalid-syntax: f-string: unterminated string | 7 | # For f-strings, the `FStringRanges` won't contain the range for 8 | # unterminated f-strings. @@ -71,7 +71,7 @@ ISC_syntax_error.py:9:8: SyntaxError: f-string: unterminated string 11 | f"a" f"""b | -ISC_syntax_error.py:9:9: SyntaxError: Expected FStringEnd, found newline +ISC_syntax_error.py:9:9: invalid-syntax: Expected FStringEnd, found newline | 7 | # For f-strings, the `FStringRanges` won't contain the range for 8 | # unterminated f-strings. @@ -82,7 +82,7 @@ ISC_syntax_error.py:9:9: SyntaxError: Expected FStringEnd, found newline 12 | c""" f"d {e | -ISC_syntax_error.py:10:13: SyntaxError: f-string: unterminated string +ISC_syntax_error.py:10:13: invalid-syntax: f-string: unterminated string | 8 | # unterminated f-strings. 9 | f"a" f"b @@ -92,7 +92,7 @@ ISC_syntax_error.py:10:13: SyntaxError: f-string: unterminated string 12 | c""" f"d {e | -ISC_syntax_error.py:10:14: SyntaxError: Expected FStringEnd, found newline +ISC_syntax_error.py:10:14: invalid-syntax: Expected FStringEnd, found newline | 8 | # unterminated f-strings. 9 | f"a" f"b @@ -102,7 +102,7 @@ ISC_syntax_error.py:10:14: SyntaxError: Expected FStringEnd, found newline 12 | c""" f"d {e | -ISC_syntax_error.py:16:5: SyntaxError: missing closing quote in string literal +ISC_syntax_error.py:16:5: invalid-syntax: missing closing quote in string literal | 14 | ( 15 | "a" @@ -112,7 +112,7 @@ ISC_syntax_error.py:16:5: SyntaxError: missing closing quote in string literal 18 | "d" | -ISC_syntax_error.py:26:9: SyntaxError: f-string: unterminated triple-quoted string +ISC_syntax_error.py:26:9: invalid-syntax: f-string: unterminated triple-quoted string | 24 | ( 25 | """abc""" @@ -124,14 +124,14 @@ ISC_syntax_error.py:26:9: SyntaxError: f-string: unterminated triple-quoted stri | |__^ | -ISC_syntax_error.py:30:1: SyntaxError: unexpected EOF while parsing +ISC_syntax_error.py:30:1: invalid-syntax: unexpected EOF while parsing | 28 | "i" "j" 29 | ) | ^ | -ISC_syntax_error.py:30:1: SyntaxError: f-string: unterminated string +ISC_syntax_error.py:30:1: invalid-syntax: f-string: unterminated string | 28 | "i" "j" 29 | ) diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E111_E11.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E111_E11.py.snap index 4b92dd6823..e1cccc2580 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E111_E11.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E111_E11.py.snap @@ -21,7 +21,7 @@ E11.py:6:1: E111 Indentation is not a multiple of 4 8 | if False: | -E11.py:9:1: SyntaxError: Expected an indented block after `if` statement +E11.py:9:1: invalid-syntax: Expected an indented block after `if` statement | 7 | #: E112 8 | if False: @@ -31,7 +31,7 @@ E11.py:9:1: SyntaxError: Expected an indented block after `if` statement 11 | print() | -E11.py:12:1: SyntaxError: Unexpected indentation +E11.py:12:1: invalid-syntax: Unexpected indentation | 10 | #: E113 11 | print() @@ -41,7 +41,7 @@ E11.py:12:1: SyntaxError: Unexpected indentation 14 | mimetype = 'application/x-directory' | -E11.py:14:1: SyntaxError: Expected a statement +E11.py:14:1: invalid-syntax: Expected a statement | 12 | print() 13 | #: E114 E116 @@ -51,7 +51,7 @@ E11.py:14:1: SyntaxError: Expected a statement 16 | create_date = False | -E11.py:45:1: SyntaxError: Expected an indented block after `if` statement +E11.py:45:1: invalid-syntax: Expected an indented block after `if` statement | 43 | #: E112 44 | if False: # diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E112_E11.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E112_E11.py.snap index 5ade4346e0..d0f4156303 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E112_E11.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E112_E11.py.snap @@ -11,7 +11,7 @@ E11.py:9:1: E112 Expected an indented block 11 | print() | -E11.py:9:1: SyntaxError: Expected an indented block after `if` statement +E11.py:9:1: invalid-syntax: Expected an indented block after `if` statement | 7 | #: E112 8 | if False: @@ -21,7 +21,7 @@ E11.py:9:1: SyntaxError: Expected an indented block after `if` statement 11 | print() | -E11.py:12:1: SyntaxError: Unexpected indentation +E11.py:12:1: invalid-syntax: Unexpected indentation | 10 | #: E113 11 | print() @@ -31,7 +31,7 @@ E11.py:12:1: SyntaxError: Unexpected indentation 14 | mimetype = 'application/x-directory' | -E11.py:14:1: SyntaxError: Expected a statement +E11.py:14:1: invalid-syntax: Expected a statement | 12 | print() 13 | #: E114 E116 @@ -51,7 +51,7 @@ E11.py:45:1: E112 Expected an indented block 47 | if False: | -E11.py:45:1: SyntaxError: Expected an indented block after `if` statement +E11.py:45:1: invalid-syntax: Expected an indented block after `if` statement | 43 | #: E112 44 | if False: # diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E113_E11.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E113_E11.py.snap index 533d2ee8d1..af7b677a47 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E113_E11.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E113_E11.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E11.py:9:1: SyntaxError: Expected an indented block after `if` statement +E11.py:9:1: invalid-syntax: Expected an indented block after `if` statement | 7 | #: E112 8 | if False: @@ -21,7 +21,7 @@ E11.py:12:1: E113 Unexpected indentation 14 | mimetype = 'application/x-directory' | -E11.py:12:1: SyntaxError: Unexpected indentation +E11.py:12:1: invalid-syntax: Unexpected indentation | 10 | #: E113 11 | print() @@ -31,7 +31,7 @@ E11.py:12:1: SyntaxError: Unexpected indentation 14 | mimetype = 'application/x-directory' | -E11.py:14:1: SyntaxError: Expected a statement +E11.py:14:1: invalid-syntax: Expected a statement | 12 | print() 13 | #: E114 E116 @@ -41,7 +41,7 @@ E11.py:14:1: SyntaxError: Expected a statement 16 | create_date = False | -E11.py:45:1: SyntaxError: Expected an indented block after `if` statement +E11.py:45:1: invalid-syntax: Expected an indented block after `if` statement | 43 | #: E112 44 | if False: # diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E114_E11.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E114_E11.py.snap index 0ce72700a4..c607a40024 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E114_E11.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E114_E11.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E11.py:9:1: SyntaxError: Expected an indented block after `if` statement +E11.py:9:1: invalid-syntax: Expected an indented block after `if` statement | 7 | #: E112 8 | if False: @@ -11,7 +11,7 @@ E11.py:9:1: SyntaxError: Expected an indented block after `if` statement 11 | print() | -E11.py:12:1: SyntaxError: Unexpected indentation +E11.py:12:1: invalid-syntax: Unexpected indentation | 10 | #: E113 11 | print() @@ -21,7 +21,7 @@ E11.py:12:1: SyntaxError: Unexpected indentation 14 | mimetype = 'application/x-directory' | -E11.py:14:1: SyntaxError: Expected a statement +E11.py:14:1: invalid-syntax: Expected a statement | 12 | print() 13 | #: E114 E116 @@ -41,7 +41,7 @@ E11.py:15:1: E114 Indentation is not a multiple of 4 (comment) 17 | #: E116 E116 E116 | -E11.py:45:1: SyntaxError: Expected an indented block after `if` statement +E11.py:45:1: invalid-syntax: Expected an indented block after `if` statement | 43 | #: E112 44 | if False: # diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E115_E11.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E115_E11.py.snap index a8b570fb33..ac2d406eaf 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E115_E11.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E115_E11.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E11.py:9:1: SyntaxError: Expected an indented block after `if` statement +E11.py:9:1: invalid-syntax: Expected an indented block after `if` statement | 7 | #: E112 8 | if False: @@ -11,7 +11,7 @@ E11.py:9:1: SyntaxError: Expected an indented block after `if` statement 11 | print() | -E11.py:12:1: SyntaxError: Unexpected indentation +E11.py:12:1: invalid-syntax: Unexpected indentation | 10 | #: E113 11 | print() @@ -21,7 +21,7 @@ E11.py:12:1: SyntaxError: Unexpected indentation 14 | mimetype = 'application/x-directory' | -E11.py:14:1: SyntaxError: Expected a statement +E11.py:14:1: invalid-syntax: Expected a statement | 12 | print() 13 | #: E114 E116 @@ -91,7 +91,7 @@ E11.py:35:1: E115 Expected an indented block (comment) 37 | #: E117 | -E11.py:45:1: SyntaxError: Expected an indented block after `if` statement +E11.py:45:1: invalid-syntax: Expected an indented block after `if` statement | 43 | #: E112 44 | if False: # diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E116_E11.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E116_E11.py.snap index 01db13d269..fce1b92cbe 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E116_E11.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E116_E11.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E11.py:9:1: SyntaxError: Expected an indented block after `if` statement +E11.py:9:1: invalid-syntax: Expected an indented block after `if` statement | 7 | #: E112 8 | if False: @@ -11,7 +11,7 @@ E11.py:9:1: SyntaxError: Expected an indented block after `if` statement 11 | print() | -E11.py:12:1: SyntaxError: Unexpected indentation +E11.py:12:1: invalid-syntax: Unexpected indentation | 10 | #: E113 11 | print() @@ -21,7 +21,7 @@ E11.py:12:1: SyntaxError: Unexpected indentation 14 | mimetype = 'application/x-directory' | -E11.py:14:1: SyntaxError: Expected a statement +E11.py:14:1: invalid-syntax: Expected a statement | 12 | print() 13 | #: E114 E116 @@ -71,7 +71,7 @@ E11.py:26:1: E116 Unexpected indentation (comment) 28 | def start(self): | -E11.py:45:1: SyntaxError: Expected an indented block after `if` statement +E11.py:45:1: invalid-syntax: Expected an indented block after `if` statement | 43 | #: E112 44 | if False: # diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E117_E11.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E117_E11.py.snap index 65c7dd99c8..df779d24bc 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E117_E11.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E117_E11.py.snap @@ -11,7 +11,7 @@ E11.py:6:1: E117 Over-indented 8 | if False: | -E11.py:9:1: SyntaxError: Expected an indented block after `if` statement +E11.py:9:1: invalid-syntax: Expected an indented block after `if` statement | 7 | #: E112 8 | if False: @@ -21,7 +21,7 @@ E11.py:9:1: SyntaxError: Expected an indented block after `if` statement 11 | print() | -E11.py:12:1: SyntaxError: Unexpected indentation +E11.py:12:1: invalid-syntax: Unexpected indentation | 10 | #: E113 11 | print() @@ -31,7 +31,7 @@ E11.py:12:1: SyntaxError: Unexpected indentation 14 | mimetype = 'application/x-directory' | -E11.py:14:1: SyntaxError: Expected a statement +E11.py:14:1: invalid-syntax: Expected a statement | 12 | print() 13 | #: E114 E116 @@ -61,7 +61,7 @@ E11.py:42:1: E117 Over-indented 44 | if False: # | -E11.py:45:1: SyntaxError: Expected an indented block after `if` statement +E11.py:45:1: invalid-syntax: Expected an indented block after `if` statement | 43 | #: E112 44 | if False: # diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E301_E30_syntax_error.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E301_E30_syntax_error.py.snap index 5e99bc6e15..7bb80342d1 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E301_E30_syntax_error.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E301_E30_syntax_error.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E30_syntax_error.py:4:15: SyntaxError: Expected ']', found '(' +E30_syntax_error.py:4:15: invalid-syntax: Expected ']', found '(' | 2 | # parenthesis. 3 | @@ -10,7 +10,7 @@ E30_syntax_error.py:4:15: SyntaxError: Expected ']', found '(' 5 | pass | -E30_syntax_error.py:13:18: SyntaxError: Expected ')', found newline +E30_syntax_error.py:13:18: invalid-syntax: Expected ')', found newline | 12 | class Foo: 13 | def __init__( @@ -30,7 +30,7 @@ E30_syntax_error.py:15:5: E301 Expected 1 blank line, found 0 | = help: Add missing blank line -E30_syntax_error.py:18:11: SyntaxError: Expected ')', found newline +E30_syntax_error.py:18:11: invalid-syntax: Expected ')', found newline | 16 | pass 17 | @@ -41,7 +41,7 @@ E30_syntax_error.py:18:11: SyntaxError: Expected ')', found newline 21 | def top( | -E30_syntax_error.py:21:9: SyntaxError: Expected ')', found newline +E30_syntax_error.py:21:9: invalid-syntax: Expected ')', found newline | 21 | def top( | ^ diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E302_E30_syntax_error.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E302_E30_syntax_error.py.snap index 88d95e3ee9..822fb79e6b 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E302_E30_syntax_error.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E302_E30_syntax_error.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E30_syntax_error.py:4:15: SyntaxError: Expected ']', found '(' +E30_syntax_error.py:4:15: invalid-syntax: Expected ']', found '(' | 2 | # parenthesis. 3 | @@ -20,7 +20,7 @@ E30_syntax_error.py:7:1: E302 Expected 2 blank lines, found 1 | = help: Add missing blank line(s) -E30_syntax_error.py:13:18: SyntaxError: Expected ')', found newline +E30_syntax_error.py:13:18: invalid-syntax: Expected ')', found newline | 12 | class Foo: 13 | def __init__( @@ -30,7 +30,7 @@ E30_syntax_error.py:13:18: SyntaxError: Expected ')', found newline 16 | pass | -E30_syntax_error.py:18:11: SyntaxError: Expected ')', found newline +E30_syntax_error.py:18:11: invalid-syntax: Expected ')', found newline | 16 | pass 17 | @@ -41,7 +41,7 @@ E30_syntax_error.py:18:11: SyntaxError: Expected ')', found newline 21 | def top( | -E30_syntax_error.py:21:9: SyntaxError: Expected ')', found newline +E30_syntax_error.py:21:9: invalid-syntax: Expected ')', found newline | 21 | def top( | ^ diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E303_E30_syntax_error.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E303_E30_syntax_error.py.snap index f268b987e1..655694ea0a 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E303_E30_syntax_error.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E303_E30_syntax_error.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E30_syntax_error.py:4:15: SyntaxError: Expected ']', found '(' +E30_syntax_error.py:4:15: invalid-syntax: Expected ']', found '(' | 2 | # parenthesis. 3 | @@ -19,7 +19,7 @@ E30_syntax_error.py:12:1: E303 Too many blank lines (3) | = help: Remove extraneous blank line(s) -E30_syntax_error.py:13:18: SyntaxError: Expected ')', found newline +E30_syntax_error.py:13:18: invalid-syntax: Expected ')', found newline | 12 | class Foo: 13 | def __init__( @@ -29,7 +29,7 @@ E30_syntax_error.py:13:18: SyntaxError: Expected ')', found newline 16 | pass | -E30_syntax_error.py:18:11: SyntaxError: Expected ')', found newline +E30_syntax_error.py:18:11: invalid-syntax: Expected ')', found newline | 16 | pass 17 | @@ -40,7 +40,7 @@ E30_syntax_error.py:18:11: SyntaxError: Expected ')', found newline 21 | def top( | -E30_syntax_error.py:21:9: SyntaxError: Expected ')', found newline +E30_syntax_error.py:21:9: invalid-syntax: Expected ')', found newline | 21 | def top( | ^ diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E305_E30_syntax_error.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E305_E30_syntax_error.py.snap index 6d5796ccab..ed1dfa66f6 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E305_E30_syntax_error.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E305_E30_syntax_error.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E30_syntax_error.py:4:15: SyntaxError: Expected ']', found '(' +E30_syntax_error.py:4:15: invalid-syntax: Expected ']', found '(' | 2 | # parenthesis. 3 | @@ -10,7 +10,7 @@ E30_syntax_error.py:4:15: SyntaxError: Expected ']', found '(' 5 | pass | -E30_syntax_error.py:13:18: SyntaxError: Expected ')', found newline +E30_syntax_error.py:13:18: invalid-syntax: Expected ')', found newline | 12 | class Foo: 13 | def __init__( @@ -29,7 +29,7 @@ E30_syntax_error.py:18:1: E305 Expected 2 blank lines after class or function de | = help: Add missing blank line(s) -E30_syntax_error.py:18:11: SyntaxError: Expected ')', found newline +E30_syntax_error.py:18:11: invalid-syntax: Expected ')', found newline | 16 | pass 17 | @@ -40,7 +40,7 @@ E30_syntax_error.py:18:11: SyntaxError: Expected ')', found newline 21 | def top( | -E30_syntax_error.py:21:9: SyntaxError: Expected ')', found newline +E30_syntax_error.py:21:9: invalid-syntax: Expected ')', found newline | 21 | def top( | ^ diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E306_E30_syntax_error.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E306_E30_syntax_error.py.snap index 226c3ad35a..2389bcb644 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E306_E30_syntax_error.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E306_E30_syntax_error.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E30_syntax_error.py:4:15: SyntaxError: Expected ']', found '(' +E30_syntax_error.py:4:15: invalid-syntax: Expected ']', found '(' | 2 | # parenthesis. 3 | @@ -10,7 +10,7 @@ E30_syntax_error.py:4:15: SyntaxError: Expected ']', found '(' 5 | pass | -E30_syntax_error.py:13:18: SyntaxError: Expected ')', found newline +E30_syntax_error.py:13:18: invalid-syntax: Expected ')', found newline | 12 | class Foo: 13 | def __init__( @@ -20,7 +20,7 @@ E30_syntax_error.py:13:18: SyntaxError: Expected ')', found newline 16 | pass | -E30_syntax_error.py:18:11: SyntaxError: Expected ')', found newline +E30_syntax_error.py:18:11: invalid-syntax: Expected ')', found newline | 16 | pass 17 | @@ -31,7 +31,7 @@ E30_syntax_error.py:18:11: SyntaxError: Expected ')', found newline 21 | def top( | -E30_syntax_error.py:21:9: SyntaxError: Expected ')', found newline +E30_syntax_error.py:21:9: invalid-syntax: Expected ')', found newline | 21 | def top( | ^ diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501_4.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501_4.py.snap index 4893167012..2334712b50 100644 Binary files a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501_4.py.snap and b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501_4.py.snap differ diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W191_W19.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W191_W19.py.snap index ec2fd5bb5a..b1fce5b6a5 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W191_W19.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W191_W19.py.snap @@ -8,14 +8,14 @@ W19.py:1:1: W191 Indentation contains tabs 2 | multiline string with tab in it''' | -W19.py:1:1: SyntaxError: Unexpected indentation +W19.py:1:1: invalid-syntax: Unexpected indentation | 1 | '''File starts with a tab | ^^^^ 2 | multiline string with tab in it''' | -W19.py:5:1: SyntaxError: Expected a statement +W19.py:5:1: invalid-syntax: Expected a statement | 4 | #: W191 5 | if False: diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__white_space_syntax_error_compatibility.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__white_space_syntax_error_compatibility.snap index 8e10a8f07d..d78a1c3367 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__white_space_syntax_error_compatibility.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__white_space_syntax_error_compatibility.snap @@ -1,8 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs -snapshot_kind: text --- -E2_syntax_error.py:1:10: SyntaxError: Expected an expression +E2_syntax_error.py:1:10: invalid-syntax: Expected an expression | 1 | a = (1 or) | ^ diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2510_invalid_characters_syntax_error.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2510_invalid_characters_syntax_error.py.snap index 191bff373d..8ab97da102 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2510_invalid_characters_syntax_error.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2510_invalid_characters_syntax_error.py.snap @@ -11,7 +11,7 @@ invalid_characters_syntax_error.py:5:6: PLE2510 Invalid unescaped character back | = help: Replace with escape sequence -invalid_characters_syntax_error.py:7:5: SyntaxError: missing closing quote in string literal +invalid_characters_syntax_error.py:7:5: invalid-syntax: missing closing quote in string literal | 5 | b = '␈' 6 | # Unterminated string @@ -21,7 +21,7 @@ invalid_characters_syntax_error.py:7:5: SyntaxError: missing closing quote in st 9 | # Unterminated f-string | -invalid_characters_syntax_error.py:7:7: SyntaxError: Expected a statement +invalid_characters_syntax_error.py:7:7: invalid-syntax: Expected a statement | 5 | b = '␈' 6 | # Unterminated string @@ -43,7 +43,7 @@ invalid_characters_syntax_error.py:8:6: PLE2510 Invalid unescaped character back | = help: Replace with escape sequence -invalid_characters_syntax_error.py:10:7: SyntaxError: f-string: unterminated string +invalid_characters_syntax_error.py:10:7: invalid-syntax: f-string: unterminated string | 8 | b = '␈' 9 | # Unterminated f-string @@ -53,7 +53,7 @@ invalid_characters_syntax_error.py:10:7: SyntaxError: f-string: unterminated str 12 | # Implicitly concatenated | -invalid_characters_syntax_error.py:10:8: SyntaxError: Expected FStringEnd, found newline +invalid_characters_syntax_error.py:10:8: invalid-syntax: Expected FStringEnd, found newline | 8 | b = '␈' 9 | # Unterminated f-string @@ -93,7 +93,7 @@ invalid_characters_syntax_error.py:13:11: PLE2510 Invalid unescaped character ba | = help: Replace with escape sequence -invalid_characters_syntax_error.py:13:14: SyntaxError: missing closing quote in string literal +invalid_characters_syntax_error.py:13:14: invalid-syntax: missing closing quote in string literal | 11 | b = f'␈' 12 | # Implicitly concatenated @@ -101,7 +101,7 @@ invalid_characters_syntax_error.py:13:14: SyntaxError: missing closing quote in | ^^ | -invalid_characters_syntax_error.py:13:16: SyntaxError: Expected a statement +invalid_characters_syntax_error.py:13:16: invalid-syntax: Expected a statement | 11 | b = f'␈' 12 | # Implicitly concatenated diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__async_comprehension_in_sync_comprehension_notebook_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__async_comprehension_in_sync_comprehension_notebook_3.10.snap index c573573f70..b8f733bcbc 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__async_comprehension_in_sync_comprehension_notebook_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__async_comprehension_in_sync_comprehension_notebook_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -resources/test/fixtures/syntax_errors/async_comprehension.ipynb:3:5: SyntaxError: cannot use an asynchronous comprehension inside of a synchronous comprehension on Python 3.10 (syntax was added in 3.11) +resources/test/fixtures/syntax_errors/async_comprehension.ipynb:3:5: invalid-syntax: cannot use an asynchronous comprehension inside of a synchronous comprehension on Python 3.10 (syntax was added in 3.11) | 1 | async def elements(n): yield n 2 | [x async for x in elements(5)] # okay, async at top level diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_AsyncComprehensionOutsideAsyncFunction_async_in_sync_error_on_310_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_AsyncComprehensionOutsideAsyncFunction_async_in_sync_error_on_310_3.10.snap index 9fd781f021..8f0b694212 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_AsyncComprehensionOutsideAsyncFunction_async_in_sync_error_on_310_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_AsyncComprehensionOutsideAsyncFunction_async_in_sync_error_on_310_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:1:27: SyntaxError: cannot use an asynchronous comprehension inside of a synchronous comprehension on Python 3.10 (syntax was added in 3.11) +:1:27: invalid-syntax: cannot use an asynchronous comprehension inside of a synchronous comprehension on Python 3.10 (syntax was added in 3.11) | 1 | async def f(): return [[x async for x in foo(n)] for n in range(3)] | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateMatchClassAttribute_duplicate_match_class_attribute_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateMatchClassAttribute_duplicate_match_class_attribute_3.10.snap index bac3111de0..c54cffce1c 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateMatchClassAttribute_duplicate_match_class_attribute_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateMatchClassAttribute_duplicate_match_class_attribute_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:3:21: SyntaxError: attribute name `x` repeated in class pattern +:3:21: invalid-syntax: attribute name `x` repeated in class pattern | 2 | match x: 3 | case Point(x=1, x=2): diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateMatchKey_duplicate_match_key_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateMatchKey_duplicate_match_key_3.10.snap index f877e86e31..0dff722356 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateMatchKey_duplicate_match_key_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateMatchKey_duplicate_match_key_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:3:21: SyntaxError: mapping pattern checks duplicate key `'key'` +:3:21: invalid-syntax: mapping pattern checks duplicate key `'key'` | 2 | match x: 3 | case {'key': 1, 'key': 2}: diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateTypeParameter_duplicate_type_param_3.12.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateTypeParameter_duplicate_type_param_3.12.snap index 5ede497ec6..a216e0014f 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateTypeParameter_duplicate_type_param_3.12.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_DuplicateTypeParameter_duplicate_type_param_3.12.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:1:12: SyntaxError: duplicate type parameter +:1:12: invalid-syntax: duplicate type parameter | 1 | class C[T, T]: pass | ^ diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_walrus_in_return_annotation_3.12.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_walrus_in_return_annotation_3.12.snap index a09dda153f..9302f2f743 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_walrus_in_return_annotation_3.12.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_walrus_in_return_annotation_3.12.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:2:22: SyntaxError: named expression cannot be used within a generic definition +:2:22: invalid-syntax: named expression cannot be used within a generic definition | 2 | def f[T](x: int) -> (y := 3): return x | ^^^^^^ diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_from_in_base_class_3.12.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_from_in_base_class_3.12.snap index 6f71b926a1..9b53c29edd 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_from_in_base_class_3.12.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_from_in_base_class_3.12.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:2:13: SyntaxError: yield expression cannot be used within a generic definition +:2:13: invalid-syntax: yield expression cannot be used within a generic definition | 2 | class C[T]((yield from [object])): | ^^^^^^^^^^^^^^^^^^^ diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_in_type_alias_3.12.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_in_type_alias_3.12.snap index 39c220e6a1..04022d4371 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_in_type_alias_3.12.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_in_type_alias_3.12.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:2:11: SyntaxError: yield expression cannot be used within a type alias +:2:11: invalid-syntax: yield expression cannot be used within a type alias | 2 | type Y = (yield 1) | ^^^^^^^ diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_in_type_param_3.12.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_in_type_param_3.12.snap index 9f0c12aaac..77f409e139 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_in_type_param_3.12.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidExpression_invalid_expression_yield_in_type_param_3.12.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:2:12: SyntaxError: yield expression cannot be used within a TypeVar bound +:2:12: invalid-syntax: yield expression cannot be used within a TypeVar bound | 2 | type X[T: (yield 1)] = int | ^^^^^^^ diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_3.10.snap index 81bc057071..823721b5ad 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:3:12: SyntaxError: Starred expression cannot be used here +:3:12: invalid-syntax: Starred expression cannot be used here | 2 | def func(): 3 | return *x diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_for_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_for_3.10.snap index 811caf59bb..360ed91ab1 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_for_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_for_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:2:5: SyntaxError: Starred expression cannot be used here +:2:5: invalid-syntax: Starred expression cannot be used here | 2 | for *x in range(10): | ^^ diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_yield_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_yield_3.10.snap index ee1549b0cd..250f75191b 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_yield_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_InvalidStarExpression_invalid_star_expression_yield_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:3:11: SyntaxError: Starred expression cannot be used here +:3:11: invalid-syntax: Starred expression cannot be used here | 2 | def func(): 3 | yield *x diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_IrrefutableCasePattern_irrefutable_case_pattern_capture_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_IrrefutableCasePattern_irrefutable_case_pattern_capture_3.10.snap index 502f151558..f4eff967a9 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_IrrefutableCasePattern_irrefutable_case_pattern_capture_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_IrrefutableCasePattern_irrefutable_case_pattern_capture_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:3:10: SyntaxError: name capture `irrefutable` makes remaining patterns unreachable +:3:10: invalid-syntax: name capture `irrefutable` makes remaining patterns unreachable | 2 | match value: 3 | case irrefutable: diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_IrrefutableCasePattern_irrefutable_case_pattern_wildcard_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_IrrefutableCasePattern_irrefutable_case_pattern_wildcard_3.10.snap index cc54b4776b..ac8a5e593e 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_IrrefutableCasePattern_irrefutable_case_pattern_wildcard_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_IrrefutableCasePattern_irrefutable_case_pattern_wildcard_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:3:10: SyntaxError: wildcard makes remaining patterns unreachable +:3:10: invalid-syntax: wildcard makes remaining patterns unreachable | 2 | match value: 3 | case _: diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_MultipleCaseAssignment_multiple_case_assignment_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_MultipleCaseAssignment_multiple_case_assignment_3.10.snap index 6cee83489a..6fca18778a 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_MultipleCaseAssignment_multiple_case_assignment_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_MultipleCaseAssignment_multiple_case_assignment_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:3:14: SyntaxError: multiple assignments to name `a` in pattern +:3:14: invalid-syntax: multiple assignments to name `a` in pattern | 2 | match x: 3 | case [a, a]: diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_ReboundComprehensionVariable_rebound_comprehension_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_ReboundComprehensionVariable_rebound_comprehension_3.10.snap index 80fb65620a..c08764edd5 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_ReboundComprehensionVariable_rebound_comprehension_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_ReboundComprehensionVariable_rebound_comprehension_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:1:2: SyntaxError: assignment expression cannot rebind comprehension variable +:1:2: invalid-syntax: assignment expression cannot rebind comprehension variable | 1 | [x:= 2 for x in range(2)] | ^ diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_SingleStarredAssignment_single_starred_assignment_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_SingleStarredAssignment_single_starred_assignment_3.10.snap index ecc8f955d8..2295dec878 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_SingleStarredAssignment_single_starred_assignment_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_SingleStarredAssignment_single_starred_assignment_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:1:1: SyntaxError: starred assignment target must be in a list or tuple +:1:1: invalid-syntax: starred assignment target must be in a list or tuple | 1 | *a = [1, 2, 3, 4] | ^^ diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_3.10.snap index baebbdf41f..576fcb6706 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:2:1: SyntaxError: cannot assign to `__debug__` +:2:1: invalid-syntax: cannot assign to `__debug__` | 2 | __debug__ = False | ^^^^^^^^^ diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_class_type_param_3.12.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_class_type_param_3.12.snap index 44139dc6cf..7db94e4b2e 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_class_type_param_3.12.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_class_type_param_3.12.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:2:15: SyntaxError: cannot assign to `__debug__` +:2:15: invalid-syntax: cannot assign to `__debug__` | 2 | class Generic[__debug__]: | ^^^^^^^^^ diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_in_function_param_3.10.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_in_function_param_3.10.snap index 935ad56054..12e6d3d0a6 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_in_function_param_3.10.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__semantic_syntax_error_WriteToDebug_write_to_debug_in_function_param_3.10.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/linter.rs --- -:2:13: SyntaxError: cannot assign to `__debug__` +:2:13: invalid-syntax: cannot assign to `__debug__` | 2 | def process(__debug__): | ^^^^^^^^^ diff --git a/crates/ruff_wasm/src/lib.rs b/crates/ruff_wasm/src/lib.rs index 8fcb8d791b..da5c91e7b5 100644 --- a/crates/ruff_wasm/src/lib.rs +++ b/crates/ruff_wasm/src/lib.rs @@ -57,7 +57,7 @@ export interface Diagnostic { #[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] pub struct ExpandedMessage { - pub code: Option, + pub code: String, pub message: String, pub start_location: Location, pub end_location: Location, @@ -229,7 +229,7 @@ impl Workspace { let messages: Vec = diagnostics .into_iter() .map(|msg| ExpandedMessage { - code: msg.secondary_code().map(ToString::to_string), + code: msg.secondary_code_or_id().to_string(), message: msg.body().to_string(), start_location: source_code.line_column(msg.expect_range().start()).into(), end_location: source_code.line_column(msg.expect_range().end()).into(), diff --git a/crates/ruff_wasm/tests/api.rs b/crates/ruff_wasm/tests/api.rs index fb7478d3b2..8dada44a5b 100644 --- a/crates/ruff_wasm/tests/api.rs +++ b/crates/ruff_wasm/tests/api.rs @@ -27,7 +27,7 @@ fn empty_config() { "if (1, 2):\n pass", r#"{}"#, [ExpandedMessage { - code: Some(Rule::IfTuple.noqa_code().to_string()), + code: Rule::IfTuple.noqa_code().to_string(), message: "If test is a tuple, which is always `True`".to_string(), start_location: Location { row: OneIndexed::from_zero_indexed(0), @@ -50,8 +50,8 @@ fn syntax_error() { "x =\ny = 1\n", r#"{}"#, [ExpandedMessage { - code: None, - message: "SyntaxError: Expected an expression".to_string(), + code: "invalid-syntax".to_string(), + message: "Expected an expression".to_string(), start_location: Location { row: OneIndexed::from_zero_indexed(0), column: OneIndexed::from_zero_indexed(3) @@ -73,8 +73,9 @@ fn unsupported_syntax_error() { "match 2:\n case 1: ...", r#"{"target-version": "py39"}"#, [ExpandedMessage { - code: None, - message: "SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)".to_string(), + code: "invalid-syntax".to_string(), + message: "Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)" + .to_string(), start_location: Location { row: OneIndexed::from_zero_indexed(0), column: OneIndexed::from_zero_indexed(0) diff --git a/python/ruff-ecosystem/ruff_ecosystem/check.py b/python/ruff-ecosystem/ruff_ecosystem/check.py index bf8d222125..6babd762d4 100644 --- a/python/ruff-ecosystem/ruff_ecosystem/check.py +++ b/python/ruff-ecosystem/ruff_ecosystem/check.py @@ -45,7 +45,7 @@ CHECK_DIFF_LINE_RE = re.compile( ) CHECK_DIAGNOSTIC_LINE_RE = re.compile( - r"^(?P[+-])? ?(?P.*): (?P[A-Z]{1,4}[0-9]{3,4}|SyntaxError:)(?P \[\*\])? (?P.*)" + r"^(?P[+-])? ?(?P.*): (?P[A-Z]{1,4}[0-9]{3,4}|[a-z\-]+:)(?P \[\*\])? (?P.*)" ) CHECK_VIOLATION_FIX_INDICATOR = " [*]"