Skip to content

Commit

Permalink
Merge branch 'astral-sh:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
tjkuson authored Jul 19, 2023
2 parents c0c1c6d + 7e6b472 commit 68563d1
Show file tree
Hide file tree
Showing 51 changed files with 766 additions and 512 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

139 changes: 68 additions & 71 deletions crates/ruff/src/checkers/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ where
stmt,
name,
decorator_list,
returns.as_ref().map(|expr| &**expr),
returns.as_ref().map(AsRef::as_ref),
args,
stmt.is_async_function_def_stmt(),
);
Expand Down Expand Up @@ -470,18 +470,14 @@ where
Rule::SuperfluousElseContinue,
Rule::SuperfluousElseBreak,
]) {
flake8_return::rules::function(
self,
body,
returns.as_ref().map(|expr| &**expr),
);
flake8_return::rules::function(self, body, returns.as_ref().map(AsRef::as_ref));
}
if self.enabled(Rule::UselessReturn) {
pylint::rules::useless_return(
self,
stmt,
body,
returns.as_ref().map(|expr| &**expr),
returns.as_ref().map(AsRef::as_ref),
);
}
if self.enabled(Rule::ComplexStructure) {
Expand Down Expand Up @@ -1404,11 +1400,7 @@ where
}
if stmt.is_for_stmt() {
if self.enabled(Rule::ReimplementedBuiltin) {
flake8_simplify::rules::convert_for_loop_to_any_all(
self,
stmt,
self.semantic.sibling_stmt(),
);
flake8_simplify::rules::convert_for_loop_to_any_all(self, stmt);
}
if self.enabled(Rule::InDictKeys) {
flake8_simplify::rules::key_in_dict_for(self, target, iter);
Expand Down Expand Up @@ -4061,7 +4053,7 @@ where
}

// Step 2: Binding
let bindings = match except_handler {
let binding = match except_handler {
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
type_: _,
name,
Expand All @@ -4070,17 +4062,17 @@ where
}) => {
if let Some(name) = name {
// Store the existing binding, if any.
let existing_id = self.semantic.lookup_symbol(name.as_str());
let binding_id = self.semantic.lookup_symbol(name.as_str());

// Add the bound exception name to the scope.
let binding_id = self.add_binding(
self.add_binding(
name.as_str(),
name.range(),
BindingKind::Assignment,
BindingKind::BoundException,
BindingFlags::empty(),
);

Some((name, existing_id, binding_id))
Some((name, binding_id))
} else {
None
}
Expand All @@ -4091,33 +4083,11 @@ where
walk_except_handler(self, except_handler);

// Step 4: Clean-up
if let Some((name, existing_id, binding_id)) = bindings {
// If the exception name wasn't used in the scope, emit a diagnostic.
if !self.semantic.is_used(binding_id) {
if self.enabled(Rule::UnusedVariable) {
let mut diagnostic = Diagnostic::new(
pyflakes::rules::UnusedVariable {
name: name.to_string(),
},
name.range(),
);
if self.patch(Rule::UnusedVariable) {
diagnostic.try_set_fix(|| {
pyflakes::fixes::remove_exception_handler_assignment(
except_handler,
self.locator,
)
.map(Fix::automatic)
});
}
self.diagnostics.push(diagnostic);
}
}

if let Some((name, binding_id)) = binding {
self.add_binding(
name.as_str(),
name.range(),
BindingKind::UnboundException(existing_id),
BindingKind::UnboundException(binding_id),
BindingFlags::empty(),
);
}
Expand Down Expand Up @@ -4240,21 +4210,10 @@ where
flake8_pie::rules::no_unnecessary_pass(self, body);
}

// Step 2: Binding
let prev_body = self.semantic.body;
let prev_body_index = self.semantic.body_index;
self.semantic.body = body;
self.semantic.body_index = 0;

// Step 3: Traversal
for stmt in body {
self.visit_stmt(stmt);
self.semantic.body_index += 1;
}

// Step 4: Clean-up
self.semantic.body = prev_body;
self.semantic.body_index = prev_body_index;
}
}

Expand Down Expand Up @@ -4815,6 +4774,62 @@ impl<'a> Checker<'a> {
}
}

/// Run any lint rules that operate over a single [`Binding`].
fn check_bindings(&mut self) {
if !self.any_enabled(&[
Rule::UnusedVariable,
Rule::UnconventionalImportAlias,
Rule::UnaliasedCollectionsAbcSetImport,
]) {
return;
}

for binding in self.semantic.bindings.iter() {
// F841
if self.enabled(Rule::UnusedVariable) {
if binding.kind.is_bound_exception() && !binding.is_used() {
let mut diagnostic = Diagnostic::new(
pyflakes::rules::UnusedVariable {
name: binding.name(self.locator).to_string(),
},
binding.range,
);
if self.patch(Rule::UnusedVariable) {
diagnostic.try_set_fix(|| {
pyflakes::fixes::remove_exception_handler_assignment(
binding,
self.locator,
)
.map(Fix::automatic)
});
}
self.diagnostics.push(diagnostic);
}
}

if self.enabled(Rule::UnconventionalImportAlias) {
if let Some(diagnostic) =
flake8_import_conventions::rules::unconventional_import_alias(
self,
binding,
&self.settings.flake8_import_conventions.aliases,
)
{
self.diagnostics.push(diagnostic);
}
}
if self.is_stub {
if self.enabled(Rule::UnaliasedCollectionsAbcSetImport) {
if let Some(diagnostic) =
flake8_pyi::rules::unaliased_collections_abc_set_import(self, binding)
{
self.diagnostics.push(diagnostic);
}
}
}
}
}

