Skip to content

Commit

Permalink
Update to the new rule architecture (#4589)
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanPlasse committed May 24, 2023
1 parent fcdc7bd commit 4233f6e
Show file tree
Hide file tree
Showing 108 changed files with 2,741 additions and 2,373 deletions.
32 changes: 14 additions & 18 deletions crates/ruff/src/checkers/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use crate::fs::relativize_path;
use crate::importer::Importer;
use crate::noqa::NoqaMapping;
use crate::registry::{AsRule, Rule};
use crate::rules::flake8_builtins::rules::AnyShadowing;
use crate::rules::flake8_builtins::helpers::AnyShadowing;
use crate::rules::{
flake8_2020, flake8_annotations, flake8_async, flake8_bandit, flake8_blind_except,
flake8_boolean_trap, flake8_bugbear, flake8_builtins, flake8_comprehensions, flake8_datetimez,
Expand Down Expand Up @@ -894,7 +894,7 @@ where

// flake8_tidy_imports
if self.enabled(Rule::BannedApi) {
flake8_tidy_imports::banned_api::name_or_parent_is_banned(
flake8_tidy_imports::rules::name_or_parent_is_banned(
self,
&alias.name,
alias,
Expand Down Expand Up @@ -1057,15 +1057,13 @@ where
if let Some(module) =
helpers::resolve_imported_module_path(level, module, self.module_path)
{
flake8_tidy_imports::banned_api::name_or_parent_is_banned(
self, &module, stmt,
);
flake8_tidy_imports::rules::name_or_parent_is_banned(self, &module, stmt);

for alias in names {
if &alias.name == "*" {
continue;
}
flake8_tidy_imports::banned_api::name_is_banned(
flake8_tidy_imports::rules::name_is_banned(
self,
format!("{module}.{}", alias.name),
alias,
Expand Down Expand Up @@ -1179,16 +1177,14 @@ where
}

if self.enabled(Rule::RelativeImports) {
if let Some(diagnostic) =
flake8_tidy_imports::relative_imports::banned_relative_import(
self,
stmt,
level,
module,
self.module_path,
self.settings.flake8_tidy_imports.ban_relative_imports,
)
{
if let Some(diagnostic) = flake8_tidy_imports::rules::banned_relative_import(
self,
stmt,
level,
module,
self.module_path,
self.settings.flake8_tidy_imports.ban_relative_imports,
) {
self.diagnostics.push(diagnostic);
}
}
Expand Down Expand Up @@ -2438,7 +2434,7 @@ where
flake8_2020::rules::name_or_attribute(self, expr);
}
if self.enabled(Rule::BannedApi) {
flake8_tidy_imports::banned_api::banned_attribute_access(self, expr);
flake8_tidy_imports::rules::banned_attribute_access(self, expr);
}
if self.enabled(Rule::PrivateMemberAccess) {
flake8_self::rules::private_member_access(self, expr);
Expand Down Expand Up @@ -3024,7 +3020,7 @@ where
Rule::BuiltinOpen,
Rule::PyPath,
]) {
flake8_use_pathlib::helpers::replaceable_by_pathlib(self, func);
flake8_use_pathlib::rules::replaceable_by_pathlib(self, func);
}

// numpy
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff/src/flake8_to_ruff/converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::rules::flake8_pytest_style::types::{
ParametrizeNameType, ParametrizeValuesRowType, ParametrizeValuesType,
};
use crate::rules::flake8_quotes::settings::Quote;
use crate::rules::flake8_tidy_imports::relative_imports::Strictness;
use crate::rules::flake8_tidy_imports::settings::Strictness;
use crate::rules::pydocstyle::settings::Convention;
use crate::rules::{
flake8_annotations, flake8_bugbear, flake8_builtins, flake8_errmsg, flake8_pytest_style,
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@ ruff_macros::register_rules!(
// mccabe
rules::mccabe::rules::ComplexStructure,
// flake8-tidy-imports
rules::flake8_tidy_imports::banned_api::BannedApi,
rules::flake8_tidy_imports::relative_imports::RelativeImports,
rules::flake8_tidy_imports::rules::BannedApi,
rules::flake8_tidy_imports::rules::RelativeImports,
// flake8-return
rules::flake8_return::rules::UnnecessaryReturnNone,
rules::flake8_return::rules::ImplicitReturnValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ruff_python_ast::source_code::{Indexer, Locator};
use crate::registry::Rule;
use crate::settings::Settings;

use super::detection::comment_contains_code;
use super::super::detection::comment_contains_code;

/// ## What it does
/// Checks for commented-out Python code.
Expand Down
3 changes: 3 additions & 0 deletions crates/ruff/src/rules/eradicate/rules/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub(crate) use commented_out_code::{commented_out_code, CommentedOutCode};

mod commented_out_code;
8 changes: 8 additions & 0 deletions crates/ruff/src/rules/flake8_2020/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use ruff_python_semantic::model::SemanticModel;
use rustpython_parser::ast::Expr;

pub(super) fn is_sys(model: &SemanticModel, expr: &Expr, target: &str) -> bool {
model
.resolve_call_path(expr)
.map_or(false, |call_path| call_path.as_slice() == ["sys", target])
}
1 change: 1 addition & 0 deletions crates/ruff/src/rules/flake8_2020/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Rules from [flake8-2020](https://pypi.org/project/flake8-2020/).
mod helpers;
pub(crate) mod rules;

#[cfg(test)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,11 @@ use rustpython_parser::ast::{self, Cmpop, Constant, Expr, Ranged};

use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_semantic::model::SemanticModel;

use crate::checkers::ast::Checker;
use crate::registry::Rule;

#[violation]
pub struct SysVersionSlice3;

impl Violation for SysVersionSlice3 {
#[derive_message_formats]
fn message(&self) -> String {
format!("`sys.version[:3]` referenced (python3.10), use `sys.version_info`")
}
}

#[violation]
pub struct SysVersion2;

impl Violation for SysVersion2 {
#[derive_message_formats]
fn message(&self) -> String {
format!("`sys.version[2]` referenced (python3.10), use `sys.version_info`")
}
}
use super::super::helpers::is_sys;

#[violation]
pub struct SysVersionCmpStr3;
Expand All @@ -48,16 +29,6 @@ impl Violation for SysVersionInfo0Eq3 {
}
}

#[violation]
pub struct SixPY3;

impl Violation for SixPY3 {
#[derive_message_formats]
fn message(&self) -> String {
format!("`six.PY3` referenced (python4), use `not six.PY2`")
}
}

#[violation]
pub struct SysVersionInfo1CmpInt;

Expand All @@ -84,16 +55,6 @@ impl Violation for SysVersionInfoMinorCmpInt {
}
}

#[violation]
pub struct SysVersion0;

impl Violation for SysVersion0 {
#[derive_message_formats]
fn message(&self) -> String {
format!("`sys.version[0]` referenced (python10), use `sys.version_info`")
}
}

#[violation]
pub struct SysVersionCmpStr10;

Expand All @@ -104,69 +65,6 @@ impl Violation for SysVersionCmpStr10 {
}
}

#[violation]
pub struct SysVersionSlice1;

impl Violation for SysVersionSlice1 {
#[derive_message_formats]
fn message(&self) -> String {
format!("`sys.version[:1]` referenced (python10), use `sys.version_info`")
}
}

fn is_sys(model: &SemanticModel, expr: &Expr, target: &str) -> bool {
model
.resolve_call_path(expr)
.map_or(false, |call_path| call_path.as_slice() == ["sys", target])
}

/// YTT101, YTT102, YTT301, YTT303
pub(crate) fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
if is_sys(checker.semantic_model(), value, "version") {
match slice {
Expr::Slice(ast::ExprSlice {
lower: None,
upper: Some(upper),
step: None,
range: _,
}) => {
if let Expr::Constant(ast::ExprConstant {
value: Constant::Int(i),
..
}) = upper.as_ref()
{
if *i == BigInt::from(1) && checker.enabled(Rule::SysVersionSlice1) {
checker
.diagnostics
.push(Diagnostic::new(SysVersionSlice1, value.range()));
} else if *i == BigInt::from(3) && checker.enabled(Rule::SysVersionSlice3) {
checker
.diagnostics
.push(Diagnostic::new(SysVersionSlice3, value.range()));
}
}
}

Expr::Constant(ast::ExprConstant {
value: Constant::Int(i),
..
}) => {
if *i == BigInt::from(2) && checker.enabled(Rule::SysVersion2) {
checker
.diagnostics
.push(Diagnostic::new(SysVersion2, value.range()));
} else if *i == BigInt::from(0) && checker.enabled(Rule::SysVersion0) {
checker
.diagnostics
.push(Diagnostic::new(SysVersion0, value.range()));
}
}

_ => {}
}
}
}

/// YTT103, YTT201, YTT203, YTT204, YTT302
pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &[Expr]) {
match left {
Expand Down Expand Up @@ -257,16 +155,3 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], compara
}
}
}

/// YTT202
pub(crate) fn name_or_attribute(checker: &mut Checker, expr: &Expr) {
if checker
.semantic_model()
.resolve_call_path(expr)
.map_or(false, |call_path| call_path.as_slice() == ["six", "PY3"])
{
checker
.diagnostics
.push(Diagnostic::new(SixPY3, expr.range()));
}
}
12 changes: 12 additions & 0 deletions crates/ruff/src/rules/flake8_2020/rules/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pub(crate) use compare::{
compare, SysVersionCmpStr10, SysVersionCmpStr3, SysVersionInfo0Eq3, SysVersionInfo1CmpInt,
SysVersionInfoMinorCmpInt,
};
pub(crate) use name_or_attribute::{name_or_attribute, SixPY3};
pub(crate) use subscript::{
subscript, SysVersion0, SysVersion2, SysVersionSlice1, SysVersionSlice3,
};

mod compare;
mod name_or_attribute;
mod subscript;
29 changes: 29 additions & 0 deletions crates/ruff/src/rules/flake8_2020/rules/name_or_attribute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use rustpython_parser::ast::{Expr, Ranged};

use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

use crate::checkers::ast::Checker;

#[violation]
pub struct SixPY3;

impl Violation for SixPY3 {
#[derive_message_formats]
fn message(&self) -> String {
format!("`six.PY3` referenced (python4), use `not six.PY2`")
}
}

/// YTT202
pub(crate) fn name_or_attribute(checker: &mut Checker, expr: &Expr) {
if checker
.semantic_model()
.resolve_call_path(expr)
.map_or(false, |call_path| call_path.as_slice() == ["six", "PY3"])
{
checker
.diagnostics
.push(Diagnostic::new(SixPY3, expr.range()));
}
}
Loading

0 comments on commit 4233f6e

Please sign in to comment.