Adapt is-macro for a few enums (#3182)
This commit is contained in:
20
Cargo.lock
generated
20
Cargo.lock
generated
@@ -2,6 +2,12 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "Inflector"
|
||||
version = "0.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
@@ -1023,6 +1029,19 @@ dependencies = [
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-macro"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a7d079e129b77477a49c5c4f1cfe9ce6c2c909ef52520693e8e811a714c7b20"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"pmutil",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.4"
|
||||
@@ -1971,6 +1990,7 @@ dependencies = [
|
||||
"ignore",
|
||||
"imperative",
|
||||
"insta",
|
||||
"is-macro",
|
||||
"itertools",
|
||||
"js-sys",
|
||||
"libcst",
|
||||
|
||||
@@ -33,6 +33,7 @@ glob = { version = "0.3.0" }
|
||||
globset = { version = "0.4.9" }
|
||||
ignore = { version = "0.4.18" }
|
||||
imperative = { version = "1.0.3" }
|
||||
is-macro = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
libcst = { workspace = true }
|
||||
log = { version = "0.4.17" }
|
||||
|
||||
@@ -124,7 +124,7 @@ impl<'a> Scope<'a> {
|
||||
// StarImportation
|
||||
// FutureImportation
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, is_macro::Is)]
|
||||
pub enum BindingKind<'a> {
|
||||
Annotation,
|
||||
Argument,
|
||||
|
||||
@@ -229,9 +229,8 @@ impl<'a> Checker<'a> {
|
||||
|
||||
/// Return `true` if `member` is bound as a builtin.
|
||||
pub fn is_builtin(&self, member: &str) -> bool {
|
||||
self.find_binding(member).map_or(false, |binding| {
|
||||
matches!(binding.kind, BindingKind::Builtin)
|
||||
})
|
||||
self.find_binding(member)
|
||||
.map_or(false, |binding| binding.kind.is_builtin())
|
||||
}
|
||||
|
||||
pub fn resolve_call_path<'b>(&'a self, value: &'b Expr) -> Option<CallPath<'a>>
|
||||
@@ -1928,9 +1927,7 @@ where
|
||||
if self.scopes[GLOBAL_SCOPE_INDEX]
|
||||
.bindings
|
||||
.get(name)
|
||||
.map_or(true, |index| {
|
||||
matches!(self.bindings[*index].kind, BindingKind::Annotation)
|
||||
})
|
||||
.map_or(true, |index| self.bindings[*index].kind.is_annotation())
|
||||
{
|
||||
let index = self.bindings.len();
|
||||
self.bindings.push(Binding {
|
||||
@@ -1992,9 +1989,7 @@ where
|
||||
if self.scopes[GLOBAL_SCOPE_INDEX]
|
||||
.bindings
|
||||
.get(name)
|
||||
.map_or(true, |index| {
|
||||
matches!(self.bindings[*index].kind, BindingKind::Annotation)
|
||||
})
|
||||
.map_or(true, |index| self.bindings[*index].kind.is_annotation())
|
||||
{
|
||||
let index = self.bindings.len();
|
||||
self.bindings.push(Binding {
|
||||
@@ -4136,7 +4131,7 @@ impl<'a> Checker<'a> {
|
||||
let existing_binding_index = self.scopes[*scope_index].bindings.get(&name).unwrap();
|
||||
let existing = &self.bindings[*existing_binding_index];
|
||||
let in_current_scope = stack_index == 0;
|
||||
if !matches!(existing.kind, BindingKind::Builtin)
|
||||
if !existing.kind.is_builtin()
|
||||
&& existing.source.as_ref().map_or(true, |left| {
|
||||
binding.source.as_ref().map_or(true, |right| {
|
||||
!branch_detection::different_forks(
|
||||
@@ -4156,7 +4151,7 @@ impl<'a> Checker<'a> {
|
||||
| BindingKind::StarImportation(..)
|
||||
| BindingKind::FutureImportation
|
||||
);
|
||||
if matches!(binding.kind, BindingKind::LoopVar) && existing_is_import {
|
||||
if binding.kind.is_loop_var() && existing_is_import {
|
||||
if self.settings.rules.enabled(&Rule::ImportShadowedByLoopVar) {
|
||||
self.diagnostics.push(Diagnostic::new(
|
||||
pyflakes::rules::ImportShadowedByLoopVar {
|
||||
@@ -4170,7 +4165,7 @@ impl<'a> Checker<'a> {
|
||||
if !existing.used()
|
||||
&& binding.redefines(existing)
|
||||
&& (!self.settings.dummy_variable_rgx.is_match(name) || existing_is_import)
|
||||
&& !(matches!(existing.kind, BindingKind::FunctionDefinition)
|
||||
&& !(existing.kind.is_function_definition()
|
||||
&& visibility::is_overload(
|
||||
self,
|
||||
cast::decorator_list(existing.source.as_ref().unwrap()),
|
||||
@@ -4205,36 +4200,29 @@ impl<'a> Checker<'a> {
|
||||
|
||||
let scope = self.current_scope();
|
||||
let binding = if let Some(index) = scope.bindings.get(&name) {
|
||||
if matches!(self.bindings[*index].kind, BindingKind::Builtin) {
|
||||
// Avoid overriding builtins.
|
||||
binding
|
||||
} else if matches!(self.bindings[*index].kind, BindingKind::Global) {
|
||||
// If the original binding was a global, and the new binding conflicts within
|
||||
// the current scope, then the new binding is also a global.
|
||||
Binding {
|
||||
runtime_usage: self.bindings[*index].runtime_usage,
|
||||
synthetic_usage: self.bindings[*index].synthetic_usage,
|
||||
typing_usage: self.bindings[*index].typing_usage,
|
||||
kind: BindingKind::Global,
|
||||
..binding
|
||||
let existing = &self.bindings[*index];
|
||||
match &existing.kind {
|
||||
BindingKind::Builtin => {
|
||||
// Avoid overriding builtins.
|
||||
binding
|
||||
}
|
||||
} else if matches!(self.bindings[*index].kind, BindingKind::Nonlocal) {
|
||||
// If the original binding was a nonlocal, and the new binding conflicts within
|
||||
// the current scope, then the new binding is also a nonlocal.
|
||||
Binding {
|
||||
runtime_usage: self.bindings[*index].runtime_usage,
|
||||
synthetic_usage: self.bindings[*index].synthetic_usage,
|
||||
typing_usage: self.bindings[*index].typing_usage,
|
||||
kind: BindingKind::Nonlocal,
|
||||
..binding
|
||||
kind @ (BindingKind::Global | BindingKind::Nonlocal) => {
|
||||
// If the original binding was a global or nonlocal, and the new binding conflicts within
|
||||
// the current scope, then the new binding is also as the same.
|
||||
Binding {
|
||||
runtime_usage: existing.runtime_usage,
|
||||
synthetic_usage: existing.synthetic_usage,
|
||||
typing_usage: existing.typing_usage,
|
||||
kind: kind.clone(),
|
||||
..binding
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Binding {
|
||||
runtime_usage: self.bindings[*index].runtime_usage,
|
||||
synthetic_usage: self.bindings[*index].synthetic_usage,
|
||||
typing_usage: self.bindings[*index].typing_usage,
|
||||
_ => Binding {
|
||||
runtime_usage: existing.runtime_usage,
|
||||
synthetic_usage: existing.synthetic_usage,
|
||||
typing_usage: existing.typing_usage,
|
||||
..binding
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
binding
|
||||
@@ -4243,7 +4231,7 @@ impl<'a> Checker<'a> {
|
||||
// Don't treat annotations as assignments if there is an existing value
|
||||
// in scope.
|
||||
let scope = &mut self.scopes[*(self.scope_stack.last().expect("No current scope found"))];
|
||||
if !(matches!(binding.kind, BindingKind::Annotation) && scope.bindings.contains_key(name)) {
|
||||
if !(binding.kind.is_annotation() && scope.bindings.contains_key(name)) {
|
||||
if let Some(rebound_index) = scope.bindings.insert(name, binding_index) {
|
||||
scope
|
||||
.rebounds
|
||||
@@ -4282,7 +4270,7 @@ impl<'a> Checker<'a> {
|
||||
let context = self.execution_context();
|
||||
self.bindings[*index].mark_used(scope_id, Range::from_located(expr), context);
|
||||
|
||||
if matches!(self.bindings[*index].kind, BindingKind::Annotation)
|
||||
if self.bindings[*index].kind.is_annotation()
|
||||
&& !self.in_deferred_string_type_definition
|
||||
&& !self.in_deferred_type_definition
|
||||
{
|
||||
@@ -4430,9 +4418,7 @@ impl<'a> Checker<'a> {
|
||||
.current_scope()
|
||||
.bindings
|
||||
.get(id)
|
||||
.map_or(false, |index| {
|
||||
matches!(self.bindings[*index].kind, BindingKind::Global)
|
||||
})
|
||||
.map_or(false, |index| self.bindings[*index].kind.is_global())
|
||||
{
|
||||
pep8_naming::rules::non_lowercase_variable_in_function(self, expr, parent, id);
|
||||
}
|
||||
@@ -4935,7 +4921,7 @@ impl<'a> Checker<'a> {
|
||||
{
|
||||
for (name, index) in &scope.bindings {
|
||||
let binding = &self.bindings[*index];
|
||||
if matches!(binding.kind, BindingKind::Global) {
|
||||
if binding.kind.is_global() {
|
||||
if let Some(stmt) = &binding.source {
|
||||
if matches!(stmt.node, StmtKind::Global { .. }) {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
|
||||
@@ -6,7 +6,6 @@ use rustpython_parser::ast::Location;
|
||||
use rustpython_parser::lexer::LexResult;
|
||||
use rustpython_parser::Tok;
|
||||
|
||||
use crate::registry::LintSource;
|
||||
use crate::settings::Settings;
|
||||
|
||||
bitflags! {
|
||||
@@ -21,7 +20,7 @@ impl Flags {
|
||||
if settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
.any(|rule_code| matches!(rule_code.lint_source(), LintSource::Imports))
|
||||
.any(|rule_code| rule_code.lint_source().is_imports())
|
||||
{
|
||||
Self::NOQA | Self::ISORT
|
||||
} else {
|
||||
|
||||
@@ -20,7 +20,7 @@ use crate::directives::Directives;
|
||||
use crate::doc_lines::{doc_lines_from_ast, doc_lines_from_tokens};
|
||||
use crate::message::{Message, Source};
|
||||
use crate::noqa::{add_noqa, rule_is_ignored};
|
||||
use crate::registry::{Diagnostic, LintSource, Rule};
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::rules::pycodestyle;
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code::{Indexer, Locator, Stylist};
|
||||
@@ -81,7 +81,7 @@ pub fn check_path(
|
||||
if settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
.any(|rule_code| matches!(rule_code.lint_source(), LintSource::Tokens))
|
||||
.any(|rule_code| rule_code.lint_source().is_tokens())
|
||||
{
|
||||
diagnostics.extend(check_tokens(locator, &tokens, settings, autofix));
|
||||
}
|
||||
@@ -90,7 +90,7 @@ pub fn check_path(
|
||||
if settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
.any(|rule_code| matches!(rule_code.lint_source(), LintSource::Filesystem))
|
||||
.any(|rule_code| rule_code.lint_source().is_filesystem())
|
||||
{
|
||||
diagnostics.extend(check_file_path(path, package, settings));
|
||||
}
|
||||
@@ -99,7 +99,7 @@ pub fn check_path(
|
||||
if settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
.any(|rule_code| matches!(rule_code.lint_source(), LintSource::LogicalLines))
|
||||
.any(|rule_code| rule_code.lint_source().is_logical_lines())
|
||||
{
|
||||
diagnostics.extend(check_logical_lines(&tokens, locator, stylist, settings));
|
||||
}
|
||||
@@ -108,12 +108,12 @@ pub fn check_path(
|
||||
let use_ast = settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
.any(|rule_code| matches!(rule_code.lint_source(), LintSource::Ast));
|
||||
.any(|rule_code| rule_code.lint_source().is_ast());
|
||||
let use_imports = !directives.isort.skip_file
|
||||
&& settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
.any(|rule_code| matches!(rule_code.lint_source(), LintSource::Imports));
|
||||
.any(|rule_code| rule_code.lint_source().is_imports());
|
||||
if use_ast || use_imports || use_doc_lines {
|
||||
match ruff_rustpython::parse_program_tokens(tokens, &path.to_string_lossy()) {
|
||||
Ok(python_ast) => {
|
||||
@@ -177,7 +177,7 @@ pub fn check_path(
|
||||
if settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
.any(|rule_code| matches!(rule_code.lint_source(), LintSource::PhysicalLines))
|
||||
.any(|rule_code| rule_code.lint_source().is_physical_lines())
|
||||
{
|
||||
diagnostics.extend(check_physical_lines(
|
||||
path,
|
||||
@@ -203,7 +203,7 @@ pub fn check_path(
|
||||
|| settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
.any(|rule_code| matches!(rule_code.lint_source(), LintSource::NoQa))
|
||||
.any(|rule_code| rule_code.lint_source().is_noqa())
|
||||
{
|
||||
check_noqa(
|
||||
&mut diagnostics,
|
||||
|
||||
@@ -759,6 +759,7 @@ impl Linter {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(is_macro::Is)]
|
||||
pub enum LintSource {
|
||||
Ast,
|
||||
Io,
|
||||
@@ -766,7 +767,7 @@ pub enum LintSource {
|
||||
LogicalLines,
|
||||
Tokens,
|
||||
Imports,
|
||||
NoQa,
|
||||
Noqa,
|
||||
Filesystem,
|
||||
}
|
||||
|
||||
@@ -775,7 +776,7 @@ impl Rule {
|
||||
/// physical lines).
|
||||
pub const fn lint_source(&self) -> &'static LintSource {
|
||||
match self {
|
||||
Rule::UnusedNOQA => &LintSource::NoQa,
|
||||
Rule::UnusedNOQA => &LintSource::Noqa,
|
||||
Rule::BlanketNOQA
|
||||
| Rule::BlanketTypeIgnore
|
||||
| Rule::DocLineTooLong
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::settings::{pyproject, AllSettings, Settings};
|
||||
|
||||
/// The strategy used to discover the relevant `pyproject.toml` file for each
|
||||
/// Python file.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, is_macro::Is)]
|
||||
pub enum PyprojectDiscovery {
|
||||
/// Use a fixed `pyproject.toml` file for all Python files (i.e., one
|
||||
/// provided on the command-line).
|
||||
@@ -30,7 +30,7 @@ pub enum PyprojectDiscovery {
|
||||
}
|
||||
|
||||
impl PyprojectDiscovery {
|
||||
fn top_level_settings(&self) -> &AllSettings {
|
||||
pub fn top_level_settings(&self) -> &AllSettings {
|
||||
match self {
|
||||
PyprojectDiscovery::Fixed(settings) => settings,
|
||||
PyprojectDiscovery::Hierarchical(settings) => settings,
|
||||
@@ -82,13 +82,7 @@ impl Resolver {
|
||||
.settings
|
||||
.iter()
|
||||
.rev()
|
||||
.find_map(|(root, settings)| {
|
||||
if path.starts_with(root) {
|
||||
Some(settings)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.find_map(|(root, settings)| path.starts_with(root).then_some(settings))
|
||||
.unwrap_or(default),
|
||||
}
|
||||
}
|
||||
@@ -228,7 +222,7 @@ pub fn python_files_in_path(
|
||||
// Search for `pyproject.toml` files in all parent directories.
|
||||
let mut resolver = Resolver::default();
|
||||
let mut seen = FxHashSet::default();
|
||||
if matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) {
|
||||
if pyproject_strategy.is_hierarchical() {
|
||||
for path in &paths {
|
||||
for ancestor in path.ancestors() {
|
||||
if seen.insert(ancestor) {
|
||||
@@ -277,7 +271,7 @@ pub fn python_files_in_path(
|
||||
Box::new(|result| {
|
||||
// Search for the `pyproject.toml` file in this directory, before we visit any
|
||||
// of its contents.
|
||||
if matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) {
|
||||
if pyproject_strategy.is_hierarchical() {
|
||||
if let Ok(entry) = &result {
|
||||
if entry
|
||||
.file_type()
|
||||
@@ -372,7 +366,7 @@ pub fn python_file_at_path(
|
||||
|
||||
// Search for `pyproject.toml` files in all parent directories.
|
||||
let mut resolver = Resolver::default();
|
||||
if matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) {
|
||||
if pyproject_strategy.is_hierarchical() {
|
||||
for ancestor in path.ancestors() {
|
||||
if let Some(pyproject) = settings_toml(ancestor)? {
|
||||
let (root, settings) =
|
||||
|
||||
@@ -23,7 +23,7 @@ use rustc_hash::FxHashMap;
|
||||
use rustpython_parser::ast::{Expr, ExprKind, Stmt};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::ast::types::{BindingKind, Range, RefEquality};
|
||||
use crate::ast::types::{Range, RefEquality};
|
||||
use crate::ast::visitor::Visitor;
|
||||
use crate::ast::{helpers, visitor};
|
||||
use crate::checkers::ast::Checker;
|
||||
@@ -185,7 +185,7 @@ pub fn unused_loop_control_variable(
|
||||
.and_then(|source| (source == &RefEquality(stmt)).then_some(binding))
|
||||
});
|
||||
if let Some(binding) = binding {
|
||||
if matches!(binding.kind, BindingKind::LoopVar) {
|
||||
if binding.kind.is_loop_var() {
|
||||
if !binding.used() {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
rename,
|
||||
|
||||
@@ -3,7 +3,7 @@ use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use ruff_macros::{define_violation, derive_message_formats};
|
||||
|
||||
use crate::ast::helpers::collect_call_path;
|
||||
use crate::ast::types::{BindingKind, Range, ScopeKind};
|
||||
use crate::ast::types::{Range, ScopeKind};
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violation::Violation;
|
||||
@@ -101,7 +101,7 @@ pub fn private_member_access(checker: &mut Checker, expr: &Expr) {
|
||||
.map_or(false, |binding| {
|
||||
// TODO(charlie): Could the name ever be bound to a _different_
|
||||
// class here?
|
||||
matches!(binding.kind, BindingKind::ClassDefinition)
|
||||
binding.kind.is_class_definition()
|
||||
})
|
||||
} else {
|
||||
false
|
||||
|
||||
@@ -9,7 +9,7 @@ use super::helpers;
|
||||
use super::types::Argumentable;
|
||||
use crate::ast::function_type;
|
||||
use crate::ast::function_type::FunctionType;
|
||||
use crate::ast::types::{Binding, BindingKind, FunctionDef, Lambda, Scope, ScopeKind};
|
||||
use crate::ast::types::{Binding, FunctionDef, Lambda, Scope, ScopeKind};
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violation::Violation;
|
||||
@@ -89,8 +89,7 @@ fn function(
|
||||
dummy_variable_rgx: &Regex,
|
||||
ignore_variadic_names: bool,
|
||||
) -> Vec<Diagnostic> {
|
||||
let mut diagnostics: Vec<Diagnostic> = vec![];
|
||||
for arg in args
|
||||
let args = args
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(args.args.iter())
|
||||
@@ -104,24 +103,8 @@ fn function(
|
||||
iter::once::<Option<&Arg>>(args.kwarg.as_deref())
|
||||
.flatten()
|
||||
.skip(usize::from(ignore_variadic_names)),
|
||||
)
|
||||
{
|
||||
if let Some(binding) = values
|
||||
.get(&arg.node.arg.as_str())
|
||||
.map(|index| &bindings[*index])
|
||||
{
|
||||
if !binding.used()
|
||||
&& matches!(binding.kind, BindingKind::Argument)
|
||||
&& !dummy_variable_rgx.is_match(arg.node.arg.as_str())
|
||||
{
|
||||
diagnostics.push(Diagnostic::new(
|
||||
argumentable.check_for(arg.node.arg.to_string()),
|
||||
binding.range,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
diagnostics
|
||||
);
|
||||
call(argumentable, args, values, bindings, dummy_variable_rgx)
|
||||
}
|
||||
|
||||
/// Check a method for unused arguments.
|
||||
@@ -133,8 +116,7 @@ fn method(
|
||||
dummy_variable_rgx: &Regex,
|
||||
ignore_variadic_names: bool,
|
||||
) -> Vec<Diagnostic> {
|
||||
let mut diagnostics: Vec<Diagnostic> = vec![];
|
||||
for arg in args
|
||||
let args = args
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(args.args.iter())
|
||||
@@ -149,14 +131,25 @@ fn method(
|
||||
iter::once::<Option<&Arg>>(args.kwarg.as_deref())
|
||||
.flatten()
|
||||
.skip(usize::from(ignore_variadic_names)),
|
||||
)
|
||||
{
|
||||
);
|
||||
call(argumentable, args, values, bindings, dummy_variable_rgx)
|
||||
}
|
||||
|
||||
fn call<'a>(
|
||||
argumentable: &Argumentable,
|
||||
args: impl Iterator<Item = &'a Arg>,
|
||||
values: &FxHashMap<&str, usize>,
|
||||
bindings: &[Binding],
|
||||
dummy_variable_rgx: &Regex,
|
||||
) -> Vec<Diagnostic> {
|
||||
let mut diagnostics: Vec<Diagnostic> = vec![];
|
||||
for arg in args {
|
||||
if let Some(binding) = values
|
||||
.get(&arg.node.arg.as_str())
|
||||
.map(|index| &bindings[*index])
|
||||
{
|
||||
if !binding.used()
|
||||
&& matches!(binding.kind, BindingKind::Argument)
|
||||
&& binding.kind.is_argument()
|
||||
&& !dummy_variable_rgx.is_match(arg.node.arg.as_str())
|
||||
{
|
||||
diagnostics.push(Diagnostic::new(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use ruff_macros::{define_violation, derive_message_formats};
|
||||
|
||||
use crate::ast::types::BindingKind;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violation::Violation;
|
||||
@@ -27,7 +26,7 @@ pub fn unused_annotation(checker: &mut Checker, scope: usize) {
|
||||
.map(|(name, index)| (name, &checker.bindings[*index]))
|
||||
{
|
||||
if !binding.used()
|
||||
&& matches!(binding.kind, BindingKind::Annotation)
|
||||
&& binding.kind.is_annotation()
|
||||
&& !checker.settings.dummy_variable_rgx.is_match(name)
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
|
||||
@@ -5,7 +5,7 @@ use rustpython_parser::ast::{ExprKind, Located, Stmt, StmtKind};
|
||||
use rustpython_parser::{lexer, Mode, Tok};
|
||||
|
||||
use crate::ast::helpers::contains_effect;
|
||||
use crate::ast::types::{BindingKind, Range, RefEquality, ScopeKind};
|
||||
use crate::ast::types::{Range, RefEquality, ScopeKind};
|
||||
use crate::autofix::helpers::delete_stmt;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
@@ -330,7 +330,7 @@ pub fn unused_variable(checker: &mut Checker, scope: usize) {
|
||||
.map(|(name, index)| (name, &checker.bindings[*index]))
|
||||
{
|
||||
if !binding.used()
|
||||
&& matches!(binding.kind, BindingKind::Assignment)
|
||||
&& binding.kind.is_assignment()
|
||||
&& !checker.settings.dummy_variable_rgx.is_match(name)
|
||||
&& name != &"__tracebackhide__"
|
||||
&& name != &"__traceback_info__"
|
||||
|
||||
@@ -41,23 +41,22 @@ pub fn run(
|
||||
|
||||
// Initialize the cache.
|
||||
if cache.into() {
|
||||
fn init_cache(path: &std::path::Path) {
|
||||
if let Err(e) = cache::init(path) {
|
||||
error!(
|
||||
"Failed to initialize cache at {}: {e:?}",
|
||||
path.to_string_lossy()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
match &pyproject_strategy {
|
||||
PyprojectDiscovery::Fixed(settings) => {
|
||||
if let Err(e) = cache::init(&settings.cli.cache_dir) {
|
||||
error!(
|
||||
"Failed to initialize cache at {}: {e:?}",
|
||||
settings.cli.cache_dir.to_string_lossy()
|
||||
);
|
||||
}
|
||||
init_cache(&settings.cli.cache_dir);
|
||||
}
|
||||
PyprojectDiscovery::Hierarchical(default) => {
|
||||
for settings in std::iter::once(default).chain(resolver.iter()) {
|
||||
if let Err(e) = cache::init(&settings.cli.cache_dir) {
|
||||
error!(
|
||||
"Failed to initialize cache at {}: {e:?}",
|
||||
settings.cli.cache_dir.to_string_lossy()
|
||||
);
|
||||
}
|
||||
init_cache(&settings.cli.cache_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +28,7 @@ pub fn run_stdin(
|
||||
return Ok(Diagnostics::default());
|
||||
}
|
||||
}
|
||||
let settings = match pyproject_strategy {
|
||||
PyprojectDiscovery::Fixed(settings) => settings,
|
||||
PyprojectDiscovery::Hierarchical(settings) => settings,
|
||||
};
|
||||
let settings = pyproject_strategy.top_level_settings();
|
||||
let package_root = filename
|
||||
.and_then(Path::parent)
|
||||
.and_then(|path| packaging::detect_package_root(path, &settings.lib.namespace_packages));
|
||||
|
||||
@@ -9,7 +9,6 @@ use colored::Colorize;
|
||||
use notify::{recommended_watcher, RecursiveMode, Watcher};
|
||||
|
||||
use ::ruff::logging::{set_up_logging, LogLevel};
|
||||
use ::ruff::resolver::PyprojectDiscovery;
|
||||
use ::ruff::settings::types::SerializationFormat;
|
||||
use ::ruff::settings::CliSettings;
|
||||
use ::ruff::{fix, fs, warn_user_once};
|
||||
@@ -151,10 +150,7 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result<ExitStatus> {
|
||||
show_fixes,
|
||||
update_check,
|
||||
..
|
||||
} = match &pyproject_strategy {
|
||||
PyprojectDiscovery::Fixed(settings) => settings.cli.clone(),
|
||||
PyprojectDiscovery::Hierarchical(settings) => settings.cli.clone(),
|
||||
};
|
||||
} = pyproject_strategy.top_level_settings().cli.clone();
|
||||
|
||||
// Autofix rules are as follows:
|
||||
// - If `--fix` or `--fix-only` is set, always apply fixes to the filesystem (or
|
||||
|
||||
Reference in New Issue
Block a user