fn check_deferred_scopes(&mut self) {
if !self.any_enabled(&[
Rule::GlobalVariableNotAssigned,
Expand All @@ -4824,8 +4839,6 @@ impl<'a> Checker<'a> {
Rule::TypingOnlyFirstPartyImport,
Rule::TypingOnlyStandardLibraryImport,
Rule::TypingOnlyThirdPartyImport,
Rule::UnaliasedCollectionsAbcSetImport,
Rule::UnconventionalImportAlias,
Rule::UndefinedExport,
Rule::UndefinedLocalWithImportStarUsage,
Rule::UndefinedLocalWithImportStarUsage,
Expand Down Expand Up @@ -5125,23 +5138,6 @@ impl<'a> Checker<'a> {
if self.enabled(Rule::UnusedImport) {
pyflakes::rules::unused_import(self, scope, &mut diagnostics);
}
if self.enabled(Rule::UnconventionalImportAlias) {
flake8_import_conventions::rules::unconventional_import_alias(
self,
scope,
&mut diagnostics,
&self.settings.flake8_import_conventions.aliases,
);
}
if self.is_stub {
if self.enabled(Rule::UnaliasedCollectionsAbcSetImport) {
flake8_pyi::rules::unaliased_collections_abc_set_import(
self,
scope,
&mut diagnostics,
);
}
}
}
self.diagnostics.extend(diagnostics);
}
Expand Down Expand Up @@ -5493,6 +5489,7 @@ pub(crate) fn check_ast(
checker.semantic.scope_id = ScopeId::global();
checker.deferred.scopes.push(ScopeId::global());
checker.check_deferred_scopes();
checker.check_bindings();

checker.diagnostics
}
3 changes: 2 additions & 1 deletion crates/ruff/src/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ pub fn lint_only(
package: Option<&Path>,
settings: &Settings,
noqa: flags::Noqa,
source_kind: Option<&SourceKind>,
) -> LinterResult<(Vec<Message>, Option<ImportMap>)> {
// Tokenize once.
let tokens: Vec<LexResult> = ruff_rustpython::tokenize(contents);
Expand Down Expand Up @@ -353,7 +354,7 @@ pub fn lint_only(
&directives,
settings,
noqa,
None,
source_kind,
);

result.map(|(diagnostics, imports)| {
Expand Down
1 change: 1 addition & 0 deletions crates/ruff/src/renamer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ impl Renamer {
| BindingKind::NamedExprAssignment
| BindingKind::UnpackedAssignment
| BindingKind::Assignment
| BindingKind::BoundException
| BindingKind::LoopVar
| BindingKind::Global
| BindingKind::Nonlocal(_)
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff/src/rules/flake8_annotations/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub(super) fn match_function_def(
}) => (
name,
args,
returns.as_ref().map(|expr| &**expr),
returns.as_ref().map(AsRef::as_ref),
body,
decorator_list,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use rustc_hash::FxHashMap;

use ruff_diagnostics::{AutofixKind, Diagnostic, Fix, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_semantic::Scope;
use ruff_python_semantic::Binding;

use crate::checkers::ast::Checker;
use crate::registry::AsRule;
Expand Down Expand Up @@ -53,42 +53,38 @@ impl Violation for UnconventionalImportAlias {
/// ICN001
pub(crate) fn unconventional_import_alias(
checker: &Checker,
scope: &Scope,
diagnostics: &mut Vec<Diagnostic>,
binding: &Binding,
conventions: &FxHashMap<String, String>,
) -> Option<Diagnostic> {
for (name, binding_id) in scope.all_bindings() {
let binding = checker.semantic().binding(binding_id);
let Some(qualified_name) = binding.qualified_name() else {
return None;
};

let Some(qualified_name) = binding.qualified_name() else {
continue;
};
let Some(expected_alias) = conventions.get(qualified_name) else {
return None;
};

let Some(expected_alias) = conventions.get(qualified_name) else {
continue;
};

if binding.is_alias() && name == expected_alias {
continue;
}
let name = binding.name(checker.locator);
if binding.is_alias() && name == expected_alias {
return None;
}

let mut diagnostic = Diagnostic::new(
UnconventionalImportAlias {
name: qualified_name.to_string(),
asname: expected_alias.to_string(),
},
binding.range,
);
if checker.patch(diagnostic.kind.rule()) {
if checker.semantic().is_available(expected_alias) {
diagnostic.try_set_fix(|| {
let (edit, rest) =
Renamer::rename(name, expected_alias, scope, checker.semantic())?;
Ok(Fix::suggested_edits(edit, rest))
});
}
let mut diagnostic = Diagnostic::new(
UnconventionalImportAlias {
name: qualified_name.to_string(),
asname: expected_alias.to_string(),
},
binding.range,
);
if checker.patch(diagnostic.kind.rule()) {
if checker.semantic().is_available(expected_alias) {
diagnostic.try_set_fix(|| {
let scope = &checker.semantic().scopes[binding.scope];
let (edit, rest) =
Renamer::rename(name, expected_alias, scope, checker.semantic())?;
Ok(Fix::suggested_edits(edit, rest))
});
}
diagnostics.push(diagnostic);
}
None
Some(diagnostic)
}
Loading

0 comments on commit 68563d1

Please sign in to comment.