diff --git a/src/checks.rs b/src/checks.rs index 731bb4a602..d463f05249 100644 --- a/src/checks.rs +++ b/src/checks.rs @@ -449,9 +449,7 @@ impl CheckKind { CheckKind::FutureFeatureNotDefined(name) => { format!("future feature '{name}' is not defined") } - CheckKind::IOError(name) => { - format!("No such file or directory: `{name}`") - } + CheckKind::IOError(message) => message.clone(), CheckKind::IfTuple => "If test is a tuple, which is always `True`".to_string(), CheckKind::InvalidPrintSyntax => "use of >> is invalid with print function".to_string(), CheckKind::ImportStarNotPermitted(name) => { diff --git a/src/fs.rs b/src/fs.rs index 7b27603114..a48b3dc926 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -59,7 +59,7 @@ pub fn iter_python_files<'a>( path: &'a Path, exclude: &'a [FilePattern], extend_exclude: &'a [FilePattern], -) -> impl Iterator + 'a { +) -> impl Iterator> + 'a { // Run some checks over the provided patterns, to enable optimizations below. let has_exclude = !exclude.is_empty(); let has_extend_exclude = !extend_exclude.is_empty(); @@ -105,9 +105,10 @@ pub fn iter_python_files<'a>( } } }) - .filter_map(|entry| entry.ok()) .filter(|entry| { - (entry.depth() == 0 && !entry.file_type().is_dir()) || is_included(entry.path()) + entry.as_ref().map_or(true, |entry| { + (entry.depth() == 0 && !entry.file_type().is_dir()) || is_included(entry.path()) + }) }) } diff --git a/src/main.rs b/src/main.rs index 39cc2b372d..25529e3ccd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ extern crate core; -use std::path::PathBuf; +use std::io; +use std::path::{Path, PathBuf}; use std::process::ExitCode; use std::sync::mpsc::channel; use std::time::Instant; @@ -102,7 +103,7 @@ fn run_once( ) -> Result> { // Collect all the files to check. let start = Instant::now(); - let paths: Vec = files + let paths: Vec> = files .iter() .flat_map(|path| iter_python_files(path, &settings.exclude, &settings.extend_exclude)) .collect(); @@ -113,16 +114,33 @@ fn run_once( let mut messages: Vec = paths .par_iter() .map(|entry| { - lint_path(entry.path(), settings, &cache.into(), &autofix.into()).unwrap_or_else(|e| { - if settings.select.contains(&CheckCode::E999) { - vec![Message { - kind: CheckKind::SyntaxError(e.to_string()), - fixed: false, - location: Default::default(), - filename: entry.path().to_string_lossy().to_string(), - }] + match entry { + Ok(entry) => { + let path = entry.path(); + lint_path(path, settings, &cache.into(), &autofix.into()) + .map_err(|e| (Some(path.to_owned()), e.to_string())) + } + Err(e) => Err(( + e.path().map(Path::to_owned), + e.io_error() + .map_or_else(|| e.to_string(), io::Error::to_string), + )), + } + .unwrap_or_else(|(path, message)| { + if let Some(path) = path { + if settings.select.contains(&CheckCode::E902) { + vec![Message { + kind: CheckKind::IOError(message), + fixed: false, + location: Default::default(), + filename: path.to_string_lossy().to_string(), + }] + } else { + error!("Failed to check {}: {message}", path.to_string_lossy()); + vec![] + } } else { - error!("Failed to check {}: {e:?}", entry.path().to_string_lossy()); + error!("{message}"); vec![] } }) @@ -130,19 +148,6 @@ fn run_once( .flatten() .collect(); - if settings.select.contains(&CheckCode::E902) { - for file in files { - if !file.exists() { - messages.push(Message { - kind: CheckKind::IOError(file.to_string_lossy().to_string()), - fixed: false, - location: Default::default(), - filename: file.to_string_lossy().to_string(), - }) - } - } - } - messages.sort_unstable(); let duration = start.elapsed(); debug!("Checked files in: {:?}", duration);