From 78e5fe0a51fcbb1456d54c65b4632f60c268e389 Mon Sep 17 00:00:00 2001 From: Brent Westbrook <36778786+ntBre@users.noreply.github.com> Date: Tue, 5 Aug 2025 09:56:18 -0400 Subject: [PATCH] Allow hiding the diagnostic severity in `ruff_db` (#19644) ## Summary This PR is a spin-off from https://github.com/astral-sh/ruff/pull/19415. It enables replacing the severity and lint name in a ty-style diagnostic: ``` error[unused-import]: `os` imported but unused ``` with the noqa code and optional fix availability icon for a Ruff diagnostic: ``` F401 [*] `os` imported but unused F821 Undefined name `a` ``` or nothing at all for a Ruff syntax error: ``` SyntaxError: Expected one or more symbol names after import ``` Ruff adds the `SyntaxError` prefix to these messages manually. Initially (d912458), I just passed a `hide_severity` flag through a bunch of calls to get it into `annotate-snippets`, but after looking at it again today, I think reusing the `None` severity/level gave a nicer result. As I note in a lengthy code comment, I think all of this code should be temporary and reverted when Ruff gets real severities, so hopefully it's okay if it feels a little hacky. I think the main visible downside of this approach is that we can't style the asterisk in the fix availabilty icon in cyan, as in Ruff's current output. It's part of the message in this PR and any styling gets overwritten in `annotate-snippets`. image Hmm, I guess reusing `Level::None` also means the `F401` isn't red anymore. Maybe my initial approach was better after all. In any case, the rest of the PR should be basically the same, it just depends how we want to toggle the severity. ## Test Plan New `ruff_db` tests. These snapshots should be compared to the two tests just above them (`hide_severity_output` vs `output` and `hide_severity_syntax_errors` against `syntax_errors`). --- crates/ruff/tests/integration_test.rs | 8 +- crates/ruff/tests/lint.rs | 20 ++-- .../snapshots/lint__output_format_azure.snap | 2 +- .../lint__output_format_concise.snap | 2 +- .../snapshots/lint__output_format_full.snap | 2 +- .../snapshots/lint__output_format_github.snap | 2 +- .../lint__output_format_grouped.snap | 2 +- .../lint__output_format_json-lines.snap | 2 +- .../snapshots/lint__output_format_json.snap | 4 +- .../snapshots/lint__output_format_junit.snap | 2 +- .../snapshots/lint__output_format_pylint.snap | 2 +- .../snapshots/lint__output_format_rdjson.snap | 2 +- .../snapshots/lint__output_format_sarif.snap | 4 +- .../src/renderer/display_list.rs | 94 +++++++++++++++--- crates/ruff_annotate_snippets/src/snippet.rs | 11 ++ crates/ruff_db/src/diagnostic/mod.rs | 10 ++ crates/ruff_db/src/diagnostic/render.rs | 54 ++++++++-- crates/ruff_db/src/diagnostic/render/azure.rs | 6 +- .../ruff_db/src/diagnostic/render/concise.rs | 14 ++- crates/ruff_db/src/diagnostic/render/full.rs | 70 ++++++++++++- crates/ruff_db/src/diagnostic/render/json.rs | 12 +-- ...__render__azure__tests__syntax_errors.snap | 4 +- ...c__render__json__tests__syntax_errors.snap | 8 +- ...der__json_lines__tests__syntax_errors.snap | 4 +- ...__render__junit__tests__syntax_errors.snap | 4 +- ..._render__pylint__tests__syntax_errors.snap | 4 +- ..._render__rdjson__tests__syntax_errors.snap | 4 +- crates/ruff_linter/src/message/github.rs | 8 +- crates/ruff_linter/src/message/mod.rs | 9 +- crates/ruff_linter/src/message/sarif.rs | 44 +++++++- ...message__github__tests__syntax_errors.snap | 5 +- ...essage__grouped__tests__syntax_errors.snap | 5 +- ...__message__text__tests__syntax_errors.snap | 4 +- crates/ruff_linter/src/message/text.rs | 7 +- ..._commas__tests__COM81_syntax_error.py.snap | 4 +- ...tests__preview__COM81_syntax_error.py.snap | 4 +- ...at__tests__ISC001_ISC_syntax_error.py.snap | 28 +++--- ...at__tests__ISC002_ISC_syntax_error.py.snap | 28 +++--- ...ules__pycodestyle__tests__E111_E11.py.snap | 8 +- ...ules__pycodestyle__tests__E112_E11.py.snap | 8 +- ...ules__pycodestyle__tests__E113_E11.py.snap | 8 +- ...ules__pycodestyle__tests__E114_E11.py.snap | 8 +- ...ules__pycodestyle__tests__E115_E11.py.snap | 8 +- ...ules__pycodestyle__tests__E116_E11.py.snap | 8 +- ...ules__pycodestyle__tests__E117_E11.py.snap | 8 +- ...tyle__tests__E301_E30_syntax_error.py.snap | 8 +- ...tyle__tests__E302_E30_syntax_error.py.snap | 8 +- ...tyle__tests__E303_E30_syntax_error.py.snap | 8 +- ...tyle__tests__E305_E30_syntax_error.py.snap | 8 +- ...tyle__tests__E306_E30_syntax_error.py.snap | 8 +- ...s__pycodestyle__tests__E501_E501_4.py.snap | Bin 8943 -> 9024 bytes ...ules__pycodestyle__tests__W191_W19.py.snap | 4 +- ...hite_space_syntax_error_compatibility.snap | 3 +- ...10_invalid_characters_syntax_error.py.snap | 12 +-- ...n_in_sync_comprehension_notebook_3.10.snap | 2 +- ...ction_async_in_sync_error_on_310_3.10.snap | 2 +- ..._duplicate_match_class_attribute_3.10.snap | 2 +- ...cateMatchKey_duplicate_match_key_3.10.snap | 2 +- ...peParameter_duplicate_type_param_3.12.snap | 2 +- ...sion_walrus_in_return_annotation_3.12.snap | 2 +- ...ression_yield_from_in_base_class_3.12.snap | 2 +- ...d_expression_yield_in_type_alias_3.12.snap | 2 +- ...d_expression_yield_in_type_param_3.12.snap | 2 +- ...pression_invalid_star_expression_3.10.snap | 2 +- ...sion_invalid_star_expression_for_3.10.snap | 2 +- ...on_invalid_star_expression_yield_3.10.snap | 2 +- ...irrefutable_case_pattern_capture_3.10.snap | 2 +- ...rrefutable_case_pattern_wildcard_3.10.snap | 2 +- ...ignment_multiple_case_assignment_3.10.snap | 2 +- ...onVariable_rebound_comprehension_3.10.snap | 2 +- ...gnment_single_starred_assignment_3.10.snap | 2 +- ...rror_WriteToDebug_write_to_debug_3.10.snap | 2 +- ..._write_to_debug_class_type_param_3.12.snap | 2 +- ...write_to_debug_in_function_param_3.10.snap | 2 +- crates/ruff_wasm/src/lib.rs | 4 +- crates/ruff_wasm/tests/api.rs | 11 +- python/ruff-ecosystem/ruff_ecosystem/check.py | 2 +- 77 files changed, 448 insertions(+), 223 deletions(-) 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 4893167012931039fd3596ea068a84e4652bc5dc..2334712b503a0c53388921b78d241c6e69ab7717 100644 GIT binary patch literal 9024 zcmeI$&2ED*3;^Jsc?wHAQ-1ohm3y`O9-vhQX^TbyC1EO3AAVUWO2*8Ja-F&05Szj$ zR2+QY_hi+GlqZl1rnn45b2#jayi{BSQlxrZ=%aO;RvDM7EqHLQvbm6+uWPrfFxoHY zb(_RV{G32uezGFZeA$+YT@u({YMv^d0V{!DYQd$zgF zPD<4>34&v;PR;u~t5FRUf>B*}q}>0}%0BlHWMkUHNs%2({a_b>M&UP z1ZDxbh8Qe$madvs9R^GNrUm30VzAVOx@uZ=7%cUs7LaR*!BWTSs%h0>u=HWh0&)!z m*eDEXh2ZLG>QGr)dl?|-2$iM9m$RoSL}h99Wq_QcPWB7qT#MiU literal 8943 zcmeI$OK-w33;#mJ2mu5(Ut9hde~ zMV-cR92wQ=QWj8ZVWmlQx8HB;s*-p|Z#BYg(#PB8=6dj?M9UZAoQJH(XJcXR|cQhZBjB0mErVQetu&LQHN`dfk21 z-`a;ozjp%TW3##5Dl%Hk9*o|Vg{~QNZck^b;LRCt9L&v7Pu_y@T%z$g zg|}q9aWFSS;XS?=_&?7TbLJG@8$WrDkY`Hatr*WE=A;O`WzKkxkatS)akJtjLrKby z`xQjw4JbcuS-fN@N%?Wtf{45U<;RVSmkcEdzg5PsUt|;>P^#S2ggfF2N|nEAVWaSf zQsoXZ+!0q$s@zv%qwt7Q;%KIy1^h9uD{Q=cOY;phq 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 = " [*]"