From 97e9d3c54fa791ae44d56e7da32f8e8f6a2dc10e Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Fri, 29 Dec 2023 18:26:57 -0400 Subject: [PATCH] Use `Display` for formatter parse errors (#9316) ## Summary This helps a bit with (but does not close) the issues described in https://github.com/astral-sh/ruff/issues/9311. E.g., now, we at least see: `error: Failed to format main.py: source contains syntax errors: invalid syntax. Got unexpected token '=' at byte offset 20`. --- crates/ruff_cli/src/commands/format.rs | 2 ++ crates/ruff_cli/tests/format.rs | 26 ++++++++++++++++++++++++ crates/ruff_python_formatter/src/lib.rs | 4 ++-- crates/ruff_python_parser/src/lexer.rs | 27 +++++++++++++++++++++++++ crates/ruff_python_parser/src/parser.rs | 6 ------ 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/crates/ruff_cli/src/commands/format.rs b/crates/ruff_cli/src/commands/format.rs index 2b9144ad5b979..334dda8ae3165 100644 --- a/crates/ruff_cli/src/commands/format.rs +++ b/crates/ruff_cli/src/commands/format.rs @@ -408,11 +408,13 @@ pub(crate) fn format_source( pub(crate) enum FormatResult { /// The file was formatted. Formatted, + /// The file was formatted, [`SourceKind`] contains the formatted code Diff { unformatted: SourceKind, formatted: SourceKind, }, + /// The file was unchanged, as the formatted contents matched the existing contents. Unchanged, diff --git a/crates/ruff_cli/tests/format.rs b/crates/ruff_cli/tests/format.rs index 09d05d12b0c76..b4f175a34808d 100644 --- a/crates/ruff_cli/tests/format.rs +++ b/crates/ruff_cli/tests/format.rs @@ -328,6 +328,32 @@ OTHER = "OTHER" Ok(()) } +#[test] +fn syntax_error() -> Result<()> { + let tempdir = TempDir::new()?; + + fs::write( + tempdir.path().join("main.py"), + r#" +from module import = +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .current_dir(tempdir.path()) + .args(["format", "--no-cache", "--isolated", "--check"]) + .arg("main.py"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Failed to format main.py: source contains syntax errors: invalid syntax. Got unexpected token '=' at byte offset 20 + "###); + + Ok(()) +} + #[test] fn messages() -> Result<()> { let tempdir = TempDir::new()?; diff --git a/crates/ruff_python_formatter/src/lib.rs b/crates/ruff_python_formatter/src/lib.rs index 5b7f4ff29d80f..34c89ff52d021 100644 --- a/crates/ruff_python_formatter/src/lib.rs +++ b/crates/ruff_python_formatter/src/lib.rs @@ -108,9 +108,9 @@ where #[derive(Error, Debug)] pub enum FormatModuleError { - #[error("source contains syntax errors: {0:?}")] + #[error("source contains syntax errors: {0}")] LexError(LexicalError), - #[error("source contains syntax errors: {0:?}")] + #[error("source contains syntax errors: {0}")] ParseError(ParseError), #[error(transparent)] FormatError(#[from] FormatError), diff --git a/crates/ruff_python_parser/src/lexer.rs b/crates/ruff_python_parser/src/lexer.rs index 180c2839fec2b..eb2a1f73f1521 100644 --- a/crates/ruff_python_parser/src/lexer.rs +++ b/crates/ruff_python_parser/src/lexer.rs @@ -1308,6 +1308,31 @@ impl LexicalError { } } +impl std::ops::Deref for LexicalError { + type Target = LexicalErrorType; + + fn deref(&self) -> &Self::Target { + &self.error + } +} + +impl std::error::Error for LexicalError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + Some(&self.error) + } +} + +impl std::fmt::Display for LexicalError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + "{} at byte offset {}", + &self.error, + u32::from(self.location) + ) + } +} + /// Represents the different types of errors that can occur during lexing. #[derive(Debug, Clone, PartialEq)] pub enum LexicalErrorType { @@ -1350,6 +1375,8 @@ pub enum LexicalErrorType { OtherError(String), } +impl std::error::Error for LexicalErrorType {} + impl std::fmt::Display for LexicalErrorType { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { diff --git a/crates/ruff_python_parser/src/parser.rs b/crates/ruff_python_parser/src/parser.rs index 26603ca3dda4e..1aeffba8fcd94 100644 --- a/crates/ruff_python_parser/src/parser.rs +++ b/crates/ruff_python_parser/src/parser.rs @@ -305,12 +305,6 @@ impl fmt::Display for ParseError { } } -impl ParseError { - pub fn error(self) -> ParseErrorType { - self.error - } -} - /// Represents the different types of errors that can occur during parsing. #[derive(Debug, PartialEq)] pub enum ParseErrorType {