mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:24:57 +00:00
Remove E999
as a rule, disallow any disablement methods for syntax error (#11901)
## Summary This PR updates the way syntax errors are handled throughout the linter. The main change is that it's now not considered as a rule which involves the following changes: * Update `Message` to be an enum with two variants - one for diagnostic message and the other for syntax error message * Provide methods on the new message enum to query information required by downstream usages This means that the syntax errors cannot be hidden / disabled via any disablement methods. These are: 1. Configuration via `select`, `ignore`, `per-file-ignores`, and their `extend-*` variants ```console $ cargo run -- check ~/playground/ruff/src/lsp.py --extend-select=E999 --no-preview --no-cache Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.10s Running `target/debug/ruff check /Users/dhruv/playground/ruff/src/lsp.py --extend-select=E999 --no-preview --no-cache` warning: Rule `E999` is deprecated and will be removed in a future release. Syntax errors will always be shown regardless of whether this rule is selected or not. /Users/dhruv/playground/ruff/src/lsp.py:1:8: F401 [*] `abc` imported but unused | 1 | import abc | ^^^ F401 2 | from pathlib import Path 3 | import os | = help: Remove unused import: `abc` ``` 3. Command-line flags via `--select`, `--ignore`, `--per-file-ignores`, and their `--extend-*` variants ```console $ cargo run -- check ~/playground/ruff/src/lsp.py --no-cache --config=~/playground/ruff/pyproject.toml Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.11s Running `target/debug/ruff check /Users/dhruv/playground/ruff/src/lsp.py --no-cache --config=/Users/dhruv/playground/ruff/pyproject.toml` warning: Rule `E999` is deprecated and will be removed in a future release. Syntax errors will always be shown regardless of whether this rule is selected or not. /Users/dhruv/playground/ruff/src/lsp.py:1:8: F401 [*] `abc` imported but unused | 1 | import abc | ^^^ F401 2 | from pathlib import Path 3 | import os | = help: Remove unused import: `abc` ``` This also means that the **output format** needs to be updated: 1. The `code`, `noqa_row`, `url` fields in the JSON output is optional (`null` for syntax errors) 2. Other formats are changed accordingly For each format, a new test case specific to syntax errors have been added. Please refer to the snapshot output for the exact format for syntax error message. The output of the `--statistics` flag will have a blank entry for syntax errors: ``` 315 F821 [ ] undefined-name 119 [ ] syntax-error 103 F811 [ ] redefined-while-unused ``` The **language server** is updated to consider the syntax errors by convert them into LSP diagnostic format separately. ### Preview There are no quick fixes provided to disable syntax errors. This will automatically work for `ruff-lsp` because the `noqa_row` field will be `null` in that case. <img width="772" alt="Screenshot 2024-06-26 at 14 57 08" src="aaac827e
-4777-4ac8-8c68-eaf9f2c36774"> Even with `noqa` comment, the syntax error is displayed: <img width="763" alt="Screenshot 2024-06-26 at 14 59 51" src="ba1afb68
-7eaf-4b44-91af-6d93246475e2"> Rule documentation page: <img width="1371" alt="Screenshot 2024-06-26 at 16 48 07" src="524f01df
-d91f-4ac0-86cc-40e76b318b24"> ## Test Plan - [x] Disablement methods via config shows a warning - [x] `select`, `extend-select` - [ ] ~`ignore`~ _doesn't show any message_ - [ ] ~`per-file-ignores`, `extend-per-file-ignores`~ _doesn't show any message_ - [x] Disablement methods via command-line flag shows a warning - [x] `--select`, `--extend-select` - [ ] ~`--ignore`~ _doesn't show any message_ - [ ] ~`--per-file-ignores`, `--extend-per-file-ignores`~ _doesn't show any message_ - [x] File with syntax errors should exit with code 1 - [x] Language server - [x] Should show diagnostics for syntax errors - [x] Should not recommend a quick fix edit for adding `noqa` comment - [x] Same for `ruff-lsp` resolves: #8447
This commit is contained in:
parent
c98d8a040f
commit
e7b49694a7
52 changed files with 1235 additions and 380 deletions
|
@ -16,6 +16,7 @@ use ruff_notebook::NotebookError;
|
|||
use ruff_python_ast::PySourceType;
|
||||
use ruff_python_codegen::Stylist;
|
||||
use ruff_python_index::Indexer;
|
||||
use ruff_python_parser::ParseError;
|
||||
use ruff_python_trivia::textwrap::dedent;
|
||||
use ruff_source_file::{Locator, SourceFileBuilder};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -26,7 +27,6 @@ use crate::linter::{check_path, LinterResult};
|
|||
use crate::message::{Emitter, EmitterContext, Message, TextEmitter};
|
||||
use crate::packaging::detect_package_root;
|
||||
use crate::registry::AsRule;
|
||||
use crate::rules::pycodestyle::rules::syntax_error;
|
||||
use crate::settings::types::UnsafeFixes;
|
||||
use crate::settings::{flags, LinterSettings};
|
||||
use crate::source_kind::SourceKind;
|
||||
|
@ -188,7 +188,7 @@ pub(crate) fn test_contents<'a>(
|
|||
|
||||
let LinterResult {
|
||||
data: fixed_diagnostics,
|
||||
error: fixed_error,
|
||||
..
|
||||
} = check_path(
|
||||
path,
|
||||
None,
|
||||
|
@ -203,25 +203,21 @@ pub(crate) fn test_contents<'a>(
|
|||
&parsed,
|
||||
);
|
||||
|
||||
if let Some(fixed_error) = fixed_error {
|
||||
if !source_has_errors {
|
||||
// Previous fix introduced a syntax error, abort
|
||||
let fixes = print_diagnostics(diagnostics, path, source_kind);
|
||||
if !parsed.is_valid() && !source_has_errors {
|
||||
// Previous fix introduced a syntax error, abort
|
||||
let fixes = print_diagnostics(diagnostics, path, source_kind);
|
||||
let syntax_errors =
|
||||
print_syntax_errors(parsed.errors(), path, &locator, &transformed);
|
||||
|
||||
let mut syntax_diagnostics = Vec::new();
|
||||
syntax_error(&mut syntax_diagnostics, &fixed_error, &locator);
|
||||
let syntax_errors = print_diagnostics(syntax_diagnostics, path, &transformed);
|
||||
|
||||
panic!(
|
||||
r#"Fixed source has a syntax error where the source document does not. This is a bug in one of the generated fixes:
|
||||
panic!(
|
||||
r#"Fixed source has a syntax error where the source document does not. This is a bug in one of the generated fixes:
|
||||
{syntax_errors}
|
||||
Last generated fixes:
|
||||
{fixes}
|
||||
Source with applied fixes:
|
||||
{}"#,
|
||||
transformed.source_code()
|
||||
);
|
||||
}
|
||||
transformed.source_code()
|
||||
);
|
||||
}
|
||||
|
||||
diagnostics = fixed_diagnostics;
|
||||
|
@ -260,11 +256,40 @@ Source with applied fixes:
|
|||
|
||||
Message::from_diagnostic(diagnostic, source_code.clone(), noqa)
|
||||
})
|
||||
.chain(
|
||||
parsed
|
||||
.errors()
|
||||
.iter()
|
||||
.map(|parse_error| {
|
||||
Message::from_parse_error(parse_error, &locator, source_code.clone())
|
||||
})
|
||||
)
|
||||
.sorted()
|
||||
.collect();
|
||||
(messages, transformed)
|
||||
}
|
||||
|
||||
fn print_syntax_errors(
|
||||
errors: &[ParseError],
|
||||
path: &Path,
|
||||
locator: &Locator,
|
||||
source: &SourceKind,
|
||||
) -> String {
|
||||
let filename = path.file_name().unwrap().to_string_lossy();
|
||||
let source_file = SourceFileBuilder::new(filename.as_ref(), source.source_code()).finish();
|
||||
|
||||
let messages: Vec<_> = errors
|
||||
.iter()
|
||||
.map(|parse_error| Message::from_parse_error(parse_error, locator, source_file.clone()))
|
||||
.collect();
|
||||
|
||||
if let Some(notebook) = source.as_ipy_notebook() {
|
||||
print_jupyter_messages(&messages, path, notebook)
|
||||
} else {
|
||||
print_messages(&messages)
|
||||
}
|
||||
}
|
||||
|
||||
fn print_diagnostics(diagnostics: Vec<Diagnostic>, path: &Path, source: &SourceKind) -> String {
|
||||
let filename = path.file_name().unwrap().to_string_lossy();
|
||||
let source_file = SourceFileBuilder::new(filename.as_ref(), source.source_code()).finish();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue