Implement E902 (IOError) (#107)

This commit is contained in:
Charlie Marsh 2022-09-05 13:15:12 -04:00 committed by GitHub
parent 45db571935
commit 1a8940f015
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 34 additions and 2 deletions

View file

@ -122,6 +122,7 @@ lint rules that are obviated by Black (e.g., stylistic rules).
| ---- | ----- | ------- |
| E402 | ModuleImportNotAtTopOfFile | Module level import not at top of file |
| E501 | LineTooLong | Line too long |
| E902 | IOError | No such file or directory: `...` |
| F401 | UnusedImport | `...` imported but unused |
| F403 | ImportStarUsage | Unable to detect undefined names |
| F541 | FStringMissingPlaceholders | f-string without any placeholders |

View file

@ -8,6 +8,7 @@ fn main() {
CheckKind::DuplicateArgumentName,
CheckKind::FStringMissingPlaceholders,
CheckKind::IfTuple,
CheckKind::IOError("...".to_string()),
CheckKind::ImportStarUsage,
CheckKind::LineTooLong,
CheckKind::ModuleImportNotAtTopOfFile,

View file

@ -4,6 +4,7 @@ exclude = ["excluded.py", "**/migrations"]
select = [
"E402",
"E501",
"E902",
"F401",
"F403",
"F541",

View file

@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
pub enum CheckCode {
E402,
E501,
E902,
F401,
F403,
F541,
@ -35,6 +36,7 @@ impl FromStr for CheckCode {
match s {
"E402" => Ok(CheckCode::E402),
"E501" => Ok(CheckCode::E501),
"E902" => Ok(CheckCode::E902),
"F401" => Ok(CheckCode::F401),
"F403" => Ok(CheckCode::F403),
"F541" => Ok(CheckCode::F541),
@ -61,6 +63,7 @@ impl CheckCode {
match self {
CheckCode::E402 => "E402",
CheckCode::E501 => "E501",
CheckCode::E902 => "E902",
CheckCode::F401 => "F401",
CheckCode::F403 => "F403",
CheckCode::F541 => "F541",
@ -85,6 +88,7 @@ impl CheckCode {
match self {
CheckCode::E402 => &LintSource::AST,
CheckCode::E501 => &LintSource::Lines,
CheckCode::E902 => &LintSource::FileSystem,
CheckCode::F401 => &LintSource::AST,
CheckCode::F403 => &LintSource::AST,
CheckCode::F541 => &LintSource::AST,
@ -109,6 +113,7 @@ impl CheckCode {
pub enum LintSource {
AST,
Lines,
FileSystem,
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
@ -117,6 +122,7 @@ pub enum CheckKind {
DefaultExceptNotLast,
DuplicateArgumentName,
FStringMissingPlaceholders,
IOError(String),
IfTuple,
ImportStarUsage,
LineTooLong,
@ -141,6 +147,7 @@ impl CheckKind {
CheckKind::DefaultExceptNotLast => "DefaultExceptNotLast",
CheckKind::DuplicateArgumentName => "DuplicateArgumentName",
CheckKind::FStringMissingPlaceholders => "FStringMissingPlaceholders",
CheckKind::IOError(_) => "IOError",
CheckKind::IfTuple => "IfTuple",
CheckKind::ImportStarUsage => "ImportStarUsage",
CheckKind::LineTooLong => "LineTooLong",
@ -165,6 +172,7 @@ impl CheckKind {
CheckKind::DefaultExceptNotLast => &CheckCode::F707,
CheckKind::DuplicateArgumentName => &CheckCode::F831,
CheckKind::FStringMissingPlaceholders => &CheckCode::F541,
CheckKind::IOError(_) => &CheckCode::E902,
CheckKind::IfTuple => &CheckCode::F634,
CheckKind::ImportStarUsage => &CheckCode::F403,
CheckKind::LineTooLong => &CheckCode::E501,
@ -197,6 +205,9 @@ impl CheckKind {
CheckKind::FStringMissingPlaceholders => {
"f-string without any placeholders".to_string()
}
CheckKind::IOError(name) => {
format!("No such file or directory: `{name}`")
}
CheckKind::IfTuple => "If test is a tuple, which is always `True`".to_string(),
CheckKind::ImportStarUsage => "Unable to detect undefined names".to_string(),
CheckKind::LineTooLong => "Line too long".to_string(),
@ -242,6 +253,7 @@ impl CheckKind {
CheckKind::DuplicateArgumentName => false,
CheckKind::FStringMissingPlaceholders => false,
CheckKind::IfTuple => false,
CheckKind::IOError(_) => false,
CheckKind::ImportStarUsage => false,
CheckKind::LineTooLong => false,
CheckKind::ModuleImportNotAtTopOfFile => false,

View file

@ -18,6 +18,7 @@ use ::ruff::logging::set_up_logging;
use ::ruff::message::Message;
use ::ruff::settings::Settings;
use ::ruff::tell_user;
use ruff::checks::CheckKind;
const CARGO_PKG_NAME: &str = env!("CARGO_PKG_NAME");
const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
@ -62,7 +63,7 @@ fn run_once(
) -> Result<Vec<Message>> {
// Collect all the files to check.
let start = Instant::now();
let files: Vec<DirEntry> = files
let paths: Vec<DirEntry> = files
.iter()
.flat_map(|path| iter_python_files(path, &settings.exclude))
.collect();
@ -70,7 +71,7 @@ fn run_once(
debug!("Identified files to lint in: {:?}", duration);
let start = Instant::now();
let mut messages: Vec<Message> = files
let mut messages: Vec<Message> = paths
.par_iter()
.map(|entry| {
lint_path(entry.path(), settings, &cache.into(), &autofix.into()).unwrap_or_else(|e| {
@ -80,6 +81,20 @@ 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);

View file

@ -239,6 +239,7 @@ other-attribute = 1
select: Some(BTreeSet::from([
CheckCode::E402,
CheckCode::E501,
CheckCode::E902,
CheckCode::F401,
CheckCode::F403,
CheckCode::F541,

View file

@ -46,6 +46,7 @@ impl Settings {
BTreeSet::from([
CheckCode::E402,
CheckCode::E501,
CheckCode::E902,
CheckCode::F401,
CheckCode::F403,
CheckCode::F541,