This commit is contained in:
Charlie Marsh 2023-05-21 14:52:39 -04:00
parent df3b95a73d
commit e9fc63331a
22 changed files with 78 additions and 81 deletions

View File

@ -35,7 +35,7 @@ use ruff_python_stdlib::builtins::{BUILTINS, MAGIC_GLOBALS};
use ruff_python_stdlib::path::is_python_stub_file;
use crate::checkers::ast::deferred::Deferred;
use crate::checkers::ast::traits::RegisteredAstRule;
use crate::checkers::ast::traits::RegisteredRule;
use crate::docstrings::extraction::ExtractionTarget;
use crate::docstrings::Docstring;
use crate::fs::relativize_path;
@ -80,7 +80,7 @@ pub(crate) struct Checker<'a> {
// Check-specific state.
pub(crate) flake8_bugbear_seen: Vec<&'a Expr>,
// Dispatchers
call_rules: Vec<RegisteredAstRule<ast::ExprCall>>,
call_rules: Vec<RegisteredRule<ast::ExprCall>>,
}
pub(crate) struct RuleContext<'a> {
@ -123,18 +123,18 @@ impl<'a> Checker<'a> {
deletions: FxHashSet::default(),
flake8_bugbear_seen: Vec::default(),
call_rules: [
RegisteredAstRule::new::<flake8_django::rules::DjangoLocalsInRenderFunction>(),
RegisteredAstRule::new::<pyupgrade::rules::DeprecatedUnittestAlias>(),
RegisteredAstRule::new::<pyupgrade::rules::SuperCallWithParameters>(),
RegisteredAstRule::new::<pyupgrade::rules::UnnecessaryEncodeUTF8>(),
RegisteredAstRule::new::<pyupgrade::rules::RedundantOpenModes>(),
RegisteredAstRule::new::<pyupgrade::rules::NativeLiterals>(),
RegisteredAstRule::new::<pyupgrade::rules::OpenAlias>(),
RegisteredAstRule::new::<pyupgrade::rules::ReplaceUniversalNewlines>(),
RegisteredAstRule::new::<pyupgrade::rules::ReplaceStdoutStderr>(),
RegisteredAstRule::new::<pyupgrade::rules::OSErrorAlias>(),
RegisteredAstRule::new::<pyupgrade::rules::NonPEP604Isinstance>(),
RegisteredAstRule::new::<pyupgrade::rules::TypeOfPrimitive>(),
RegisteredRule::new::<flake8_django::rules::DjangoLocalsInRenderFunction>(),
RegisteredRule::new::<pyupgrade::rules::DeprecatedUnittestAlias>(),
RegisteredRule::new::<pyupgrade::rules::SuperCallWithParameters>(),
RegisteredRule::new::<pyupgrade::rules::UnnecessaryEncodeUTF8>(),
RegisteredRule::new::<pyupgrade::rules::RedundantOpenModes>(),
RegisteredRule::new::<pyupgrade::rules::NativeLiterals>(),
RegisteredRule::new::<pyupgrade::rules::OpenAlias>(),
RegisteredRule::new::<pyupgrade::rules::ReplaceUniversalNewlines>(),
RegisteredRule::new::<pyupgrade::rules::ReplaceStdoutStderr>(),
RegisteredRule::new::<pyupgrade::rules::OSErrorAlias>(),
RegisteredRule::new::<pyupgrade::rules::NonPEP604Isinstance>(),
RegisteredRule::new::<pyupgrade::rules::TypeOfPrimitive>(),
]
.into_iter()
.filter(|rule| rule.enabled(settings))
@ -143,6 +143,7 @@ impl<'a> Checker<'a> {
}
}
// TODO(charlie): Remove these methods from `Checker`, use the immutable `RuleContext` everywhere.
impl<'a> RuleContext<'a> {
/// Return `true` if a patch should be generated under the given autofix
/// `Mode`.
@ -2632,7 +2633,7 @@ where
pandas_vet::rules::attr(self, attr, value, expr);
}
Expr::Call(call) => {
let immutable_checker = RuleContext {
let context = RuleContext {
settings: self.settings,
locator: self.locator,
stylist: self.stylist,
@ -2640,9 +2641,10 @@ where
ctx: &self.ctx,
};
for rule in &self.call_rules {
rule.run(&mut self.diagnostics, &immutable_checker, call);
rule.run(&mut self.diagnostics, &context, call);
}
// Destructure for the rest of the rules, for now.
let ast::ExprCall {
func,
args,

View File

@ -5,7 +5,7 @@ use crate::registry::Rule;
use crate::settings::Settings;
/// Trait for a lint rule that can be run on an AST node of type `T`.
pub(crate) trait AstAnalyzer<T>: Sized {
pub(crate) trait Analyzer<T>: Sized {
/// The [`Rule`] that this analyzer implements.
fn rule() -> Rule;
@ -14,13 +14,13 @@ pub(crate) trait AstAnalyzer<T>: Sized {
}
/// Internal representation of a single [`Rule`] that can be run on an AST node of type `T`.
pub(super) struct RegisteredAstRule<T> {
pub(super) struct RegisteredRule<T> {
rule: Rule,
run: Run<T>,
run: Executor<T>,
}
impl<T> RegisteredAstRule<T> {
pub(super) fn new<R: AstAnalyzer<T> + 'static>() -> Self {
impl<T> RegisteredRule<T> {
pub(super) fn new<R: Analyzer<T> + 'static>() -> Self {
Self {
rule: R::rule(),
run: R::run,
@ -38,5 +38,5 @@ impl<T> RegisteredAstRule<T> {
}
}
/// Executor for an [`AstAnalyzer`] as a generic function pointer.
type Run<T> = fn(diagnostics: &mut Vec<Diagnostic>, checker: &RuleContext, node: &T);
/// Executor for an [`Analyzer`] as a generic function pointer.
type Executor<T> = fn(diagnostics: &mut Vec<Diagnostic>, checker: &RuleContext, node: &T);

View File

@ -5,7 +5,6 @@
//!
//! [Ruff]: https://github.com/charliermarsh/ruff
pub use codes::{Pyupgrade, RuleCodePrefix};
pub use ruff_python_ast::source_code::round_trip;
pub use rule_selector::RuleSelector;
pub use rules::pycodestyle::rules::IOError;

View File

@ -3,7 +3,7 @@ use rustpython_parser::ast::{self, Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::RuleContext;
use crate::registry::Rule;
@ -45,7 +45,7 @@ impl Violation for DjangoLocalsInRenderFunction {
}
/// DJ003
impl AstAnalyzer<ast::ExprCall> for DjangoLocalsInRenderFunction {
impl Analyzer<ast::ExprCall> for DjangoLocalsInRenderFunction {
fn rule() -> Rule {
Rule::DjangoLocalsInRenderFunction
}

View File

@ -1,8 +1,6 @@
pub(crate) use all_with_model_form::{all_with_model_form, DjangoAllWithModelForm};
pub(crate) use exclude_with_model_form::{exclude_with_model_form, DjangoExcludeWithModelForm};
pub(crate) use locals_in_render_function::{
DjangoLocalsInRenderFunction,
};
pub(crate) use locals_in_render_function::DjangoLocalsInRenderFunction;
pub(crate) use model_without_dunder_str::{model_without_dunder_str, DjangoModelWithoutDunderStr};
pub(crate) use non_leading_receiver_decorator::{
non_leading_receiver_decorator, DjangoNonLeadingReceiverDecorator,

View File

@ -5,6 +5,7 @@ use rustpython_parser::ast::{self, Constant, Expr, ExprContext, Keyword, Ranged,
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::source_code::Generator;
use ruff_python_stdlib::identifiers::is_identifier;

View File

@ -5,6 +5,7 @@ use rustpython_parser::ast::{self, Constant, Expr, ExprContext, Keyword, Ranged,
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::source_code::Generator;
use ruff_python_stdlib::identifiers::is_identifier;

View File

@ -5,7 +5,7 @@ use rustpython_parser::ast::{self, Expr};
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::RuleContext;
use crate::registry::{AsRule, Rule};
@ -28,7 +28,7 @@ impl AlwaysAutofixableViolation for DeprecatedUnittestAlias {
}
}
impl AstAnalyzer<ast::ExprCall> for DeprecatedUnittestAlias {
impl Analyzer<ast::ExprCall> for DeprecatedUnittestAlias {
fn rule() -> Rule {
Rule::DeprecatedUnittestAlias
}

View File

@ -10,7 +10,7 @@ pub(crate) use deprecated_import::{deprecated_import, DeprecatedImport};
pub(crate) use deprecated_mock_import::{
deprecated_mock_attribute, deprecated_mock_import, DeprecatedMockImport,
};
pub(crate) use deprecated_unittest_alias::{DeprecatedUnittestAlias};
pub(crate) use deprecated_unittest_alias::DeprecatedUnittestAlias;
pub(crate) use extraneous_parentheses::{extraneous_parentheses, ExtraneousParentheses};
pub(crate) use f_strings::{f_strings, FString};
pub(crate) use format_literals::{format_literals, FormatLiterals};
@ -20,31 +20,29 @@ pub(crate) use lru_cache_with_maxsize_none::{
pub(crate) use lru_cache_without_parameters::{
lru_cache_without_parameters, LRUCacheWithoutParameters,
};
pub(crate) use native_literals::{NativeLiterals};
pub(crate) use open_alias::{OpenAlias};
pub(crate) use os_error_alias::{
os_error_alias_handlers, os_error_alias_raise, OSErrorAlias,
};
pub(crate) use native_literals::NativeLiterals;
pub(crate) use open_alias::OpenAlias;
pub(crate) use os_error_alias::{os_error_alias_handlers, os_error_alias_raise, OSErrorAlias};
pub(crate) use outdated_version_block::{outdated_version_block, OutdatedVersionBlock};
pub(crate) use printf_string_formatting::{printf_string_formatting, PrintfStringFormatting};
pub(crate) use quoted_annotation::{quoted_annotation, QuotedAnnotation};
pub(crate) use redundant_open_modes::{RedundantOpenModes};
pub(crate) use replace_stdout_stderr::{ReplaceStdoutStderr};
pub(crate) use replace_universal_newlines::{ReplaceUniversalNewlines};
pub(crate) use super_call_with_parameters::{SuperCallWithParameters};
pub(crate) use type_of_primitive::{TypeOfPrimitive};
pub(crate) use redundant_open_modes::RedundantOpenModes;
pub(crate) use replace_stdout_stderr::ReplaceStdoutStderr;
pub(crate) use replace_universal_newlines::ReplaceUniversalNewlines;
pub(crate) use super_call_with_parameters::SuperCallWithParameters;
pub(crate) use type_of_primitive::TypeOfPrimitive;
pub(crate) use typing_text_str_alias::{typing_text_str_alias, TypingTextStrAlias};
pub(crate) use unicode_kind_prefix::{unicode_kind_prefix, UnicodeKindPrefix};
pub(crate) use unnecessary_builtin_import::{unnecessary_builtin_import, UnnecessaryBuiltinImport};
pub(crate) use unnecessary_coding_comment::{unnecessary_coding_comment, UTF8EncodingDeclaration};
pub(crate) use unnecessary_encode_utf8::{UnnecessaryEncodeUTF8};
pub(crate) use unnecessary_encode_utf8::UnnecessaryEncodeUTF8;
pub(crate) use unnecessary_future_import::{unnecessary_future_import, UnnecessaryFutureImport};
pub(crate) use unpacked_list_comprehension::{
unpacked_list_comprehension, UnpackedListComprehension,
};
pub(crate) use use_pep585_annotation::{use_pep585_annotation, NonPEP585Annotation};
pub(crate) use use_pep604_annotation::{use_pep604_annotation, NonPEP604Annotation};
pub(crate) use use_pep604_isinstance::{NonPEP604Isinstance};
pub(crate) use use_pep604_isinstance::NonPEP604Isinstance;
pub(crate) use useless_metaclass_type::{useless_metaclass_type, UselessMetaclassType};
pub(crate) use useless_object_inheritance::{useless_object_inheritance, UselessObjectInheritance};
pub(crate) use yield_in_for_loop::{yield_in_for_loop, YieldInForLoop};

View File

@ -6,7 +6,7 @@ use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::str::is_implicit_concatenation;
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::RuleContext;
use crate::registry::{AsRule, Rule};
@ -43,7 +43,7 @@ impl AlwaysAutofixableViolation for NativeLiterals {
}
}
impl AstAnalyzer<ast::ExprCall> for NativeLiterals {
impl Analyzer<ast::ExprCall> for NativeLiterals {
fn rule() -> Rule {
Rule::NativeLiterals
}

View File

@ -3,7 +3,7 @@ use rustpython_parser::ast::{self, Ranged};
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
use ruff_macros::{derive_message_formats, violation};
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::RuleContext;
use crate::registry::{AsRule, Rule};
@ -23,7 +23,7 @@ impl Violation for OpenAlias {
}
}
impl AstAnalyzer<ast::ExprCall> for OpenAlias {
impl Analyzer<ast::ExprCall> for OpenAlias {
fn rule() -> Rule {
Rule::OpenAlias
}

View File

@ -6,7 +6,7 @@ use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::call_path::compose_call_path;
use ruff_python_semantic::context::Context;
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::{Checker, RuleContext};
use crate::registry::{AsRule, Rule};
@ -30,7 +30,7 @@ impl AlwaysAutofixableViolation for OSErrorAlias {
}
}
impl AstAnalyzer<ast::ExprCall> for OSErrorAlias {
impl Analyzer<ast::ExprCall> for OSErrorAlias {
fn rule() -> Rule {
Rule::OSErrorAlias
}

View File

@ -10,7 +10,7 @@ use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::find_keyword;
use ruff_python_ast::source_code::Locator;
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::RuleContext;
use crate::registry::Rule;
@ -42,7 +42,7 @@ impl AlwaysAutofixableViolation for RedundantOpenModes {
}
}
impl AstAnalyzer<ast::ExprCall> for RedundantOpenModes {
impl Analyzer<ast::ExprCall> for RedundantOpenModes {
fn rule() -> Rule {
Rule::RedundantOpenModes
}

View File

@ -7,7 +7,7 @@ use ruff_python_ast::helpers::find_keyword;
use ruff_python_ast::source_code::Locator;
use crate::autofix::actions::remove_argument;
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::RuleContext;
use crate::registry::{AsRule, Rule};
@ -25,7 +25,7 @@ impl AlwaysAutofixableViolation for ReplaceStdoutStderr {
}
}
impl AstAnalyzer<ast::ExprCall> for ReplaceStdoutStderr {
impl Analyzer<ast::ExprCall> for ReplaceStdoutStderr {
fn rule() -> Rule {
Rule::ReplaceStdoutStderr
}

View File

@ -5,7 +5,7 @@ use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::find_keyword;
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::RuleContext;
use crate::registry::{AsRule, Rule};
@ -23,7 +23,7 @@ impl AlwaysAutofixableViolation for ReplaceUniversalNewlines {
}
}
impl AstAnalyzer<ast::ExprCall> for ReplaceUniversalNewlines {
impl Analyzer<ast::ExprCall> for ReplaceUniversalNewlines {
fn rule() -> Rule {
Rule::ReplaceUniversalNewlines
}

View File

@ -4,7 +4,7 @@ use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_semantic::scope::ScopeKind;
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::RuleContext;
use crate::registry::{AsRule, Rule};
use crate::rules::pyupgrade::fixes;
@ -23,7 +23,7 @@ impl AlwaysAutofixableViolation for SuperCallWithParameters {
}
}
impl AstAnalyzer<ast::ExprCall> for SuperCallWithParameters {
impl Analyzer<ast::ExprCall> for SuperCallWithParameters {
fn rule() -> Rule {
Rule::SuperCallWithParameters
}

View File

@ -3,7 +3,7 @@ use rustpython_parser::ast::{self, Expr};
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::RuleContext;
use crate::registry::{AsRule, Rule};
@ -27,7 +27,7 @@ impl AlwaysAutofixableViolation for TypeOfPrimitive {
}
}
impl AstAnalyzer<ast::ExprCall> for TypeOfPrimitive {
impl Analyzer<ast::ExprCall> for TypeOfPrimitive {
fn rule() -> Rule {
Rule::TypeOfPrimitive
}

View File

@ -7,7 +7,7 @@ use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::source_code::Locator;
use crate::autofix::actions::remove_argument;
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::RuleContext;
use crate::registry::Rule;
@ -36,7 +36,7 @@ impl AlwaysAutofixableViolation for UnnecessaryEncodeUTF8 {
}
}
impl AstAnalyzer<ast::ExprCall> for UnnecessaryEncodeUTF8 {
impl Analyzer<ast::ExprCall> for UnnecessaryEncodeUTF8 {
fn rule() -> Rule {
Rule::UnnecessaryEncodeUTF8
}

View File

@ -3,6 +3,7 @@ use rustpython_parser::ast::{self, Constant, Expr, Operator, Ranged};
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_semantic::analyze::typing::Pep604Operator;
use crate::checkers::ast::Checker;

View File

@ -6,9 +6,10 @@ use rustpython_parser::ast::{self, Expr, Operator, Ranged};
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use crate::checkers::ast::traits::AstAnalyzer;
use crate::checkers::ast::traits::Analyzer;
use crate::checkers::ast::RuleContext;
use crate::registry::{AsRule, Rule};
use crate::settings::types::PythonVersion;
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub(crate) enum CallKind {
@ -51,7 +52,7 @@ impl AlwaysAutofixableViolation for NonPEP604Isinstance {
}
}
impl AstAnalyzer<ast::ExprCall> for NonPEP604Isinstance {
impl Analyzer<ast::ExprCall> for NonPEP604Isinstance {
fn rule() -> Rule {
Rule::NonPEP604Isinstance
}
@ -82,6 +83,10 @@ pub(crate) fn use_pep604_isinstance(
func, args, range, ..
}: &ast::ExprCall,
) {
if checker.settings.target_version < PythonVersion::Py310 {
return;
}
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
let Some(kind) = CallKind::from_name(id) else {
return;

View File

@ -4,7 +4,7 @@ use criterion::{
};
use ruff::linter::lint_only;
use ruff::settings::{flags, Settings};
use ruff::{Pyupgrade, RuleCodePrefix, RuleSelector};
use ruff::RuleSelector;
use ruff_benchmark::{TestCase, TestCaseSpeed, TestFile, TestFileDownloadError};
use std::time::Duration;
@ -73,14 +73,14 @@ fn benchmark_linter(mut group: BenchmarkGroup<WallTime>, settings: &Settings) {
group.finish();
}
fn benchmark_default_rules(criterion: &mut Criterion) {
let group = criterion.benchmark_group("linter/default-rules");
benchmark_linter(group, &Settings::default());
}
fn benchmark_all_rules(criterion: &mut Criterion) {
let settings = Settings {
rules: RuleSelector::Prefix {
prefix: RuleCodePrefix::Pyupgrade(Pyupgrade::_0),
redirected_from: None,
}
.into_iter()
.collect(),
rules: RuleSelector::All.into_iter().collect(),
..Settings::default()
};
@ -88,6 +88,6 @@ fn benchmark_all_rules(criterion: &mut Criterion) {
benchmark_linter(group, &settings);
}
// criterion_group!(default_rules, benchmark_default_rules);
criterion_group!(default_rules, benchmark_default_rules);
criterion_group!(all_rules, benchmark_all_rules);
criterion_main!(all_rules);
criterion_main!(default_rules, all_rules);

8
foo.py
View File

@ -1,8 +0,0 @@
def foo(a):
"""Summary
Args:
----
a: list
parameter a
"""