From bae183b823b3b00a10c9faef1e03bb0eeff29939 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 14 Jun 2023 15:01:51 -0400 Subject: [PATCH] Rename `semantic_model` and `model` usages to `semantic` (#5097) ## Summary As discussed in Discord, and similar to oxc, we're going to refer to this as `.semantic()` everywhere. While I was auditing usages of `model: &SemanticModel`, I also changed as many function signatures as I could find to consistently take the model as the _last_ argument, rather than the first. --- crates/ruff/src/checkers/ast/mod.rs | 609 ++++++++---------- crates/ruff/src/importer/mod.rs | 25 +- .../rules/airflow/rules/task_variable_name.rs | 2 +- crates/ruff/src/rules/flake8_2020/helpers.rs | 4 +- .../src/rules/flake8_2020/rules/compare.rs | 6 +- .../flake8_2020/rules/name_or_attribute.rs | 2 +- .../src/rules/flake8_2020/rules/subscript.rs | 2 +- .../src/rules/flake8_annotations/helpers.rs | 8 +- .../flake8_annotations/rules/definition.rs | 32 +- .../flake8_async/rules/blocking_http_call.rs | 4 +- .../flake8_async/rules/blocking_os_call.rs | 4 +- .../rules/open_sleep_or_subprocess_call.rs | 4 +- .../ruff/src/rules/flake8_bandit/helpers.rs | 20 +- .../rules/bad_file_permissions.rs | 2 +- .../rules/hardcoded_sql_expression.rs | 2 +- .../rules/hashlib_insecure_hash_functions.rs | 27 +- .../rules/jinja2_autoescape_false.rs | 2 +- .../rules/logging_config_insecure_listen.rs | 2 +- .../flake8_bandit/rules/paramiko_calls.rs | 2 +- .../rules/request_with_no_cert_validation.rs | 2 +- .../rules/request_without_timeout.rs | 2 +- .../flake8_bandit/rules/shell_injection.rs | 12 +- .../rules/snmp_insecure_version.rs | 2 +- .../rules/snmp_weak_cryptography.rs | 2 +- .../rules/suspicious_function_call.rs | 2 +- .../rules/try_except_continue.rs | 2 +- .../flake8_bandit/rules/try_except_pass.rs | 2 +- .../flake8_bandit/rules/unsafe_yaml_load.rs | 4 +- .../flake8_blind_except/rules/blind_except.rs | 4 +- .../rules/abstract_base_class.rs | 12 +- .../rules/assert_raises_exception.rs | 4 +- .../rules/cached_instance_method.rs | 8 +- .../rules/function_call_argument_default.rs | 11 +- .../rules/mutable_argument_default.rs | 12 +- .../rules/no_explicit_stacklevel.rs | 2 +- .../rules/reuse_of_groupby_generator.rs | 2 +- .../rules/setattr_with_constant.rs | 2 +- .../rules/unused_loop_control_variable.rs | 9 +- .../rules/useless_contextlib_suppress.rs | 2 +- .../rules/useless_expression.rs | 2 +- .../rules/zip_without_explicit_strict.rs | 14 +- .../rules/builtin_attribute_shadowing.rs | 10 +- .../src/rules/flake8_comprehensions/fixes.rs | 2 +- .../rules/unnecessary_call_around_sorted.rs | 2 +- .../rules/unnecessary_collection_call.rs | 2 +- .../rules/unnecessary_comprehension.rs | 2 +- .../unnecessary_comprehension_any_all.rs | 2 +- .../unnecessary_double_cast_or_process.rs | 2 +- .../rules/unnecessary_generator_list.rs | 2 +- .../rules/unnecessary_generator_set.rs | 2 +- .../rules/unnecessary_list_call.rs | 2 +- .../unnecessary_list_comprehension_dict.rs | 2 +- .../unnecessary_list_comprehension_set.rs | 2 +- .../rules/unnecessary_literal_dict.rs | 2 +- .../rules/unnecessary_literal_set.rs | 2 +- .../unnecessary_literal_within_dict_call.rs | 2 +- .../unnecessary_literal_within_list_call.rs | 2 +- .../unnecessary_literal_within_tuple_call.rs | 2 +- .../rules/unnecessary_map.rs | 6 +- .../rules/unnecessary_subscript_reversal.rs | 2 +- .../rules/call_date_fromtimestamp.rs | 2 +- .../flake8_datetimez/rules/call_date_today.rs | 2 +- .../rules/call_datetime_fromtimestamp.rs | 2 +- .../rules/call_datetime_now_without_tzinfo.rs | 2 +- .../call_datetime_strptime_without_zone.rs | 4 +- .../rules/call_datetime_today.rs | 2 +- .../rules/call_datetime_utcfromtimestamp.rs | 2 +- .../rules/call_datetime_utcnow.rs | 2 +- .../rules/call_datetime_without_tzinfo.rs | 2 +- .../rules/flake8_debugger/rules/debugger.rs | 2 +- .../rules/all_with_model_form.rs | 2 +- .../rules/exclude_with_model_form.rs | 2 +- .../src/rules/flake8_django/rules/helpers.rs | 16 +- .../rules/locals_in_render_function.rs | 10 +- .../rules/model_without_dunder_str.rs | 6 +- .../rules/nullable_model_string_field.rs | 2 +- .../rules/unordered_body_content_in_model.rs | 8 +- .../rules/string_in_exception.rs | 6 +- .../future_rewritable_type_annotation.rs | 2 +- .../rules/logging_call.rs | 8 +- .../flake8_pie/rules/non_unique_enums.rs | 4 +- .../rules/reimplemented_list_builtin.rs | 2 +- .../rules/flake8_print/rules/print_call.rs | 13 +- .../flake8_pyi/rules/any_eq_ne_annotation.rs | 9 +- .../rules/bad_version_info_comparison.rs | 2 +- .../rules/collections_named_tuple.rs | 2 +- .../rules/iter_method_return_iterable.rs | 2 +- .../rules/no_return_argument_annotation.rs | 5 +- .../flake8_pyi/rules/non_self_return_type.rs | 40 +- .../flake8_pyi/rules/prefix_type_params.rs | 8 +- .../rules/flake8_pyi/rules/simple_defaults.rs | 100 ++- .../rules/str_or_repr_defined_in_stub.rs | 12 +- .../flake8_pyi/rules/unrecognized_platform.rs | 2 +- .../flake8_pytest_style/rules/assertion.rs | 8 +- .../rules/flake8_pytest_style/rules/fail.rs | 2 +- .../flake8_pytest_style/rules/fixture.rs | 10 +- .../flake8_pytest_style/rules/helpers.rs | 20 +- .../flake8_pytest_style/rules/parametrize.rs | 2 +- .../rules/flake8_pytest_style/rules/raises.rs | 10 +- .../src/rules/flake8_return/rules/function.rs | 8 +- .../rules/private_member_access.rs | 6 +- .../flake8_simplify/rules/ast_bool_op.rs | 23 +- .../rules/flake8_simplify/rules/ast_expr.rs | 2 +- .../src/rules/flake8_simplify/rules/ast_if.rs | 16 +- .../rules/flake8_simplify/rules/ast_ifexp.rs | 2 +- .../flake8_simplify/rules/ast_unary_op.rs | 12 +- .../rules/open_file_with_context_handler.rs | 26 +- .../rules/reimplemented_builtin.rs | 8 +- .../rules/suppressible_exception.rs | 2 +- .../rules/no_slots_in_namedtuple_subclass.rs | 2 +- .../rules/no_slots_in_str_subclass.rs | 2 +- .../rules/no_slots_in_tuple_subclass.rs | 4 +- .../flake8_tidy_imports/rules/banned_api.rs | 2 +- .../src/rules/flake8_type_checking/helpers.rs | 31 +- .../rules/empty_type_checking_block.rs | 4 +- .../runtime_import_in_type_checking_block.rs | 18 +- .../rules/typing_only_runtime_import.rs | 20 +- .../rules/unused_arguments.rs | 46 +- .../rules/replaceable_by_pathlib.rs | 2 +- .../numpy/rules/deprecated_type_alias.rs | 37 +- .../rules/numpy/rules/numpy_legacy_random.rs | 25 +- crates/ruff/src/rules/pandas_vet/helpers.rs | 4 +- .../ruff/src/rules/pandas_vet/rules/attr.rs | 4 +- .../ruff/src/rules/pandas_vet/rules/call.rs | 2 +- .../pandas_vet/rules/inplace_argument.rs | 10 +- .../src/rules/pandas_vet/rules/subscript.rs | 2 +- crates/ruff/src/rules/pep8_naming/helpers.rs | 16 +- ...id_first_argument_name_for_class_method.rs | 4 +- .../invalid_first_argument_name_for_method.rs | 4 +- .../rules/invalid_function_name.rs | 4 +- .../mixed_case_variable_in_class_scope.rs | 4 +- .../mixed_case_variable_in_global_scope.rs | 3 +- .../non_lowercase_variable_in_function.rs | 6 +- .../src/rules/pycodestyle/rules/imports.rs | 3 +- .../pycodestyle/rules/lambda_assignment.rs | 21 +- .../pycodestyle/rules/type_comparison.rs | 12 +- crates/ruff/src/rules/pydocstyle/helpers.rs | 5 +- .../src/rules/pydocstyle/rules/if_needed.rs | 2 +- .../pydocstyle/rules/non_imperative_mood.rs | 2 +- .../src/rules/pydocstyle/rules/not_missing.rs | 6 +- .../src/rules/pydocstyle/rules/sections.rs | 2 +- .../pyflakes/rules/invalid_print_syntax.rs | 2 +- .../pyflakes/rules/return_outside_function.rs | 2 +- .../rules/pyflakes/rules/undefined_local.rs | 13 +- .../rules/pyflakes/rules/unused_annotation.rs | 4 +- .../src/rules/pyflakes/rules/unused_import.rs | 10 +- .../rules/pyflakes/rules/unused_variable.rs | 12 +- .../pyflakes/rules/yield_outside_function.rs | 2 +- .../pygrep_hooks/rules/deprecated_log_warn.rs | 2 +- .../src/rules/pygrep_hooks/rules/no_eval.rs | 2 +- crates/ruff/src/rules/pylint/helpers.rs | 10 +- .../rules/pylint/rules/await_outside_async.rs | 2 +- .../pylint/rules/compare_to_empty_string.rs | 2 +- .../rules/pylint/rules/global_statement.rs | 6 +- .../pylint/rules/invalid_envvar_default.rs | 2 +- .../pylint/rules/invalid_envvar_value.rs | 2 +- .../rules/pylint/rules/invalid_str_return.rs | 2 +- .../rules/load_before_global_declaration.rs | 2 +- crates/ruff/src/rules/pylint/rules/logging.rs | 2 +- .../src/rules/pylint/rules/nested_min_max.rs | 27 +- .../pylint/rules/property_with_parameters.rs | 2 +- .../rules/pylint/rules/redefined_loop_name.rs | 10 +- .../pylint/rules/repeated_isinstance_calls.rs | 2 +- .../src/rules/pylint/rules/return_in_init.rs | 2 +- .../src/rules/pylint/rules/sys_exit_alias.rs | 4 +- .../unexpected_special_method_signature.rs | 4 +- .../rules/yield_from_in_async_function.rs | 2 +- .../src/rules/pylint/rules/yield_in_init.rs | 2 +- ...convert_named_tuple_functional_to_class.rs | 6 +- .../convert_typed_dict_functional_to_class.rs | 6 +- .../pyupgrade/rules/datetime_utc_alias.rs | 2 +- .../rules/lru_cache_with_maxsize_none.rs | 4 +- .../rules/lru_cache_without_parameters.rs | 2 +- .../rules/pyupgrade/rules/native_literals.rs | 4 +- .../src/rules/pyupgrade/rules/open_alias.rs | 4 +- .../rules/pyupgrade/rules/os_error_alias.rs | 21 +- .../pyupgrade/rules/outdated_version_block.rs | 6 +- .../pyupgrade/rules/redundant_open_modes.rs | 2 +- .../pyupgrade/rules/replace_stdout_stderr.rs | 6 +- .../rules/replace_universal_newlines.rs | 2 +- .../rules/super_call_with_parameters.rs | 4 +- .../pyupgrade/rules/type_of_primitive.rs | 2 +- .../pyupgrade/rules/typing_text_str_alias.rs | 2 +- .../rules/unnecessary_builtin_import.rs | 4 +- .../rules/unnecessary_future_import.rs | 4 +- .../pyupgrade/rules/use_pep585_annotation.rs | 6 +- .../pyupgrade/rules/use_pep604_annotation.rs | 4 +- .../pyupgrade/rules/use_pep604_isinstance.rs | 2 +- .../pyupgrade/rules/useless_metaclass_type.rs | 4 +- .../rules/useless_object_inheritance.rs | 2 +- .../rules/collection_literal_concatenation.rs | 2 +- .../explicit_f_string_type_conversion.rs | 2 +- .../function_call_in_dataclass_default.rs | 8 +- crates/ruff/src/rules/ruff/rules/helpers.rs | 12 +- .../src/rules/ruff/rules/implicit_optional.rs | 40 +- .../rules/ruff/rules/mutable_class_default.rs | 6 +- .../ruff/rules/mutable_dataclass_default.rs | 6 +- .../rules/ruff/rules/pairwise_over_zipped.rs | 2 +- crates/ruff/src/rules/tryceratops/helpers.rs | 8 +- .../rules/error_instead_of_exception.rs | 4 +- .../tryceratops/rules/raise_vanilla_class.rs | 2 +- .../tryceratops/rules/try_consider_else.rs | 2 +- .../rules/type_check_without_type_error.rs | 4 +- .../tryceratops/rules/verbose_log_message.rs | 2 +- .../src/analyze/function_type.rs | 10 +- .../src/analyze/logging.rs | 8 +- .../src/analyze/typing.rs | 156 ++--- .../src/analyze/visibility.rs | 36 +- crates/ruff_python_semantic/src/binding.rs | 8 +- 209 files changed, 1058 insertions(+), 1167 deletions(-) diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index b11002cfd1..5cb760be85 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -67,7 +67,7 @@ pub(crate) struct Checker<'a> { pub(crate) indexer: &'a Indexer, pub(crate) importer: Importer<'a>, // Stateful fields. - semantic_model: SemanticModel<'a>, + semantic: SemanticModel<'a>, deferred: Deferred<'a>, pub(crate) diagnostics: Vec, // Check-specific state. @@ -100,7 +100,7 @@ impl<'a> Checker<'a> { stylist, indexer, importer, - semantic_model: SemanticModel::new(&settings.typing_modules, path, module), + semantic: SemanticModel::new(&settings.typing_modules, path, module), deferred: Deferred::default(), diagnostics: Vec::default(), flake8_bugbear_seen: Vec::default(), @@ -143,7 +143,7 @@ impl<'a> Checker<'a> { /// /// If the current expression in the context is not an f-string, returns ``None``. pub(crate) fn f_string_quote_style(&self) -> Option { - let model = &self.semantic_model; + let model = &self.semantic; if !model.in_f_string() { return None; } @@ -169,14 +169,14 @@ impl<'a> Checker<'a> { /// thus be applied whenever we delete a statement, but can otherwise be omitted. pub(crate) fn isolation(&self, parent: Option<&Stmt>) -> IsolationLevel { parent - .and_then(|stmt| self.semantic_model.stmts.node_id(stmt)) + .and_then(|stmt| self.semantic.stmts.node_id(stmt)) .map_or(IsolationLevel::default(), |node_id| { IsolationLevel::Group(node_id.into()) }) } - pub(crate) const fn semantic_model(&self) -> &SemanticModel<'a> { - &self.semantic_model + pub(crate) const fn semantic(&self) -> &SemanticModel<'a> { + &self.semantic } pub(crate) const fn package(&self) -> Option<&'a Path> { @@ -205,7 +205,7 @@ where 'b: 'a, { fn visit_stmt(&mut self, stmt: &'b Stmt) { - self.semantic_model.push_stmt(stmt); + self.semantic.push_stmt(stmt); // Track whether we've seen docstrings, non-imports, etc. match stmt { @@ -216,50 +216,50 @@ where .iter() .any(|alias| alias.name.as_str() == "annotations") { - self.semantic_model.flags |= SemanticModelFlags::FUTURE_ANNOTATIONS; + self.semantic.flags |= SemanticModelFlags::FUTURE_ANNOTATIONS; } } else { - self.semantic_model.flags |= SemanticModelFlags::FUTURES_BOUNDARY; + self.semantic.flags |= SemanticModelFlags::FUTURES_BOUNDARY; } } Stmt::Import(_) => { - self.semantic_model.flags |= SemanticModelFlags::FUTURES_BOUNDARY; + self.semantic.flags |= SemanticModelFlags::FUTURES_BOUNDARY; } _ => { - self.semantic_model.flags |= SemanticModelFlags::FUTURES_BOUNDARY; - if !self.semantic_model.seen_import_boundary() + self.semantic.flags |= SemanticModelFlags::FUTURES_BOUNDARY; + if !self.semantic.seen_import_boundary() && !helpers::is_assignment_to_a_dunder(stmt) - && !helpers::in_nested_block(self.semantic_model.parents()) + && !helpers::in_nested_block(self.semantic.parents()) { - self.semantic_model.flags |= SemanticModelFlags::IMPORT_BOUNDARY; + self.semantic.flags |= SemanticModelFlags::IMPORT_BOUNDARY; } } } // Track each top-level import, to guide import insertions. if matches!(stmt, Stmt::Import(_) | Stmt::ImportFrom(_)) { - if self.semantic_model.at_top_level() { + if self.semantic.at_top_level() { self.importer.visit_import(stmt); } } // Store the flags prior to any further descent, so that we can restore them after visiting // the node. - let flags_snapshot = self.semantic_model.flags; + let flags_snapshot = self.semantic.flags; // Pre-visit. match stmt { Stmt::Global(ast::StmtGlobal { names, range: _ }) => { let ranges: Vec = helpers::find_names(stmt, self.locator).collect(); - if !self.semantic_model.scope_id.is_global() { + if !self.semantic.scope_id.is_global() { for (name, range) in names.iter().zip(ranges.iter()) { // Add a binding to the current scope. - let binding_id = self.semantic_model.push_binding( + let binding_id = self.semantic.push_binding( *range, BindingKind::Global, BindingFlags::empty(), ); - let scope = self.semantic_model.scope_mut(); + let scope = self.semantic.scope_mut(); scope.add(name, binding_id); } } @@ -272,15 +272,15 @@ where } Stmt::Nonlocal(ast::StmtNonlocal { names, range: _ }) => { let ranges: Vec = helpers::find_names(stmt, self.locator).collect(); - if !self.semantic_model.scope_id.is_global() { + if !self.semantic.scope_id.is_global() { for (name, range) in names.iter().zip(ranges.iter()) { // Add a binding to the current scope. - let binding_id = self.semantic_model.push_binding( + let binding_id = self.semantic.push_binding( *range, BindingKind::Nonlocal, BindingFlags::empty(), ); - let scope = self.semantic_model.scope_mut(); + let scope = self.semantic.scope_mut(); scope.add(name, binding_id); } @@ -288,15 +288,15 @@ where // and the current scope, and, per standard resolution rules, any class scopes.) for (name, range) in names.iter().zip(ranges.iter()) { let binding_id = self - .semantic_model + .semantic .scopes - .ancestors(self.semantic_model.scope_id) + .ancestors(self.semantic.scope_id) .skip(1) .filter(|scope| !(scope.kind.is_module() || scope.kind.is_class())) .find_map(|scope| scope.get(name.as_str())); if let Some(binding_id) = binding_id { - self.semantic_model.add_local_reference( + self.semantic.add_local_reference( binding_id, stmt.range(), ExecutionContext::Runtime, @@ -324,7 +324,7 @@ where if self.enabled(Rule::BreakOutsideLoop) { if let Some(diagnostic) = pyflakes::rules::break_outside_loop( stmt, - &mut self.semantic_model.parents().skip(1), + &mut self.semantic.parents().skip(1), ) { self.diagnostics.push(diagnostic); } @@ -334,7 +334,7 @@ where if self.enabled(Rule::ContinueOutsideLoop) { if let Some(diagnostic) = pyflakes::rules::continue_outside_loop( stmt, - &mut self.semantic_model.parents().skip(1), + &mut self.semantic.parents().skip(1), ) { self.diagnostics.push(diagnostic); } @@ -360,7 +360,7 @@ where self.diagnostics .extend(flake8_django::rules::non_leading_receiver_decorator( decorator_list, - |expr| self.semantic_model.resolve_call_path(expr), + |expr| self.semantic.resolve_call_path(expr), )); } @@ -382,7 +382,7 @@ where name, decorator_list, &self.settings.pep8_naming.ignore_names, - &self.semantic_model, + &self.semantic, self.locator, ) { self.diagnostics.push(diagnostic); @@ -392,7 +392,7 @@ where if let Some(diagnostic) = pep8_naming::rules::invalid_first_argument_name_for_class_method( self, - self.semantic_model.scope(), + self.semantic.scope(), name, decorator_list, args, @@ -405,7 +405,7 @@ where if let Some(diagnostic) = pep8_naming::rules::invalid_first_argument_name_for_method( self, - self.semantic_model.scope(), + self.semantic.scope(), name, decorator_list, args, @@ -448,7 +448,7 @@ where } if self.enabled(Rule::DunderFunctionName) { if let Some(diagnostic) = pep8_naming::rules::dunder_function_name( - self.semantic_model.scope(), + self.semantic.scope(), stmt, name, &self.settings.pep8_naming.ignore_names, @@ -614,7 +614,7 @@ where if self.enabled(Rule::YieldInForLoop) { pyupgrade::rules::yield_in_for_loop(self, stmt); } - if let ScopeKind::Class(class_def) = self.semantic_model.scope().kind { + if let ScopeKind::Class(class_def) = self.semantic.scope().kind { if self.enabled(Rule::BuiltinAttributeShadowing) { flake8_builtins::rules::builtin_attribute_shadowing( self, @@ -814,7 +814,7 @@ where ); if self.enabled(Rule::LateFutureImport) { - if self.semantic_model.seen_futures_boundary() { + if self.semantic.seen_futures_boundary() { self.diagnostics.push(Diagnostic::new( pyflakes::rules::LateFutureImport, stmt.range(), @@ -1094,7 +1094,7 @@ where } if self.enabled(Rule::LateFutureImport) { - if self.semantic_model.seen_futures_boundary() { + if self.semantic.seen_futures_boundary() { self.diagnostics.push(Diagnostic::new( pyflakes::rules::LateFutureImport, stmt.range(), @@ -1102,12 +1102,12 @@ where } } } else if &alias.name == "*" { - self.semantic_model + self.semantic .scope_mut() .add_star_import(StarImportation { level, module }); if self.enabled(Rule::UndefinedLocalWithNestedImportStarUsage) { - let scope = self.semantic_model.scope(); + let scope = self.semantic.scope(); if !matches!(scope.kind, ScopeKind::Module) { self.diagnostics.push(Diagnostic::new( pyflakes::rules::UndefinedLocalWithNestedImportStarUsage { @@ -1370,14 +1370,14 @@ where test, body, orelse, - self.semantic_model.stmt_parent(), + self.semantic.stmt_parent(), ); } if self.enabled(Rule::IfWithSameArms) { flake8_simplify::rules::if_with_same_arms( self, stmt, - self.semantic_model.stmt_parent(), + self.semantic.stmt_parent(), ); } if self.enabled(Rule::NeedlessBool) { @@ -1390,14 +1390,14 @@ where test, body, orelse, - self.semantic_model.stmt_parent(), + self.semantic.stmt_parent(), ); } if self.enabled(Rule::IfElseBlockInsteadOfIfExp) { flake8_simplify::rules::use_ternary_operator( self, stmt, - self.semantic_model.stmt_parent(), + self.semantic.stmt_parent(), ); } if self.enabled(Rule::IfElseBlockInsteadOfDictGet) { @@ -1407,7 +1407,7 @@ where test, body, orelse, - self.semantic_model.stmt_parent(), + self.semantic.stmt_parent(), ); } if self.enabled(Rule::TypeCheckWithoutTypeError) { @@ -1416,7 +1416,7 @@ where body, test, orelse, - self.semantic_model.stmt_parent(), + self.semantic.stmt_parent(), ); } if self.enabled(Rule::OutdatedVersionBlock) { @@ -1435,7 +1435,7 @@ where msg, range: _, }) => { - if !self.semantic_model.in_type_checking_block() { + if !self.semantic.in_type_checking_block() { if self.enabled(Rule::Assert) { self.diagnostics .push(flake8_bandit::rules::assert_used(stmt)); @@ -1478,7 +1478,7 @@ where self, stmt, body, - self.semantic_model.stmt_parent(), + self.semantic.stmt_parent(), ); } if self.enabled(Rule::RedefinedLoopName) { @@ -1508,7 +1508,7 @@ where .. }) => { if self.enabled(Rule::UnusedLoopControlVariable) { - self.deferred.for_loops.push(self.semantic_model.snapshot()); + self.deferred.for_loops.push(self.semantic.snapshot()); } if self.enabled(Rule::LoopVariableOverridesIterator) { flake8_bugbear::rules::loop_variable_overrides_iterator(self, target, iter); @@ -1533,7 +1533,7 @@ where flake8_simplify::rules::convert_for_loop_to_any_all( self, stmt, - self.semantic_model.sibling_stmt(), + self.semantic.sibling_stmt(), ); } if self.enabled(Rule::InDictKeys) { @@ -1674,7 +1674,7 @@ where ]) { // Ignore assignments in function bodies; those are covered by other rules. if !self - .semantic_model + .semantic .scopes() .any(|scope| scope.kind.is_any_function()) { @@ -1723,7 +1723,7 @@ where if self.enabled(Rule::AssignmentDefaultInStub) { // Ignore assignments in function bodies; those are covered by other rules. if !self - .semantic_model + .semantic .scopes() .any(|scope| scope.kind.is_any_function()) { @@ -1739,10 +1739,7 @@ where ); } } - if self - .semantic_model - .match_typing_expr(annotation, "TypeAlias") - { + if self.semantic.match_typing_expr(annotation, "TypeAlias") { if self.enabled(Rule::SnakeCaseTypeAlias) { flake8_pyi::rules::snake_case_type_alias(self, target); } @@ -1776,7 +1773,7 @@ where } if self.enabled(Rule::AsyncioDanglingTask) { if let Some(diagnostic) = ruff::rules::asyncio_dangling_task(value, |expr| { - self.semantic_model.resolve_call_path(expr) + self.semantic.resolve_call_path(expr) }) { self.diagnostics.push(diagnostic); } @@ -1811,7 +1808,7 @@ where // Function annotations are always evaluated at runtime, unless future annotations // are enabled. - let runtime_annotation = !self.semantic_model.future_annotations(); + let runtime_annotation = !self.semantic.future_annotations(); for arg in &args.posonlyargs { if let Some(expr) = &arg.annotation { @@ -1882,22 +1879,22 @@ where let definition = docstrings::extraction::extract_definition( ExtractionTarget::Function, stmt, - self.semantic_model.definition_id, - &self.semantic_model.definitions, + self.semantic.definition_id, + &self.semantic.definitions, ); - self.semantic_model.push_definition(definition); + self.semantic.push_definition(definition); - self.semantic_model.push_scope(match &stmt { + self.semantic.push_scope(match &stmt { Stmt::FunctionDef(stmt) => ScopeKind::Function(stmt), Stmt::AsyncFunctionDef(stmt) => ScopeKind::AsyncFunction(stmt), _ => unreachable!("Expected Stmt::FunctionDef | Stmt::AsyncFunctionDef"), }); - self.deferred.functions.push(self.semantic_model.snapshot()); + self.deferred.functions.push(self.semantic.snapshot()); // Extract any global bindings from the function body. if let Some(globals) = Globals::from_body(body) { - self.semantic_model.set_globals(globals); + self.semantic.set_globals(globals); } } Stmt::ClassDef( @@ -1922,16 +1919,16 @@ where let definition = docstrings::extraction::extract_definition( ExtractionTarget::Class, stmt, - self.semantic_model.definition_id, - &self.semantic_model.definitions, + self.semantic.definition_id, + &self.semantic.definitions, ); - self.semantic_model.push_definition(definition); + self.semantic.push_definition(definition); - self.semantic_model.push_scope(ScopeKind::Class(class_def)); + self.semantic.push_scope(ScopeKind::Class(class_def)); // Extract any global bindings from the class body. if let Some(globals) = Globals::from_body(body) { - self.semantic_model.set_globals(globals); + self.semantic.set_globals(globals); } self.visit_body(body); @@ -1952,7 +1949,7 @@ where }) => { let mut handled_exceptions = Exceptions::empty(); for type_ in extract_handled_exceptions(handlers) { - if let Some(call_path) = self.semantic_model.resolve_call_path(type_) { + if let Some(call_path) = self.semantic.resolve_call_path(type_) { match call_path.as_slice() { ["", "NameError"] => { handled_exceptions |= Exceptions::NAME_ERROR; @@ -1968,9 +1965,7 @@ where } } - self.semantic_model - .handled_exceptions - .push(handled_exceptions); + self.semantic.handled_exceptions.push(handled_exceptions); if self.enabled(Rule::JumpStatementInFinally) { flake8_bugbear::rules::jump_statement_in_finally(self, finalbody); @@ -1982,9 +1977,9 @@ where } self.visit_body(body); - self.semantic_model.handled_exceptions.pop(); + self.semantic.handled_exceptions.pop(); - self.semantic_model.flags |= SemanticModelFlags::EXCEPTION_HANDLER; + self.semantic.flags |= SemanticModelFlags::EXCEPTION_HANDLER; for excepthandler in handlers { self.visit_excepthandler(excepthandler); } @@ -2001,8 +1996,8 @@ where // If we're in a class or module scope, then the annotation needs to be // available at runtime. // See: https://docs.python.org/3/reference/simple_stmts.html#annotated-assignment-statements - let runtime_annotation = if self.semantic_model.future_annotations() { - if self.semantic_model.scope().kind.is_class() { + let runtime_annotation = if self.semantic.future_annotations() { + if self.semantic.scope().kind.is_class() { let baseclasses = &self .settings .flake8_type_checking @@ -2012,16 +2007,16 @@ where .flake8_type_checking .runtime_evaluated_decorators; flake8_type_checking::helpers::runtime_evaluated( - &self.semantic_model, baseclasses, decorators, + &self.semantic, ) } else { false } } else { matches!( - self.semantic_model.scope().kind, + self.semantic.scope().kind, ScopeKind::Class(_) | ScopeKind::Module ) }; @@ -2032,10 +2027,7 @@ where self.visit_annotation(annotation); } if let Some(expr) = value { - if self - .semantic_model - .match_typing_expr(annotation, "TypeAlias") - { + if self.semantic.match_typing_expr(annotation, "TypeAlias") { self.visit_type_definition(expr); } else { self.visit_expr(expr); @@ -2073,8 +2065,8 @@ where ) => { self.visit_boolean_test(test); - if typing::is_type_checking_block(stmt_if, &self.semantic_model) { - if self.semantic_model.at_top_level() { + if typing::is_type_checking_block(stmt_if, &self.semantic) { + if self.semantic.at_top_level() { self.importer.visit_type_checking_block(stmt); } if self.enabled(Rule::EmptyTypeCheckingBlock) { @@ -2094,12 +2086,12 @@ where // Post-visit. match stmt { Stmt::FunctionDef(_) | Stmt::AsyncFunctionDef(_) => { - self.semantic_model.pop_scope(); - self.semantic_model.pop_definition(); + self.semantic.pop_scope(); + self.semantic.pop_definition(); } Stmt::ClassDef(ast::StmtClassDef { name, .. }) => { - self.semantic_model.pop_scope(); - self.semantic_model.pop_definition(); + self.semantic.pop_scope(); + self.semantic.pop_definition(); self.add_binding( name, stmt.range(), @@ -2110,22 +2102,22 @@ where _ => {} } - self.semantic_model.flags = flags_snapshot; - self.semantic_model.pop_stmt(); + self.semantic.flags = flags_snapshot; + self.semantic.pop_stmt(); } fn visit_annotation(&mut self, expr: &'b Expr) { - let flags_snapshot = self.semantic_model.flags; - self.semantic_model.flags |= SemanticModelFlags::ANNOTATION; + let flags_snapshot = self.semantic.flags; + self.semantic.flags |= SemanticModelFlags::ANNOTATION; self.visit_type_definition(expr); - self.semantic_model.flags = flags_snapshot; + self.semantic.flags = flags_snapshot; } fn visit_expr(&mut self, expr: &'b Expr) { - if !self.semantic_model.in_f_string() - && !self.semantic_model.in_deferred_type_definition() - && self.semantic_model.in_type_definition() - && self.semantic_model.future_annotations() + if !self.semantic.in_f_string() + && !self.semantic.in_deferred_type_definition() + && self.semantic.in_type_definition() + && self.semantic.future_annotations() { if let Expr::Constant(ast::ExprConstant { value: Constant::Str(value), @@ -2135,21 +2127,21 @@ where self.deferred.string_type_definitions.push(( expr.range(), value, - self.semantic_model.snapshot(), + self.semantic.snapshot(), )); } else { self.deferred .future_type_definitions - .push((expr, self.semantic_model.snapshot())); + .push((expr, self.semantic.snapshot())); } return; } - self.semantic_model.push_expr(expr); + self.semantic.push_expr(expr); // Store the flags prior to any further descent, so that we can restore them after visiting // the node. - let flags_snapshot = self.semantic_model.flags; + let flags_snapshot = self.semantic.flags; // If we're in a boolean test (e.g., the `test` of a `Stmt::If`), but now within a // subexpression (e.g., `a` in `f(a)`), then we're no longer in a boolean test. @@ -2161,7 +2153,7 @@ where .. }) ) { - self.semantic_model.flags -= SemanticModelFlags::BOOLEAN_TEST; + self.semantic.flags -= SemanticModelFlags::BOOLEAN_TEST; } // Pre-visit. @@ -2172,14 +2164,13 @@ where Rule::FutureRewritableTypeAnnotation, Rule::NonPEP604Annotation, ]) { - if let Some(operator) = - typing::to_pep604_operator(value, slice, &self.semantic_model) + if let Some(operator) = typing::to_pep604_operator(value, slice, &self.semantic) { if self.enabled(Rule::FutureRewritableTypeAnnotation) { if self.settings.target_version < PythonVersion::Py310 && self.settings.target_version >= PythonVersion::Py37 - && !self.semantic_model.future_annotations() - && self.semantic_model.in_annotation() + && !self.semantic.future_annotations() + && self.semantic.in_annotation() { flake8_future_annotations::rules::future_rewritable_type_annotation( self, value, @@ -2189,8 +2180,8 @@ where if self.enabled(Rule::NonPEP604Annotation) { if self.settings.target_version >= PythonVersion::Py310 || (self.settings.target_version >= PythonVersion::Py37 - && self.semantic_model.future_annotations() - && self.semantic_model.in_annotation()) + && self.semantic.future_annotations() + && self.semantic.in_annotation()) { pyupgrade::rules::use_pep604_annotation( self, expr, slice, operator, @@ -2203,9 +2194,9 @@ where // Ex) list[...] if self.enabled(Rule::FutureRequiredTypeAnnotation) { if self.settings.target_version < PythonVersion::Py39 - && !self.semantic_model.future_annotations() - && self.semantic_model.in_annotation() - && typing::is_pep585_generic(value, &self.semantic_model) + && !self.semantic.future_annotations() + && self.semantic.in_annotation() + && typing::is_pep585_generic(value, &self.semantic) { flake8_future_annotations::rules::future_required_type_annotation( self, @@ -2215,8 +2206,8 @@ where } } - if self.semantic_model.match_typing_expr(value, "Literal") { - self.semantic_model.flags |= SemanticModelFlags::LITERAL; + if self.semantic.match_typing_expr(value, "Literal") { + self.semantic.flags |= SemanticModelFlags::LITERAL; } if self.any_enabled(&[ Rule::SysVersionSlice3, @@ -2278,13 +2269,13 @@ where Rule::NonPEP585Annotation, ]) { if let Some(replacement) = - typing::to_pep585_generic(expr, &self.semantic_model) + typing::to_pep585_generic(expr, &self.semantic) { if self.enabled(Rule::FutureRewritableTypeAnnotation) { if self.settings.target_version < PythonVersion::Py39 && self.settings.target_version >= PythonVersion::Py37 - && !self.semantic_model.future_annotations() - && self.semantic_model.in_annotation() + && !self.semantic.future_annotations() + && self.semantic.in_annotation() { flake8_future_annotations::rules::future_rewritable_type_annotation( self, expr, @@ -2294,8 +2285,8 @@ where if self.enabled(Rule::NonPEP585Annotation) { if self.settings.target_version >= PythonVersion::Py39 || (self.settings.target_version >= PythonVersion::Py37 - && self.semantic_model.future_annotations() - && self.semantic_model.in_annotation()) + && self.semantic.future_annotations() + && self.semantic.in_annotation()) { pyupgrade::rules::use_pep585_annotation( self, @@ -2318,7 +2309,7 @@ where } } - if let ScopeKind::Class(class_def) = self.semantic_model.scope().kind { + if let ScopeKind::Class(class_def) = self.semantic.scope().kind { if self.enabled(Rule::BuiltinAttributeShadowing) { flake8_builtins::rules::builtin_attribute_shadowing( self, @@ -2354,13 +2345,12 @@ where Rule::FutureRewritableTypeAnnotation, Rule::NonPEP585Annotation, ]) { - if let Some(replacement) = typing::to_pep585_generic(expr, &self.semantic_model) - { + if let Some(replacement) = typing::to_pep585_generic(expr, &self.semantic) { if self.enabled(Rule::FutureRewritableTypeAnnotation) { if self.settings.target_version < PythonVersion::Py39 && self.settings.target_version >= PythonVersion::Py37 - && !self.semantic_model.future_annotations() - && self.semantic_model.in_annotation() + && !self.semantic.future_annotations() + && self.semantic.in_annotation() { flake8_future_annotations::rules::future_rewritable_type_annotation( self, expr, @@ -2370,8 +2360,8 @@ where if self.enabled(Rule::NonPEP585Annotation) { if self.settings.target_version >= PythonVersion::Py39 || (self.settings.target_version >= PythonVersion::Py37 - && self.semantic_model.future_annotations() - && self.semantic_model.in_annotation()) + && self.semantic.future_annotations() + && self.semantic.in_annotation()) { pyupgrade::rules::use_pep585_annotation(self, expr, &replacement); } @@ -2416,7 +2406,7 @@ where }) => { if let Expr::Name(ast::ExprName { id, ctx, range: _ }) = func.as_ref() { if id == "locals" && matches!(ctx, ExprContext::Load) { - let scope = self.semantic_model.scope_mut(); + let scope = self.semantic.scope_mut(); scope.set_uses_locals(); } } @@ -2748,7 +2738,7 @@ where flake8_comprehensions::rules::unnecessary_map( self, expr, - self.semantic_model.expr_parent(), + self.semantic.expr_parent(), func, args, ); @@ -3151,8 +3141,8 @@ where // Ex) `str | None` if self.enabled(Rule::FutureRequiredTypeAnnotation) { if self.settings.target_version < PythonVersion::Py310 - && !self.semantic_model.future_annotations() - && self.semantic_model.in_annotation() + && !self.semantic.future_annotations() + && self.semantic.in_annotation() { flake8_future_annotations::rules::future_required_type_annotation( self, @@ -3164,8 +3154,8 @@ where if self.is_stub { if self.enabled(Rule::DuplicateUnionMember) - && self.semantic_model.in_type_definition() - && self.semantic_model.expr_parent().map_or(true, |parent| { + && self.semantic.in_type_definition() + && self.semantic.expr_parent().map_or(true, |parent| { !matches!( parent, Expr::BinOp(ast::ExprBinOp { @@ -3316,14 +3306,14 @@ where kind, range: _, }) => { - if self.semantic_model.in_type_definition() - && !self.semantic_model.in_literal() - && !self.semantic_model.in_f_string() + if self.semantic.in_type_definition() + && !self.semantic.in_literal() + && !self.semantic.in_f_string() { self.deferred.string_type_definitions.push(( expr.range(), value, - self.semantic_model.snapshot(), + self.semantic.snapshot(), )); } if self.enabled(Rule::HardcodedBindAllInterfaces) { @@ -3367,7 +3357,7 @@ where for expr in &args.defaults { self.visit_expr(expr); } - self.semantic_model.push_scope(ScopeKind::Lambda(lambda)); + self.semantic.push_scope(ScopeKind::Lambda(lambda)); } Expr::IfExp(ast::ExprIfExp { test, @@ -3541,9 +3531,7 @@ where self.visit_expr(value); } Expr::Lambda(_) => { - self.deferred - .lambdas - .push((expr, self.semantic_model.snapshot())); + self.deferred.lambdas.push((expr, self.semantic.snapshot())); } Expr::IfExp(ast::ExprIfExp { test, @@ -3561,53 +3549,41 @@ where keywords, range: _, }) => { - let callable = self - .semantic_model - .resolve_call_path(func) - .and_then(|call_path| { - if self - .semantic_model - .match_typing_call_path(&call_path, "cast") - { - Some(typing::Callable::Cast) - } else if self - .semantic_model - .match_typing_call_path(&call_path, "NewType") - { - Some(typing::Callable::NewType) - } else if self - .semantic_model - .match_typing_call_path(&call_path, "TypeVar") - { - Some(typing::Callable::TypeVar) - } else if self - .semantic_model - .match_typing_call_path(&call_path, "NamedTuple") - { - Some(typing::Callable::NamedTuple) - } else if self - .semantic_model - .match_typing_call_path(&call_path, "TypedDict") - { - Some(typing::Callable::TypedDict) - } else if [ - "Arg", - "DefaultArg", - "NamedArg", - "DefaultNamedArg", - "VarArg", - "KwArg", - ] - .iter() - .any(|target| call_path.as_slice() == ["mypy_extensions", target]) - { - Some(typing::Callable::MypyExtension) - } else if call_path.as_slice() == ["", "bool"] { - Some(typing::Callable::Bool) - } else { - None - } - }); + let callable = self.semantic.resolve_call_path(func).and_then(|call_path| { + if self.semantic.match_typing_call_path(&call_path, "cast") { + Some(typing::Callable::Cast) + } else if self.semantic.match_typing_call_path(&call_path, "NewType") { + Some(typing::Callable::NewType) + } else if self.semantic.match_typing_call_path(&call_path, "TypeVar") { + Some(typing::Callable::TypeVar) + } else if self + .semantic + .match_typing_call_path(&call_path, "NamedTuple") + { + Some(typing::Callable::NamedTuple) + } else if self + .semantic + .match_typing_call_path(&call_path, "TypedDict") + { + Some(typing::Callable::TypedDict) + } else if [ + "Arg", + "DefaultArg", + "NamedArg", + "DefaultNamedArg", + "VarArg", + "KwArg", + ] + .iter() + .any(|target| call_path.as_slice() == ["mypy_extensions", target]) + { + Some(typing::Callable::MypyExtension) + } else if call_path.as_slice() == ["", "bool"] { + Some(typing::Callable::Bool) + } else { + None + } + }); match callable { Some(typing::Callable::Bool) => { self.visit_expr(func); @@ -3788,15 +3764,15 @@ where // `obj["foo"]["bar"]`, we need to avoid treating the `obj["foo"]` // portion as an annotation, despite having `ExprContext::Load`. Thus, we track // the `ExprContext` at the top-level. - if self.semantic_model.in_subscript() { + if self.semantic.in_subscript() { visitor::walk_expr(self, expr); } else if matches!(ctx, ExprContext::Store | ExprContext::Del) { - self.semantic_model.flags |= SemanticModelFlags::SUBSCRIPT; + self.semantic.flags |= SemanticModelFlags::SUBSCRIPT; visitor::walk_expr(self, expr); } else { match typing::match_annotated_subscript( value, - &self.semantic_model, + &self.semantic, self.settings.typing_modules.iter().map(String::as_str), &self.settings.pyflakes.extend_generics, ) { @@ -3840,7 +3816,7 @@ where } } Expr::JoinedStr(_) => { - self.semantic_model.flags |= if self.semantic_model.in_f_string() { + self.semantic.flags |= if self.semantic.in_f_string() { SemanticModelFlags::NESTED_F_STRING } else { SemanticModelFlags::F_STRING @@ -3857,13 +3833,13 @@ where | Expr::ListComp(_) | Expr::DictComp(_) | Expr::SetComp(_) => { - self.semantic_model.pop_scope(); + self.semantic.pop_scope(); } _ => {} }; - self.semantic_model.flags = flags_snapshot; - self.semantic_model.pop_expr(); + self.semantic.flags = flags_snapshot; + self.semantic.pop_expr(); } fn visit_excepthandler(&mut self, excepthandler: &'b Excepthandler) { @@ -3963,7 +3939,7 @@ where ); // If the exception name wasn't used in the scope, emit a diagnostic. - if !self.semantic_model.is_used(binding_id) { + if !self.semantic.is_used(binding_id) { if self.enabled(Rule::UnusedVariable) { let mut diagnostic = Diagnostic::new( pyflakes::rules::UnusedVariable { name: name.into() }, @@ -4096,18 +4072,18 @@ where flake8_pie::rules::no_unnecessary_pass(self, body); } - let prev_body = self.semantic_model.body; - let prev_body_index = self.semantic_model.body_index; - self.semantic_model.body = body; - self.semantic_model.body_index = 0; + let prev_body = self.semantic.body; + let prev_body_index = self.semantic.body_index; + self.semantic.body = body; + self.semantic.body_index = 0; for stmt in body { self.visit_stmt(stmt); - self.semantic_model.body_index += 1; + self.semantic.body_index += 1; } - self.semantic_model.body = prev_body; - self.semantic_model.body_index = prev_body_index; + self.semantic.body = prev_body; + self.semantic.body_index = prev_body_index; } } @@ -4158,7 +4134,7 @@ impl<'a> Checker<'a> { // while all subsequent reads and writes are evaluated in the inner scope. In particular, // `x` is local to `foo`, and the `T` in `y=T` skips the class scope when resolving. self.visit_expr(&generator.iter); - self.semantic_model.push_scope(ScopeKind::Generator); + self.semantic.push_scope(ScopeKind::Generator); self.visit_expr(&generator.target); for expr in &generator.ifs { self.visit_boolean_test(expr); @@ -4175,36 +4151,36 @@ impl<'a> Checker<'a> { /// Visit an body of [`Stmt`] nodes within a type-checking block. fn visit_type_checking_block(&mut self, body: &'a [Stmt]) { - let snapshot = self.semantic_model.flags; - self.semantic_model.flags |= SemanticModelFlags::TYPE_CHECKING_BLOCK; + let snapshot = self.semantic.flags; + self.semantic.flags |= SemanticModelFlags::TYPE_CHECKING_BLOCK; self.visit_body(body); - self.semantic_model.flags = snapshot; + self.semantic.flags = snapshot; } /// Visit an [`Expr`], and treat it as a type definition. fn visit_type_definition(&mut self, expr: &'a Expr) { - let snapshot = self.semantic_model.flags; - self.semantic_model.flags |= SemanticModelFlags::TYPE_DEFINITION; + let snapshot = self.semantic.flags; + self.semantic.flags |= SemanticModelFlags::TYPE_DEFINITION; self.visit_expr(expr); - self.semantic_model.flags = snapshot; + self.semantic.flags = snapshot; } /// Visit an [`Expr`], and treat it as _not_ a type definition. fn visit_non_type_definition(&mut self, expr: &'a Expr) { - let snapshot = self.semantic_model.flags; - self.semantic_model.flags -= SemanticModelFlags::TYPE_DEFINITION; + let snapshot = self.semantic.flags; + self.semantic.flags -= SemanticModelFlags::TYPE_DEFINITION; self.visit_expr(expr); - self.semantic_model.flags = snapshot; + self.semantic.flags = snapshot; } /// Visit an [`Expr`], and treat it as a boolean test. This is useful for detecting whether an /// expressions return value is significant, or whether the calling context only relies on /// its truthiness. fn visit_boolean_test(&mut self, expr: &'a Expr) { - let snapshot = self.semantic_model.flags; - self.semantic_model.flags |= SemanticModelFlags::BOOLEAN_TEST; + let snapshot = self.semantic.flags; + self.semantic.flags |= SemanticModelFlags::BOOLEAN_TEST; self.visit_expr(expr); - self.semantic_model.flags = snapshot; + self.semantic.flags = snapshot; } /// Add a [`Binding`] to the current scope, bound to the given name. @@ -4220,28 +4196,28 @@ impl<'a> Checker<'a> { // expressions in generators and comprehensions bind to the scope that contains the // outermost comprehension. let scope_id = if kind.is_named_expr_assignment() { - self.semantic_model + self.semantic .scopes - .ancestor_ids(self.semantic_model.scope_id) - .find_or_last(|scope_id| !self.semantic_model.scopes[*scope_id].kind.is_generator()) - .unwrap_or(self.semantic_model.scope_id) + .ancestor_ids(self.semantic.scope_id) + .find_or_last(|scope_id| !self.semantic.scopes[*scope_id].kind.is_generator()) + .unwrap_or(self.semantic.scope_id) } else { - self.semantic_model.scope_id + self.semantic.scope_id }; // Create the `Binding`. - let binding_id = self.semantic_model.push_binding(range, kind, flags); - let binding = self.semantic_model.binding(binding_id); + let binding_id = self.semantic.push_binding(range, kind, flags); + let binding = self.semantic.binding(binding_id); // Determine whether the binding shadows any existing bindings. if let Some((stack_index, shadowed_id)) = self - .semantic_model + .semantic .scopes - .ancestors(self.semantic_model.scope_id) + .ancestors(self.semantic.scope_id) .enumerate() .find_map(|(stack_index, scope)| { scope.get(name).and_then(|binding_id| { - let binding = self.semantic_model.binding(binding_id); + let binding = self.semantic.binding(binding_id); if binding.is_unbound() { None } else { @@ -4250,12 +4226,12 @@ impl<'a> Checker<'a> { }) }) { - let shadowed = self.semantic_model.binding(shadowed_id); + let shadowed = self.semantic.binding(shadowed_id); let in_current_scope = stack_index == 0; if !shadowed.kind.is_builtin() && shadowed.source.map_or(true, |left| { binding.source.map_or(true, |right| { - !branch_detection::different_forks(left, right, &self.semantic_model.stmts) + !branch_detection::different_forks(left, right, &self.semantic.stmts) }) }) { @@ -4285,18 +4261,14 @@ impl<'a> Checker<'a> { && (!self.settings.dummy_variable_rgx.is_match(name) || shadows_import) && !(shadowed.kind.is_function_definition() && visibility::is_overload( - &self.semantic_model, - cast::decorator_list( - self.semantic_model.stmts[shadowed.source.unwrap()], - ), + cast::decorator_list(self.semantic.stmts[shadowed.source.unwrap()]), + &self.semantic, )) { if self.enabled(Rule::RedefinedWhileUnused) { #[allow(deprecated)] let line = self.locator.compute_line_index( - shadowed - .trimmed_range(&self.semantic_model, self.locator) - .start(), + shadowed.trimmed_range(&self.semantic, self.locator).start(), ); let mut diagnostic = Diagnostic::new( @@ -4304,16 +4276,16 @@ impl<'a> Checker<'a> { name: name.to_string(), line, }, - binding.trimmed_range(&self.semantic_model, self.locator), + binding.trimmed_range(&self.semantic, self.locator), ); - if let Some(range) = binding.parent_range(&self.semantic_model) { + if let Some(range) = binding.parent_range(&self.semantic) { diagnostic.set_parent(range.start()); } self.diagnostics.push(diagnostic); } } } else if shadows_import && binding.redefines(shadowed) { - self.semantic_model + self.semantic .shadowed_bindings .insert(binding_id, shadowed_id); } @@ -4321,16 +4293,16 @@ impl<'a> Checker<'a> { } // If there's an existing binding in this scope, copy its references. - if let Some(shadowed_id) = self.semantic_model.scopes[scope_id].get(name) { + if let Some(shadowed_id) = self.semantic.scopes[scope_id].get(name) { // If this is an annotation, and we already have an existing value in the same scope, // don't treat it as an assignment, but track it as a delayed annotation. - if self.semantic_model.binding(binding_id).kind.is_annotation() { - self.semantic_model + if self.semantic.binding(binding_id).kind.is_annotation() { + self.semantic .add_delayed_annotation(shadowed_id, binding_id); return binding_id; } - let shadowed = &self.semantic_model.bindings[shadowed_id]; + let shadowed = &self.semantic.bindings[shadowed_id]; match &shadowed.kind { BindingKind::Builtin | BindingKind::Deletion | BindingKind::UnboundException => { // Avoid overriding builtins. @@ -4339,18 +4311,18 @@ impl<'a> Checker<'a> { // If the original binding was a global or nonlocal, then the new binding is // too. let references = shadowed.references.clone(); - self.semantic_model.bindings[binding_id].kind = kind.clone(); - self.semantic_model.bindings[binding_id].references = references; + self.semantic.bindings[binding_id].kind = kind.clone(); + self.semantic.bindings[binding_id].references = references; } _ => { let references = shadowed.references.clone(); - self.semantic_model.bindings[binding_id].references = references; + self.semantic.bindings[binding_id].references = references; } } } // Add the binding to the scope. - let scope = &mut self.semantic_model.scopes[scope_id]; + let scope = &mut self.semantic.scopes[scope_id]; scope.add(name, binding_id); binding_id @@ -4364,8 +4336,8 @@ impl<'a> Checker<'a> { .chain(self.settings.builtins.iter().map(String::as_str)) { // Add the builtin to the scope. - let binding_id = self.semantic_model.push_builtin(); - let scope = self.semantic_model.scope_mut(); + let binding_id = self.semantic.push_builtin(); + let scope = self.semantic.scope_mut(); scope.add(builtin, binding_id); } } @@ -4374,7 +4346,7 @@ impl<'a> Checker<'a> { let Expr::Name(ast::ExprName { id, .. }) = expr else { return; }; - match self.semantic_model.resolve_read(id, expr.range()) { + match self.semantic.resolve_read(id, expr.range()) { ResolvedRead::Resolved(_) | ResolvedRead::ImplicitGlobal => { // Nothing to do. } @@ -4382,7 +4354,7 @@ impl<'a> Checker<'a> { // F405 if self.enabled(Rule::UndefinedLocalWithImportStarUsage) { let sources: Vec = self - .semantic_model + .semantic .scopes .iter() .flat_map(Scope::star_imports) @@ -4411,7 +4383,7 @@ impl<'a> Checker<'a> { // Avoid flagging if `NameError` is handled. if self - .semantic_model + .semantic .handled_exceptions .iter() .any(|handler_names| handler_names.contains(Exceptions::NAME_ERROR)) @@ -4431,37 +4403,30 @@ impl<'a> Checker<'a> { } fn handle_node_store(&mut self, id: &'a str, expr: &Expr) { - let parent = self.semantic_model.stmt(); + let parent = self.semantic.stmt(); if self.enabled(Rule::UndefinedLocal) { pyflakes::rules::undefined_local(self, id); } if self.enabled(Rule::NonLowercaseVariableInFunction) { - if self.semantic_model.scope().kind.is_any_function() { + if self.semantic.scope().kind.is_any_function() { // Ignore globals. - if !self - .semantic_model - .scope() - .get(id) - .map_or(false, |binding_id| { - self.semantic_model.binding(binding_id).kind.is_global() - }) - { + if !self.semantic.scope().get(id).map_or(false, |binding_id| { + self.semantic.binding(binding_id).kind.is_global() + }) { pep8_naming::rules::non_lowercase_variable_in_function(self, expr, parent, id); } } } if self.enabled(Rule::MixedCaseVariableInClassScope) { - if let ScopeKind::Class(ast::StmtClassDef { bases, .. }) = - &self.semantic_model.scope().kind - { + if let ScopeKind::Class(ast::StmtClassDef { bases, .. }) = &self.semantic.scope().kind { pep8_naming::rules::mixed_case_variable_in_class_scope( self, expr, parent, id, bases, ); } } if self.enabled(Rule::MixedCaseVariableInGlobalScope) { - if matches!(self.semantic_model.scope().kind, ScopeKind::Module) { + if matches!(self.semantic.scope().kind, ScopeKind::Module) { pep8_naming::rules::mixed_case_variable_in_global_scope(self, expr, parent, id); } } @@ -4499,7 +4464,7 @@ impl<'a> Checker<'a> { return; } - let scope = self.semantic_model.scope(); + let scope = self.semantic.scope(); if scope.kind.is_module() && match parent { @@ -4527,8 +4492,7 @@ impl<'a> Checker<'a> { _ => false, } { - let (names, flags) = - extract_all_names(parent, |name| self.semantic_model.is_builtin(name)); + let (names, flags) = extract_all_names(parent, |name| self.semantic.is_builtin(name)); if self.enabled(Rule::InvalidAllFormat) { if matches!(flags, AllNamesFlags::INVALID_FORMAT) { @@ -4554,7 +4518,7 @@ impl<'a> Checker<'a> { } if self - .semantic_model + .semantic .expr_ancestors() .any(|expr| matches!(expr, Expr::NamedExpr(_))) { @@ -4581,16 +4545,13 @@ impl<'a> Checker<'a> { }; // Treat the deletion of a name as a reference to that name. - if let Some(binding_id) = self.semantic_model.scope().get(id) { - self.semantic_model.add_local_reference( - binding_id, - expr.range(), - ExecutionContext::Runtime, - ); + if let Some(binding_id) = self.semantic.scope().get(id) { + self.semantic + .add_local_reference(binding_id, expr.range(), ExecutionContext::Runtime); // If the name is unbound, then it's an error. if self.enabled(Rule::UndefinedName) { - let binding = self.semantic_model.binding(binding_id); + let binding = self.semantic.binding(binding_id); if binding.is_unbound() { self.diagnostics.push(Diagnostic::new( pyflakes::rules::UndefinedName { @@ -4612,17 +4573,15 @@ impl<'a> Checker<'a> { } } - if helpers::on_conditional_branch(&mut self.semantic_model.parents()) { + if helpers::on_conditional_branch(&mut self.semantic.parents()) { return; } // Create a binding to model the deletion. - let binding_id = self.semantic_model.push_binding( - expr.range(), - BindingKind::Deletion, - BindingFlags::empty(), - ); - let scope = self.semantic_model.scope_mut(); + let binding_id = + self.semantic + .push_binding(expr.range(), BindingKind::Deletion, BindingFlags::empty()); + let scope = self.semantic.scope_mut(); scope.add(id, binding_id); } @@ -4630,9 +4589,9 @@ impl<'a> Checker<'a> { while !self.deferred.future_type_definitions.is_empty() { let type_definitions = std::mem::take(&mut self.deferred.future_type_definitions); for (expr, snapshot) in type_definitions { - self.semantic_model.restore(snapshot); + self.semantic.restore(snapshot); - self.semantic_model.flags |= SemanticModelFlags::TYPE_DEFINITION + self.semantic.flags |= SemanticModelFlags::TYPE_DEFINITION | SemanticModelFlags::FUTURE_TYPE_DEFINITION; self.visit_expr(expr); } @@ -4646,11 +4605,9 @@ impl<'a> Checker<'a> { if let Ok((expr, kind)) = parse_type_annotation(value, range, self.locator) { let expr = allocator.alloc(expr); - self.semantic_model.restore(snapshot); + self.semantic.restore(snapshot); - if self.semantic_model.in_annotation() - && self.semantic_model.future_annotations() - { + if self.semantic.in_annotation() && self.semantic.future_annotations() { if self.enabled(Rule::QuotedAnnotation) { pyupgrade::rules::quoted_annotation(self, value, range); } @@ -4668,7 +4625,7 @@ impl<'a> Checker<'a> { } }; - self.semantic_model.flags |= + self.semantic.flags |= SemanticModelFlags::TYPE_DEFINITION | type_definition_flag; self.visit_expr(expr); } else { @@ -4689,9 +4646,9 @@ impl<'a> Checker<'a> { while !self.deferred.functions.is_empty() { let deferred_functions = std::mem::take(&mut self.deferred.functions); for snapshot in deferred_functions { - self.semantic_model.restore(snapshot); + self.semantic.restore(snapshot); - match &self.semantic_model.stmt() { + match &self.semantic.stmt() { Stmt::FunctionDef(ast::StmtFunctionDef { body, args, .. }) | Stmt::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, args, .. }) => { self.visit_arguments(args); @@ -4711,7 +4668,7 @@ impl<'a> Checker<'a> { while !self.deferred.lambdas.is_empty() { let lambdas = std::mem::take(&mut self.deferred.lambdas); for (expr, snapshot) in lambdas { - self.semantic_model.restore(snapshot); + self.semantic.restore(snapshot); if let Expr::Lambda(ast::ExprLambda { args, @@ -4734,13 +4691,13 @@ impl<'a> Checker<'a> { while !self.deferred.assignments.is_empty() { let assignments = std::mem::take(&mut self.deferred.assignments); for snapshot in assignments { - self.semantic_model.restore(snapshot); + self.semantic.restore(snapshot); if self.enabled(Rule::UnusedVariable) { - pyflakes::rules::unused_variable(self, self.semantic_model.scope_id); + pyflakes::rules::unused_variable(self, self.semantic.scope_id); } if self.enabled(Rule::UnusedAnnotation) { - pyflakes::rules::unused_annotation(self, self.semantic_model.scope_id); + pyflakes::rules::unused_annotation(self, self.semantic.scope_id); } if !self.is_stub { if self.any_enabled(&[ @@ -4750,8 +4707,8 @@ impl<'a> Checker<'a> { Rule::UnusedStaticMethodArgument, Rule::UnusedLambdaArgument, ]) { - let scope = &self.semantic_model.scopes[self.semantic_model.scope_id]; - let parent = &self.semantic_model.scopes[scope.parent.unwrap()]; + let scope = &self.semantic.scopes[self.semantic.scope_id]; + let parent = &self.semantic.scopes[scope.parent.unwrap()]; self.diagnostics .extend(flake8_unused_arguments::rules::unused_arguments( self, parent, scope, @@ -4767,11 +4724,10 @@ impl<'a> Checker<'a> { let for_loops = std::mem::take(&mut self.deferred.for_loops); for snapshot in for_loops { - self.semantic_model.restore(snapshot); + self.semantic.restore(snapshot); if let Stmt::For(ast::StmtFor { target, body, .. }) - | Stmt::AsyncFor(ast::StmtAsyncFor { target, body, .. }) = - &self.semantic_model.stmt() + | Stmt::AsyncFor(ast::StmtAsyncFor { target, body, .. }) = &self.semantic.stmt() { if self.enabled(Rule::UnusedLoopControlVariable) { flake8_bugbear::rules::unused_loop_control_variable(self, target, body); @@ -4806,10 +4762,10 @@ impl<'a> Checker<'a> { // Mark anything referenced in `__all__` as used. let exports: Vec<(&str, TextRange)> = { - self.semantic_model + self.semantic .global_scope() .get_all("__all__") - .map(|binding_id| &self.semantic_model.bindings[binding_id]) + .map(|binding_id| &self.semantic.bindings[binding_id]) .filter_map(|binding| match &binding.kind { BindingKind::Export(Export { names }) => { Some(names.iter().map(|name| (*name, binding.range))) @@ -4821,12 +4777,9 @@ impl<'a> Checker<'a> { }; for (name, range) in &exports { - if let Some(binding_id) = self.semantic_model.global_scope().get(name) { - self.semantic_model.add_global_reference( - binding_id, - *range, - ExecutionContext::Runtime, - ); + if let Some(binding_id) = self.semantic.global_scope().get(name) { + self.semantic + .add_global_reference(binding_id, *range, ExecutionContext::Runtime); } } @@ -4837,17 +4790,17 @@ impl<'a> Checker<'a> { if self.settings.flake8_type_checking.strict { vec![] } else { - self.semantic_model + self.semantic .scopes .iter() .map(|scope| { scope .binding_ids() - .map(|binding_id| self.semantic_model.binding(binding_id)) + .map(|binding_id| self.semantic.binding(binding_id)) .filter(|binding| { flake8_type_checking::helpers::is_valid_runtime_import( - &self.semantic_model, binding, + &self.semantic, ) }) .collect() @@ -4859,8 +4812,8 @@ impl<'a> Checker<'a> { }; let mut diagnostics: Vec = vec![]; - for scope_id in self.semantic_model.dead_scopes.iter().rev() { - let scope = &self.semantic_model.scopes[*scope_id]; + for scope_id in self.semantic.dead_scopes.iter().rev() { + let scope = &self.semantic.scopes[*scope_id]; if scope.kind.is_module() { // F822 @@ -4902,10 +4855,10 @@ impl<'a> Checker<'a> { // PLW0602 if self.enabled(Rule::GlobalVariableNotAssigned) { for (name, binding_id) in scope.bindings() { - let binding = self.semantic_model.binding(binding_id); + let binding = self.semantic.binding(binding_id); if binding.kind.is_global() { if let Some(source) = binding.source { - let stmt = &self.semantic_model.stmts[source]; + let stmt = &self.semantic.stmts[source]; if stmt.is_global_stmt() { diagnostics.push(Diagnostic::new( pylint::rules::GlobalVariableNotAssigned { @@ -4929,28 +4882,26 @@ impl<'a> Checker<'a> { // the bindings are in different scopes. if self.enabled(Rule::RedefinedWhileUnused) { for (name, binding_id) in scope.bindings() { - if let Some(shadowed_id) = self.semantic_model.shadowed_binding(binding_id) { - let shadowed = self.semantic_model.binding(shadowed_id); + if let Some(shadowed_id) = self.semantic.shadowed_binding(binding_id) { + let shadowed = self.semantic.binding(shadowed_id); if shadowed.is_used() { continue; } #[allow(deprecated)] let line = self.locator.compute_line_index( - shadowed - .trimmed_range(&self.semantic_model, self.locator) - .start(), + shadowed.trimmed_range(&self.semantic, self.locator).start(), ); - let binding = self.semantic_model.binding(binding_id); + let binding = self.semantic.binding(binding_id); let mut diagnostic = Diagnostic::new( pyflakes::rules::RedefinedWhileUnused { name: (*name).to_string(), line, }, - binding.trimmed_range(&self.semantic_model, self.locator), + binding.trimmed_range(&self.semantic, self.locator), ); - if let Some(range) = binding.parent_range(&self.semantic_model) { + if let Some(range) = binding.parent_range(&self.semantic) { diagnostic.set_parent(range.start()); } diagnostics.push(diagnostic); @@ -4962,7 +4913,7 @@ impl<'a> Checker<'a> { let runtime_imports: Vec<&Binding> = if self.settings.flake8_type_checking.strict { vec![] } else { - self.semantic_model + self.semantic .scopes .ancestor_ids(*scope_id) .flat_map(|scope_id| runtime_imports[scope_id.as_usize()].iter()) @@ -5067,10 +5018,10 @@ impl<'a> Checker<'a> { // Compute visibility of all definitions. let exports: Option> = { - let global_scope = self.semantic_model.global_scope(); + let global_scope = self.semantic.global_scope(); global_scope .get_all("__all__") - .map(|binding_id| &self.semantic_model.bindings[binding_id]) + .map(|binding_id| &self.semantic.bindings[binding_id]) .filter_map(|binding| match &binding.kind { BindingKind::Export(Export { names }) => Some(names.iter().copied()), _ => None, @@ -5080,7 +5031,7 @@ impl<'a> Checker<'a> { }) }; - let definitions = std::mem::take(&mut self.semantic_model.definitions); + let definitions = std::mem::take(&mut self.semantic.definitions); let mut overloaded_name: Option = None; for ContextualizedDefinition { definition, @@ -5098,9 +5049,9 @@ impl<'a> Checker<'a> { // classes, etc.). if !overloaded_name.map_or(false, |overloaded_name| { flake8_annotations::helpers::is_overload_impl( - &self.semantic_model, definition, &overloaded_name, + &self.semantic, ) }) { self.diagnostics @@ -5111,7 +5062,7 @@ impl<'a> Checker<'a> { )); } overloaded_name = - flake8_annotations::helpers::overloaded_name(&self.semantic_model, definition); + flake8_annotations::helpers::overloaded_name(definition, &self.semantic); } // flake8-pyi @@ -5129,9 +5080,9 @@ impl<'a> Checker<'a> { // pydocstyle if enforce_docstrings { if pydocstyle::helpers::should_ignore_definition( - &self.semantic_model, definition, &self.settings.pydocstyle.ignore_decorators, + &self.semantic, ) { continue; } @@ -5335,8 +5286,8 @@ pub(crate) fn check_ast( checker.check_definitions(); // Reset the scope to module-level, and check all consumed scopes. - checker.semantic_model.scope_id = ScopeId::global(); - checker.semantic_model.dead_scopes.push(ScopeId::global()); + checker.semantic.scope_id = ScopeId::global(); + checker.semantic.dead_scopes.push(ScopeId::global()); checker.check_dead_scopes(); checker.diagnostics diff --git a/crates/ruff/src/importer/mod.rs b/crates/ruff/src/importer/mod.rs index b31d97a066..b7a67141b6 100644 --- a/crates/ruff/src/importer/mod.rs +++ b/crates/ruff/src/importer/mod.rs @@ -116,7 +116,7 @@ impl<'a> Importer<'a> { &self, import: &StmtImports, at: TextSize, - semantic_model: &SemanticModel, + semantic: &SemanticModel, ) -> Result { // Generate the modified import statement. let content = autofix::codemods::retain_imports( @@ -130,7 +130,7 @@ impl<'a> Importer<'a> { let (type_checking_edit, type_checking) = self.get_or_import_symbol( &ImportRequest::import_from("typing", "TYPE_CHECKING"), at, - semantic_model, + semantic, )?; // Add the import to a `TYPE_CHECKING` block. @@ -164,11 +164,11 @@ impl<'a> Importer<'a> { &self, symbol: &ImportRequest, at: TextSize, - semantic_model: &SemanticModel, + semantic: &SemanticModel, ) -> Result<(Edit, String), ResolutionError> { - match self.get_symbol(symbol, at, semantic_model) { + match self.get_symbol(symbol, at, semantic) { Some(result) => result, - None => self.import_symbol(symbol, at, semantic_model), + None => self.import_symbol(symbol, at, semantic), } } @@ -177,11 +177,10 @@ impl<'a> Importer<'a> { &self, symbol: &ImportRequest, at: TextSize, - semantic_model: &SemanticModel, + semantic: &SemanticModel, ) -> Option> { // If the symbol is already available in the current scope, use it. - let imported_name = - semantic_model.resolve_qualified_import_name(symbol.module, symbol.member)?; + let imported_name = semantic.resolve_qualified_import_name(symbol.module, symbol.member)?; // If the symbol source (i.e., the import statement) comes after the current location, // abort. For example, we could be generating an edit within a function, and the import @@ -196,7 +195,7 @@ impl<'a> Importer<'a> { // If the symbol source (i.e., the import statement) is in a typing-only context, but we're // in a runtime context, abort. - if imported_name.context().is_typing() && semantic_model.execution_context().is_runtime() { + if imported_name.context().is_typing() && semantic.execution_context().is_runtime() { return Some(Err(ResolutionError::IncompatibleContext)); } @@ -233,13 +232,13 @@ impl<'a> Importer<'a> { &self, symbol: &ImportRequest, at: TextSize, - semantic_model: &SemanticModel, + semantic: &SemanticModel, ) -> Result<(Edit, String), ResolutionError> { if let Some(stmt) = self.find_import_from(symbol.module, at) { // Case 1: `from functools import lru_cache` is in scope, and we're trying to reference // `functools.cache`; thus, we add `cache` to the import, and return `"cache"` as the // bound name. - if semantic_model.is_available(symbol.member) { + if semantic.is_available(symbol.member) { let Ok(import_edit) = self.add_member(stmt, symbol.member) else { return Err(ResolutionError::InvalidEdit); }; @@ -252,7 +251,7 @@ impl<'a> Importer<'a> { ImportStyle::Import => { // Case 2a: No `functools` import is in scope; thus, we add `import functools`, // and return `"functools.cache"` as the bound name. - if semantic_model.is_available(symbol.module) { + if semantic.is_available(symbol.module) { let import_edit = self.add_import(&AnyImport::Import(Import::module(symbol.module)), at); Ok(( @@ -270,7 +269,7 @@ impl<'a> Importer<'a> { ImportStyle::ImportFrom => { // Case 2b: No `functools` import is in scope; thus, we add // `from functools import cache`, and return `"cache"` as the bound name. - if semantic_model.is_available(symbol.member) { + if semantic.is_available(symbol.member) { let import_edit = self.add_import( &AnyImport::ImportFrom(ImportFrom::member( symbol.module, diff --git a/crates/ruff/src/rules/airflow/rules/task_variable_name.rs b/crates/ruff/src/rules/airflow/rules/task_variable_name.rs index eae2490138..419053c2c3 100644 --- a/crates/ruff/src/rules/airflow/rules/task_variable_name.rs +++ b/crates/ruff/src/rules/airflow/rules/task_variable_name.rs @@ -67,7 +67,7 @@ pub(crate) fn variable_name_task_id( // If the function doesn't come from Airflow, we can't do anything. if !checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| matches!(call_path[0], "airflow")) { diff --git a/crates/ruff/src/rules/flake8_2020/helpers.rs b/crates/ruff/src/rules/flake8_2020/helpers.rs index 81f3e83383..3f86f9bfd9 100644 --- a/crates/ruff/src/rules/flake8_2020/helpers.rs +++ b/crates/ruff/src/rules/flake8_2020/helpers.rs @@ -2,8 +2,8 @@ use rustpython_parser::ast::Expr; use ruff_python_semantic::SemanticModel; -pub(super) fn is_sys(model: &SemanticModel, expr: &Expr, target: &str) -> bool { - model +pub(super) fn is_sys(expr: &Expr, target: &str, semantic: &SemanticModel) -> bool { + semantic .resolve_call_path(expr) .map_or(false, |call_path| call_path.as_slice() == ["sys", target]) } diff --git a/crates/ruff/src/rules/flake8_2020/rules/compare.rs b/crates/ruff/src/rules/flake8_2020/rules/compare.rs index 9877be4fae..185551481c 100644 --- a/crates/ruff/src/rules/flake8_2020/rules/compare.rs +++ b/crates/ruff/src/rules/flake8_2020/rules/compare.rs @@ -69,7 +69,7 @@ impl Violation for SysVersionCmpStr10 { pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &[Expr]) { match left { Expr::Subscript(ast::ExprSubscript { value, slice, .. }) - if is_sys(checker.semantic_model(), value, "version_info") => + if is_sys(value, "version_info", checker.semantic()) => { if let Expr::Constant(ast::ExprConstant { value: Constant::Int(i), @@ -111,7 +111,7 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], compara } Expr::Attribute(ast::ExprAttribute { value, attr, .. }) - if is_sys(checker.semantic_model(), value, "version_info") && attr == "minor" => + if is_sys(value, "version_info", checker.semantic()) && attr == "minor" => { if let ( [Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE], @@ -132,7 +132,7 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], compara _ => {} } - if is_sys(checker.semantic_model(), left, "version") { + if is_sys(left, "version", checker.semantic()) { if let ( [Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE], [Expr::Constant(ast::ExprConstant { diff --git a/crates/ruff/src/rules/flake8_2020/rules/name_or_attribute.rs b/crates/ruff/src/rules/flake8_2020/rules/name_or_attribute.rs index d861abd262..e8afff1335 100644 --- a/crates/ruff/src/rules/flake8_2020/rules/name_or_attribute.rs +++ b/crates/ruff/src/rules/flake8_2020/rules/name_or_attribute.rs @@ -18,7 +18,7 @@ impl Violation for SixPY3 { /// YTT202 pub(crate) fn name_or_attribute(checker: &mut Checker, expr: &Expr) { if checker - .semantic_model() + .semantic() .resolve_call_path(expr) .map_or(false, |call_path| call_path.as_slice() == ["six", "PY3"]) { diff --git a/crates/ruff/src/rules/flake8_2020/rules/subscript.rs b/crates/ruff/src/rules/flake8_2020/rules/subscript.rs index b55a602423..71d6768c86 100644 --- a/crates/ruff/src/rules/flake8_2020/rules/subscript.rs +++ b/crates/ruff/src/rules/flake8_2020/rules/subscript.rs @@ -50,7 +50,7 @@ impl Violation for SysVersionSlice1 { /// YTT101, YTT102, YTT301, YTT303 pub(crate) fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) { - if is_sys(checker.semantic_model(), value, "version") { + if is_sys(value, "version", checker.semantic()) { match slice { Expr::Slice(ast::ExprSlice { lower: None, diff --git a/crates/ruff/src/rules/flake8_annotations/helpers.rs b/crates/ruff/src/rules/flake8_annotations/helpers.rs index 7a3bd1bb15..c3db27fa2f 100644 --- a/crates/ruff/src/rules/flake8_annotations/helpers.rs +++ b/crates/ruff/src/rules/flake8_annotations/helpers.rs @@ -35,14 +35,14 @@ pub(super) fn match_function_def( } /// Return the name of the function, if it's overloaded. -pub(crate) fn overloaded_name(model: &SemanticModel, definition: &Definition) -> Option { +pub(crate) fn overloaded_name(definition: &Definition, semantic: &SemanticModel) -> Option { if let Definition::Member(Member { kind: MemberKind::Function | MemberKind::NestedFunction | MemberKind::Method, stmt, .. }) = definition { - if visibility::is_overload(model, cast::decorator_list(stmt)) { + if visibility::is_overload(cast::decorator_list(stmt), semantic) { let (name, ..) = match_function_def(stmt); Some(name.to_string()) } else { @@ -56,9 +56,9 @@ pub(crate) fn overloaded_name(model: &SemanticModel, definition: &Definition) -> /// Return `true` if the definition is the implementation for an overloaded /// function. pub(crate) fn is_overload_impl( - model: &SemanticModel, definition: &Definition, overloaded_name: &str, + semantic: &SemanticModel, ) -> bool { if let Definition::Member(Member { kind: MemberKind::Function | MemberKind::NestedFunction | MemberKind::Method, @@ -66,7 +66,7 @@ pub(crate) fn is_overload_impl( .. }) = definition { - if visibility::is_overload(model, cast::decorator_list(stmt)) { + if visibility::is_overload(cast::decorator_list(stmt), semantic) { false } else { let (name, ..) = match_function_def(stmt); diff --git a/crates/ruff/src/rules/flake8_annotations/rules/definition.rs b/crates/ruff/src/rules/flake8_annotations/rules/definition.rs index 53498e5058..a5313ec9be 100644 --- a/crates/ruff/src/rules/flake8_annotations/rules/definition.rs +++ b/crates/ruff/src/rules/flake8_annotations/rules/definition.rs @@ -431,15 +431,15 @@ fn is_none_returning(body: &[Stmt]) -> bool { /// ANN401 fn check_dynamically_typed( - model: &SemanticModel, annotation: &Expr, func: F, diagnostics: &mut Vec, is_overridden: bool, + semantic: &SemanticModel, ) where F: FnOnce() -> String, { - if !is_overridden && model.match_typing_expr(annotation, "Any") { + if !is_overridden && semantic.match_typing_expr(annotation, "Any") { diagnostics.push(Diagnostic::new( AnyType { name: func() }, annotation.range(), @@ -480,7 +480,7 @@ pub(crate) fn definition( // unless configured to suppress ANN* for declarations that are fully untyped. let mut diagnostics = Vec::new(); - let is_overridden = visibility::is_override(checker.semantic_model(), decorator_list); + let is_overridden = visibility::is_override(decorator_list, checker.semantic()); // ANN001, ANN401 for arg in args @@ -492,10 +492,7 @@ pub(crate) fn definition( // If this is a non-static method, skip `cls` or `self`. usize::from( is_method - && !visibility::is_staticmethod( - checker.semantic_model(), - cast::decorator_list(stmt), - ), + && !visibility::is_staticmethod(cast::decorator_list(stmt), checker.semantic()), ), ) { @@ -504,11 +501,11 @@ pub(crate) fn definition( has_any_typed_arg = true; if checker.enabled(Rule::AnyType) { check_dynamically_typed( - checker.semantic_model(), annotation, || arg.arg.to_string(), &mut diagnostics, is_overridden, + checker.semantic(), ); } } else { @@ -535,11 +532,11 @@ pub(crate) fn definition( if checker.enabled(Rule::AnyType) { let name = &arg.arg; check_dynamically_typed( - checker.semantic_model(), expr, || format!("*{name}"), &mut diagnostics, is_overridden, + checker.semantic(), ); } } @@ -567,11 +564,11 @@ pub(crate) fn definition( if checker.enabled(Rule::AnyType) { let name = &arg.arg; check_dynamically_typed( - checker.semantic_model(), expr, || format!("**{name}"), &mut diagnostics, is_overridden, + checker.semantic(), ); } } @@ -592,13 +589,10 @@ pub(crate) fn definition( } // ANN101, ANN102 - if is_method - && !visibility::is_staticmethod(checker.semantic_model(), cast::decorator_list(stmt)) - { + if is_method && !visibility::is_staticmethod(cast::decorator_list(stmt), checker.semantic()) { if let Some(arg) = args.posonlyargs.first().or_else(|| args.args.first()) { if arg.annotation.is_none() { - if visibility::is_classmethod(checker.semantic_model(), cast::decorator_list(stmt)) - { + if visibility::is_classmethod(cast::decorator_list(stmt), checker.semantic()) { if checker.enabled(Rule::MissingTypeCls) { diagnostics.push(Diagnostic::new( MissingTypeCls { @@ -628,11 +622,11 @@ pub(crate) fn definition( has_typed_return = true; if checker.enabled(Rule::AnyType) { check_dynamically_typed( - checker.semantic_model(), expr, || name.to_string(), &mut diagnostics, is_overridden, + checker.semantic(), ); } } else if !( @@ -640,9 +634,7 @@ pub(crate) fn definition( // (explicitly or implicitly). checker.settings.flake8_annotations.suppress_none_returning && is_none_returning(body) ) { - if is_method - && visibility::is_classmethod(checker.semantic_model(), cast::decorator_list(stmt)) - { + if is_method && visibility::is_classmethod(cast::decorator_list(stmt), checker.semantic()) { if checker.enabled(Rule::MissingReturnTypeClassMethod) { diagnostics.push(Diagnostic::new( MissingReturnTypeClassMethod { @@ -652,7 +644,7 @@ pub(crate) fn definition( )); } } else if is_method - && visibility::is_staticmethod(checker.semantic_model(), cast::decorator_list(stmt)) + && visibility::is_staticmethod(cast::decorator_list(stmt), checker.semantic()) { if checker.enabled(Rule::MissingReturnTypeStaticMethod) { diagnostics.push(Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_async/rules/blocking_http_call.rs b/crates/ruff/src/rules/flake8_async/rules/blocking_http_call.rs index e7d72f8e45..dbd00a3aaf 100644 --- a/crates/ruff/src/rules/flake8_async/rules/blocking_http_call.rs +++ b/crates/ruff/src/rules/flake8_async/rules/blocking_http_call.rs @@ -64,9 +64,9 @@ const BLOCKING_HTTP_CALLS: &[&[&str]] = &[ /// ASYNC100 pub(crate) fn blocking_http_call(checker: &mut Checker, expr: &Expr) { - if checker.semantic_model().in_async_context() { + if checker.semantic().in_async_context() { if let Expr::Call(ast::ExprCall { func, .. }) = expr { - let call_path = checker.semantic_model().resolve_call_path(func); + let call_path = checker.semantic().resolve_call_path(func); let is_blocking = call_path.map_or(false, |path| BLOCKING_HTTP_CALLS.contains(&path.as_slice())); diff --git a/crates/ruff/src/rules/flake8_async/rules/blocking_os_call.rs b/crates/ruff/src/rules/flake8_async/rules/blocking_os_call.rs index ab0316f276..861689bb3d 100644 --- a/crates/ruff/src/rules/flake8_async/rules/blocking_os_call.rs +++ b/crates/ruff/src/rules/flake8_async/rules/blocking_os_call.rs @@ -56,10 +56,10 @@ const UNSAFE_OS_METHODS: &[&[&str]] = &[ /// ASYNC102 pub(crate) fn blocking_os_call(checker: &mut Checker, expr: &Expr) { - if checker.semantic_model().in_async_context() { + if checker.semantic().in_async_context() { if let Expr::Call(ast::ExprCall { func, .. }) = expr { let is_unsafe_os_method = checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |path| UNSAFE_OS_METHODS.contains(&path.as_slice())); diff --git a/crates/ruff/src/rules/flake8_async/rules/open_sleep_or_subprocess_call.rs b/crates/ruff/src/rules/flake8_async/rules/open_sleep_or_subprocess_call.rs index 1a252118c7..c0d370da82 100644 --- a/crates/ruff/src/rules/flake8_async/rules/open_sleep_or_subprocess_call.rs +++ b/crates/ruff/src/rules/flake8_async/rules/open_sleep_or_subprocess_call.rs @@ -59,10 +59,10 @@ const OPEN_SLEEP_OR_SUBPROCESS_CALL: &[&[&str]] = &[ /// ASYNC101 pub(crate) fn open_sleep_or_subprocess_call(checker: &mut Checker, expr: &Expr) { - if checker.semantic_model().in_async_context() { + if checker.semantic().in_async_context() { if let Expr::Call(ast::ExprCall { func, .. }) = expr { let is_open_sleep_or_subprocess_call = checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |path| { OPEN_SLEEP_OR_SUBPROCESS_CALL.contains(&path.as_slice()) diff --git a/crates/ruff/src/rules/flake8_bandit/helpers.rs b/crates/ruff/src/rules/flake8_bandit/helpers.rs index dc6aa6dcdb..4a72eb63d0 100644 --- a/crates/ruff/src/rules/flake8_bandit/helpers.rs +++ b/crates/ruff/src/rules/flake8_bandit/helpers.rs @@ -22,20 +22,24 @@ pub(super) fn matches_password_name(string: &str) -> bool { PASSWORD_CANDIDATE_REGEX.is_match(string) } -pub(super) fn is_untyped_exception(type_: Option<&Expr>, model: &SemanticModel) -> bool { +pub(super) fn is_untyped_exception(type_: Option<&Expr>, semantic: &SemanticModel) -> bool { type_.map_or(true, |type_| { if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &type_ { elts.iter().any(|type_| { - model.resolve_call_path(type_).map_or(false, |call_path| { + semantic + .resolve_call_path(type_) + .map_or(false, |call_path| { + call_path.as_slice() == ["", "Exception"] + || call_path.as_slice() == ["", "BaseException"] + }) + }) + } else { + semantic + .resolve_call_path(type_) + .map_or(false, |call_path| { call_path.as_slice() == ["", "Exception"] || call_path.as_slice() == ["", "BaseException"] }) - }) - } else { - model.resolve_call_path(type_).map_or(false, |call_path| { - call_path.as_slice() == ["", "Exception"] - || call_path.as_slice() == ["", "BaseException"] - }) } }) } diff --git a/crates/ruff/src/rules/flake8_bandit/rules/bad_file_permissions.rs b/crates/ruff/src/rules/flake8_bandit/rules/bad_file_permissions.rs index 7bcf81dff6..ac5910df40 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/bad_file_permissions.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/bad_file_permissions.rs @@ -108,7 +108,7 @@ pub(crate) fn bad_file_permissions( keywords: &[Keyword], ) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| call_path.as_slice() == ["os", "chmod"]) { diff --git a/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs b/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs index 4595dce6c7..41e426b34d 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs @@ -60,7 +60,7 @@ fn unparse_string_format_expression(checker: &mut Checker, expr: &Expr) -> Optio op: Operator::Add | Operator::Mod, .. }) => { - let Some(parent) = checker.semantic_model().expr_parent() else { + let Some(parent) = checker.semantic().expr_parent() else { if any_over_expr(expr, &has_string_literal) { return Some(checker.generator().expr(expr)); } diff --git a/crates/ruff/src/rules/flake8_bandit/rules/hashlib_insecure_hash_functions.rs b/crates/ruff/src/rules/flake8_bandit/rules/hashlib_insecure_hash_functions.rs index 6948f6323b..29cfeca780 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/hashlib_insecure_hash_functions.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/hashlib_insecure_hash_functions.rs @@ -48,20 +48,19 @@ pub(crate) fn hashlib_insecure_hash_functions( args: &[Expr], keywords: &[Keyword], ) { - if let Some(hashlib_call) = - checker - .semantic_model() - .resolve_call_path(func) - .and_then(|call_path| { - if call_path.as_slice() == ["hashlib", "new"] { - Some(HashlibCall::New) - } else { - WEAK_HASHES - .iter() - .find(|hash| call_path.as_slice() == ["hashlib", hash]) - .map(|hash| HashlibCall::WeakHash(hash)) - } - }) + if let Some(hashlib_call) = checker + .semantic() + .resolve_call_path(func) + .and_then(|call_path| { + if call_path.as_slice() == ["hashlib", "new"] { + Some(HashlibCall::New) + } else { + WEAK_HASHES + .iter() + .find(|hash| call_path.as_slice() == ["hashlib", hash]) + .map(|hash| HashlibCall::WeakHash(hash)) + } + }) { match hashlib_call { HashlibCall::New => { diff --git a/crates/ruff/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs b/crates/ruff/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs index 06a2e77081..2e9fddbac1 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs @@ -37,7 +37,7 @@ pub(crate) fn jinja2_autoescape_false( keywords: &[Keyword], ) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["jinja2", "Environment"] diff --git a/crates/ruff/src/rules/flake8_bandit/rules/logging_config_insecure_listen.rs b/crates/ruff/src/rules/flake8_bandit/rules/logging_config_insecure_listen.rs index 6fc645bb88..009d166786 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/logging_config_insecure_listen.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/logging_config_insecure_listen.rs @@ -24,7 +24,7 @@ pub(crate) fn logging_config_insecure_listen( keywords: &[Keyword], ) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["logging", "config", "listen"] diff --git a/crates/ruff/src/rules/flake8_bandit/rules/paramiko_calls.rs b/crates/ruff/src/rules/flake8_bandit/rules/paramiko_calls.rs index e340a09ca4..73e2e82b13 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/paramiko_calls.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/paramiko_calls.rs @@ -18,7 +18,7 @@ impl Violation for ParamikoCall { /// S601 pub(crate) fn paramiko_call(checker: &mut Checker, func: &Expr) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["paramiko", "exec_command"] diff --git a/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs b/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs index fe45fb6e76..3a11042da2 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs @@ -44,7 +44,7 @@ pub(crate) fn request_with_no_cert_validation( keywords: &[Keyword], ) { if let Some(target) = checker - .semantic_model() + .semantic() .resolve_call_path(func) .and_then(|call_path| { if call_path.len() == 2 { diff --git a/crates/ruff/src/rules/flake8_bandit/rules/request_without_timeout.rs b/crates/ruff/src/rules/flake8_bandit/rules/request_without_timeout.rs index b08edbd4fa..c164dcadc1 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/request_without_timeout.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/request_without_timeout.rs @@ -34,7 +34,7 @@ pub(crate) fn request_without_timeout( keywords: &[Keyword], ) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { HTTP_VERBS diff --git a/crates/ruff/src/rules/flake8_bandit/rules/shell_injection.rs b/crates/ruff/src/rules/flake8_bandit/rules/shell_injection.rs index c5d97d7e0b..ae2e92211a 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/shell_injection.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/shell_injection.rs @@ -102,8 +102,8 @@ pub(crate) fn shell_injection( args: &[Expr], keywords: &[Keyword], ) { - let call_kind = get_call_kind(func, checker.semantic_model()); - let shell_keyword = find_shell_keyword(checker.semantic_model(), keywords); + let call_kind = get_call_kind(func, checker.semantic()); + let shell_keyword = find_shell_keyword(keywords, checker.semantic()); if matches!(call_kind, Some(CallKind::Subprocess)) { if let Some(arg) = args.first() { @@ -227,8 +227,8 @@ enum CallKind { } /// Return the [`CallKind`] of the given function call. -fn get_call_kind(func: &Expr, model: &SemanticModel) -> Option { - model +fn get_call_kind(func: &Expr, semantic: &SemanticModel) -> Option { + semantic .resolve_call_path(func) .and_then(|call_path| match call_path.as_slice() { &[module, submodule] => match module { @@ -269,14 +269,14 @@ struct ShellKeyword<'a> { /// Return the `shell` keyword argument to the given function call, if any. fn find_shell_keyword<'a>( - model: &SemanticModel, keywords: &'a [Keyword], + semantic: &SemanticModel, ) -> Option> { keywords .iter() .find(|keyword| keyword.arg.as_ref().map_or(false, |arg| arg == "shell")) .map(|keyword| ShellKeyword { - truthiness: Truthiness::from_expr(&keyword.value, |id| model.is_builtin(id)), + truthiness: Truthiness::from_expr(&keyword.value, |id| semantic.is_builtin(id)), keyword, }) } diff --git a/crates/ruff/src/rules/flake8_bandit/rules/snmp_insecure_version.rs b/crates/ruff/src/rules/flake8_bandit/rules/snmp_insecure_version.rs index 60fc3b33dd..15541b48c9 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/snmp_insecure_version.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/snmp_insecure_version.rs @@ -25,7 +25,7 @@ pub(crate) fn snmp_insecure_version( keywords: &[Keyword], ) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["pysnmp", "hlapi", "CommunityData"] diff --git a/crates/ruff/src/rules/flake8_bandit/rules/snmp_weak_cryptography.rs b/crates/ruff/src/rules/flake8_bandit/rules/snmp_weak_cryptography.rs index 313c32a187..13b490dc33 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/snmp_weak_cryptography.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/snmp_weak_cryptography.rs @@ -27,7 +27,7 @@ pub(crate) fn snmp_weak_cryptography( keywords: &[Keyword], ) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["pysnmp", "hlapi", "UsmUserData"] diff --git a/crates/ruff/src/rules/flake8_bandit/rules/suspicious_function_call.rs b/crates/ruff/src/rules/flake8_bandit/rules/suspicious_function_call.rs index 6c6eba80fe..f2d86ea4fa 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/suspicious_function_call.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/suspicious_function_call.rs @@ -470,7 +470,7 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, expr: &Expr) { return; }; - let Some(reason) = checker.semantic_model().resolve_call_path(func).and_then(|call_path| { + let Some(reason) = checker.semantic().resolve_call_path(func).and_then(|call_path| { for module in SUSPICIOUS_MEMBERS { for member in module.members { if call_path.as_slice() == *member { diff --git a/crates/ruff/src/rules/flake8_bandit/rules/try_except_continue.rs b/crates/ruff/src/rules/flake8_bandit/rules/try_except_continue.rs index a64c33bc39..e2ce1f3cfa 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/try_except_continue.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/try_except_continue.rs @@ -27,7 +27,7 @@ pub(crate) fn try_except_continue( ) { if body.len() == 1 && body[0].is_continue_stmt() - && (check_typed_exception || is_untyped_exception(type_, checker.semantic_model())) + && (check_typed_exception || is_untyped_exception(type_, checker.semantic())) { checker .diagnostics diff --git a/crates/ruff/src/rules/flake8_bandit/rules/try_except_pass.rs b/crates/ruff/src/rules/flake8_bandit/rules/try_except_pass.rs index c740399349..a89c41b240 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/try_except_pass.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/try_except_pass.rs @@ -27,7 +27,7 @@ pub(crate) fn try_except_pass( ) { if body.len() == 1 && body[0].is_pass_stmt() - && (check_typed_exception || is_untyped_exception(type_, checker.semantic_model())) + && (check_typed_exception || is_untyped_exception(type_, checker.semantic())) { checker .diagnostics diff --git a/crates/ruff/src/rules/flake8_bandit/rules/unsafe_yaml_load.rs b/crates/ruff/src/rules/flake8_bandit/rules/unsafe_yaml_load.rs index e5225eb0d4..f72a68ab4d 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/unsafe_yaml_load.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/unsafe_yaml_load.rs @@ -38,14 +38,14 @@ pub(crate) fn unsafe_yaml_load( keywords: &[Keyword], ) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| call_path.as_slice() == ["yaml", "load"]) { let call_args = SimpleCallArgs::new(args, keywords); if let Some(loader_arg) = call_args.argument("Loader", 1) { if !checker - .semantic_model() + .semantic() .resolve_call_path(loader_arg) .map_or(false, |call_path| { call_path.as_slice() == ["yaml", "SafeLoader"] diff --git a/crates/ruff/src/rules/flake8_blind_except/rules/blind_except.rs b/crates/ruff/src/rules/flake8_blind_except/rules/blind_except.rs index ef4f52524e..843a7b1c31 100644 --- a/crates/ruff/src/rules/flake8_blind_except/rules/blind_except.rs +++ b/crates/ruff/src/rules/flake8_blind_except/rules/blind_except.rs @@ -34,7 +34,7 @@ pub(crate) fn blind_except( return; }; for exception in ["BaseException", "Exception"] { - if id == exception && checker.semantic_model().is_builtin(exception) { + if id == exception && checker.semantic().is_builtin(exception) { // If the exception is re-raised, don't flag an error. if body.iter().any(|stmt| { if let Stmt::Raise(ast::StmtRaise { exc, .. }) = stmt { @@ -58,7 +58,7 @@ pub(crate) fn blind_except( if body.iter().any(|stmt| { if let Stmt::Expr(ast::StmtExpr { value, range: _ }) = stmt { if let Expr::Call(ast::ExprCall { func, keywords, .. }) = value.as_ref() { - if logging::is_logger_candidate(func, checker.semantic_model()) { + if logging::is_logger_candidate(func, checker.semantic()) { if let Some(attribute) = func.as_attribute_expr() { let attr = attribute.attr.as_str(); if attr == "exception" { diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs b/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs index f8bd621178..6a4b303ec7 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs @@ -36,16 +36,16 @@ impl Violation for EmptyMethodWithoutAbstractDecorator { } } -fn is_abc_class(model: &SemanticModel, bases: &[Expr], keywords: &[Keyword]) -> bool { +fn is_abc_class(bases: &[Expr], keywords: &[Keyword], semantic: &SemanticModel) -> bool { keywords.iter().any(|keyword| { keyword.arg.as_ref().map_or(false, |arg| arg == "metaclass") - && model + && semantic .resolve_call_path(&keyword.value) .map_or(false, |call_path| { call_path.as_slice() == ["abc", "ABCMeta"] }) }) || bases.iter().any(|base| { - model + semantic .resolve_call_path(base) .map_or(false, |call_path| call_path.as_slice() == ["abc", "ABC"]) }) @@ -80,7 +80,7 @@ pub(crate) fn abstract_base_class( if bases.len() + keywords.len() != 1 { return; } - if !is_abc_class(checker.semantic_model(), bases, keywords) { + if !is_abc_class(bases, keywords, checker.semantic()) { return; } @@ -109,7 +109,7 @@ pub(crate) fn abstract_base_class( continue; }; - let has_abstract_decorator = is_abstract(checker.semantic_model(), decorator_list); + let has_abstract_decorator = is_abstract(decorator_list, checker.semantic()); has_abstract_method |= has_abstract_decorator; if !checker.enabled(Rule::EmptyMethodWithoutAbstractDecorator) { @@ -118,7 +118,7 @@ pub(crate) fn abstract_base_class( if !has_abstract_decorator && is_empty_body(body) - && !is_overload(checker.semantic_model(), decorator_list) + && !is_overload(decorator_list, checker.semantic()) { checker.diagnostics.push(Diagnostic::new( EmptyMethodWithoutAbstractDecorator { diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/assert_raises_exception.rs b/crates/ruff/src/rules/flake8_bugbear/rules/assert_raises_exception.rs index be7a22f54e..e629112224 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/assert_raises_exception.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/assert_raises_exception.rs @@ -66,7 +66,7 @@ pub(crate) fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items: } if !checker - .semantic_model() + .semantic() .resolve_call_path(args.first().unwrap()) .map_or(false, |call_path| call_path.as_slice() == ["", "Exception"]) { @@ -78,7 +78,7 @@ pub(crate) fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items: { AssertionKind::AssertRaises } else if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["pytest", "raises"] diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/cached_instance_method.rs b/crates/ruff/src/rules/flake8_bugbear/rules/cached_instance_method.rs index ff5d889ace..ddfba0d174 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/cached_instance_method.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/cached_instance_method.rs @@ -18,8 +18,8 @@ impl Violation for CachedInstanceMethod { } } -fn is_cache_func(model: &SemanticModel, expr: &Expr) -> bool { - model.resolve_call_path(expr).map_or(false, |call_path| { +fn is_cache_func(expr: &Expr, semantic: &SemanticModel) -> bool { + semantic.resolve_call_path(expr).map_or(false, |call_path| { call_path.as_slice() == ["functools", "lru_cache"] || call_path.as_slice() == ["functools", "cache"] }) @@ -27,7 +27,7 @@ fn is_cache_func(model: &SemanticModel, expr: &Expr) -> bool { /// B019 pub(crate) fn cached_instance_method(checker: &mut Checker, decorator_list: &[Decorator]) { - if !checker.semantic_model().scope().kind.is_class() { + if !checker.semantic().scope().kind.is_class() { return; } for decorator in decorator_list { @@ -41,11 +41,11 @@ pub(crate) fn cached_instance_method(checker: &mut Checker, decorator_list: &[De } for decorator in decorator_list { if is_cache_func( - checker.semantic_model(), match &decorator.expression { Expr::Call(ast::ExprCall { func, .. }) => func, _ => &decorator.expression, }, + checker.semantic(), ) { checker .diagnostics diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/function_call_argument_default.rs b/crates/ruff/src/rules/flake8_bugbear/rules/function_call_argument_default.rs index bf2cf7b7a5..af95ef699e 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/function_call_argument_default.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/function_call_argument_default.rs @@ -73,7 +73,7 @@ impl Violation for FunctionCallInDefaultArgument { } struct ArgumentDefaultVisitor<'a> { - model: &'a SemanticModel<'a>, + semantic: &'a SemanticModel<'a>, extend_immutable_calls: Vec>, diagnostics: Vec<(DiagnosticKind, TextRange)>, } @@ -81,7 +81,7 @@ struct ArgumentDefaultVisitor<'a> { impl<'a> ArgumentDefaultVisitor<'a> { fn new(model: &'a SemanticModel<'a>, extend_immutable_calls: Vec>) -> Self { Self { - model, + semantic: model, extend_immutable_calls, diagnostics: Vec::new(), } @@ -95,8 +95,8 @@ where fn visit_expr(&mut self, expr: &'b Expr) { match expr { Expr::Call(ast::ExprCall { func, .. }) => { - if !is_mutable_func(self.model, func) - && !is_immutable_func(self.model, func, &self.extend_immutable_calls) + if !is_mutable_func(func, self.semantic) + && !is_immutable_func(func, self.semantic, &self.extend_immutable_calls) { self.diagnostics.push(( FunctionCallInDefaultArgument { @@ -125,8 +125,7 @@ pub(crate) fn function_call_argument_default(checker: &mut Checker, arguments: & .map(|target| from_qualified_name(target)) .collect(); let diagnostics = { - let mut visitor = - ArgumentDefaultVisitor::new(checker.semantic_model(), extend_immutable_calls); + let mut visitor = ArgumentDefaultVisitor::new(checker.semantic(), extend_immutable_calls); for expr in arguments .defaults .iter() diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/mutable_argument_default.rs b/crates/ruff/src/rules/flake8_bugbear/rules/mutable_argument_default.rs index b4fb273aa8..064d1516b4 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/mutable_argument_default.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/mutable_argument_default.rs @@ -26,15 +26,15 @@ const MUTABLE_FUNCS: &[&[&str]] = &[ &["collections", "deque"], ]; -pub(crate) fn is_mutable_func(model: &SemanticModel, func: &Expr) -> bool { - model.resolve_call_path(func).map_or(false, |call_path| { +pub(crate) fn is_mutable_func(func: &Expr, semantic: &SemanticModel) -> bool { + semantic.resolve_call_path(func).map_or(false, |call_path| { MUTABLE_FUNCS .iter() .any(|target| call_path.as_slice() == *target) }) } -fn is_mutable_expr(model: &SemanticModel, expr: &Expr) -> bool { +fn is_mutable_expr(expr: &Expr, semantic: &SemanticModel) -> bool { match expr { Expr::List(_) | Expr::Dict(_) @@ -42,7 +42,7 @@ fn is_mutable_expr(model: &SemanticModel, expr: &Expr) -> bool { | Expr::ListComp(_) | Expr::DictComp(_) | Expr::SetComp(_) => true, - Expr::Call(ast::ExprCall { func, .. }) => is_mutable_func(model, func), + Expr::Call(ast::ExprCall { func, .. }) => is_mutable_func(func, semantic), _ => false, } } @@ -64,9 +64,9 @@ pub(crate) fn mutable_argument_default(checker: &mut Checker, arguments: &Argume .zip(arguments.defaults.iter().rev()), ) { - if is_mutable_expr(checker.semantic_model(), default) + if is_mutable_expr(default, checker.semantic()) && !arg.annotation.as_ref().map_or(false, |expr| { - is_immutable_annotation(checker.semantic_model(), expr) + is_immutable_annotation(expr, checker.semantic()) }) { checker diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/no_explicit_stacklevel.rs b/crates/ruff/src/rules/flake8_bugbear/rules/no_explicit_stacklevel.rs index a7d20c2801..0668fc9f39 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/no_explicit_stacklevel.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/no_explicit_stacklevel.rs @@ -45,7 +45,7 @@ pub(crate) fn no_explicit_stacklevel( keywords: &[Keyword], ) { if !checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["warnings", "warn"] diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs b/crates/ruff/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs index 618af80195..6e753163ec 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs @@ -342,7 +342,7 @@ pub(crate) fn reuse_of_groupby_generator( }; // Check if the function call is `itertools.groupby` if !checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["itertools", "groupby"] diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/setattr_with_constant.rs b/crates/ruff/src/rules/flake8_bugbear/rules/setattr_with_constant.rs index 9229339bf3..4866a9ae7c 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/setattr_with_constant.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/setattr_with_constant.rs @@ -75,7 +75,7 @@ pub(crate) fn setattr_with_constant( if let Stmt::Expr(ast::StmtExpr { value: child, range: _, - }) = checker.semantic_model().stmt() + }) = checker.semantic().stmt() { if expr == child.as_ref() { let mut diagnostic = Diagnostic::new(SetAttrWithConstant, expr.range()); diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs b/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs index 380628fc25..19432aceed 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs @@ -20,7 +20,6 @@ use rustc_hash::FxHashMap; use rustpython_parser::ast::{self, Expr, Ranged, Stmt}; -use serde::{Deserialize, Serialize}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -30,7 +29,7 @@ use ruff_python_ast::{helpers, visitor}; use crate::checkers::ast::Checker; use crate::registry::AsRule; -#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, result_like::BoolLike)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, result_like::BoolLike)] enum Certainty { Certain, Uncertain, @@ -129,7 +128,7 @@ pub(crate) fn unused_loop_control_variable(checker: &mut Checker, target: &Expr, // Avoid fixing any variables that _may_ be used, but undetectably so. let certainty = Certainty::from(!helpers::uses_magic_variable_access(body, |id| { - checker.semantic_model().is_builtin(id) + checker.semantic().is_builtin(id) })); // Attempt to rename the variable by prepending an underscore, but avoid @@ -154,10 +153,10 @@ pub(crate) fn unused_loop_control_variable(checker: &mut Checker, target: &Expr, if certainty.into() && checker.patch(diagnostic.kind.rule()) { // Avoid fixing if the variable, or any future bindings to the variable, are // used _after_ the loop. - let scope = checker.semantic_model().scope(); + let scope = checker.semantic().scope(); if scope .get_all(name) - .map(|binding_id| checker.semantic_model().binding(binding_id)) + .map(|binding_id| checker.semantic().binding(binding_id)) .all(|binding| !binding.is_used()) { diagnostic.set_fix(Fix::suggested(Edit::range_replacement( diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/useless_contextlib_suppress.rs b/crates/ruff/src/rules/flake8_bugbear/rules/useless_contextlib_suppress.rs index 456d47af04..c066a74242 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/useless_contextlib_suppress.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/useless_contextlib_suppress.rs @@ -27,7 +27,7 @@ pub(crate) fn useless_contextlib_suppress( ) { if args.is_empty() && checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["contextlib", "suppress"] diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/useless_expression.rs b/crates/ruff/src/rules/flake8_bugbear/rules/useless_expression.rs index 00376dc8b0..9d5f1083d2 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/useless_expression.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/useless_expression.rs @@ -53,7 +53,7 @@ pub(crate) fn useless_expression(checker: &mut Checker, value: &Expr) { } // Ignore statements that have side effects. - if contains_effect(value, |id| checker.semantic_model().is_builtin(id)) { + if contains_effect(value, |id| checker.semantic().is_builtin(id)) { // Flag attributes as useless expressions, even if they're attached to calls or other // expressions. if matches!(value, Expr::Attribute(_)) { diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs b/crates/ruff/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs index be3570d8fd..3a605071b5 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs @@ -27,13 +27,13 @@ pub(crate) fn zip_without_explicit_strict( ) { if let Expr::Name(ast::ExprName { id, .. }) = func { if id == "zip" - && checker.semantic_model().is_builtin("zip") + && checker.semantic().is_builtin("zip") && !kwargs .iter() .any(|keyword| keyword.arg.as_ref().map_or(false, |name| name == "strict")) && !args .iter() - .any(|arg| is_infinite_iterator(arg, checker.semantic_model())) + .any(|arg| is_infinite_iterator(arg, checker.semantic())) { checker .diagnostics @@ -44,14 +44,13 @@ pub(crate) fn zip_without_explicit_strict( /// Return `true` if the [`Expr`] appears to be an infinite iterator (e.g., a call to /// `itertools.cycle` or similar). -fn is_infinite_iterator(arg: &Expr, model: &SemanticModel) -> bool { +fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool { let Expr::Call(ast::ExprCall { func, args, keywords, .. }) = &arg else { return false; }; - return model - .resolve_call_path(func) - .map_or(false, |call_path| match call_path.as_slice() { + semantic.resolve_call_path(func).map_or(false, |call_path| { + match call_path.as_slice() { ["itertools", "cycle" | "count"] => true, ["itertools", "repeat"] => { // Ex) `itertools.repeat(1)` @@ -76,5 +75,6 @@ fn is_infinite_iterator(arg: &Expr, model: &SemanticModel) -> bool { false } _ => false, - }); + } + }) } diff --git a/crates/ruff/src/rules/flake8_builtins/rules/builtin_attribute_shadowing.rs b/crates/ruff/src/rules/flake8_builtins/rules/builtin_attribute_shadowing.rs index ec7e9fb4e6..8393ba766a 100644 --- a/crates/ruff/src/rules/flake8_builtins/rules/builtin_attribute_shadowing.rs +++ b/crates/ruff/src/rules/flake8_builtins/rules/builtin_attribute_shadowing.rs @@ -72,11 +72,11 @@ pub(crate) fn builtin_attribute_shadowing( if shadows_builtin(name, &checker.settings.flake8_builtins.builtins_ignorelist) { // Ignore shadowing within `TypedDict` definitions, since these are only accessible through // subscripting and not through attribute access. - if class_def.bases.iter().any(|base| { - checker - .semantic_model() - .match_typing_expr(base, "TypedDict") - }) { + if class_def + .bases + .iter() + .any(|base| checker.semantic().match_typing_expr(base, "TypedDict")) + { return; } diff --git a/crates/ruff/src/rules/flake8_comprehensions/fixes.rs b/crates/ruff/src/rules/flake8_comprehensions/fixes.rs index ed2ba3ada3..b32379677b 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/fixes.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/fixes.rs @@ -502,7 +502,7 @@ pub(crate) fn fix_unnecessary_collection_call( /// this method will pad the start and end of an expression as needed to /// avoid producing invalid syntax. fn pad_expression(content: String, range: TextRange, checker: &Checker) -> String { - if !checker.semantic_model().in_f_string() { + if !checker.semantic().in_f_string() { return content; } diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs index 80be40cf4f..e8770e8ac3 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs @@ -75,7 +75,7 @@ pub(crate) fn unnecessary_call_around_sorted( if inner != "sorted" { return; } - if !checker.semantic_model().is_builtin(inner) || !checker.semantic_model().is_builtin(outer) { + if !checker.semantic().is_builtin(inner) || !checker.semantic().is_builtin(outer) { return; } let mut diagnostic = Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs index 23ca342702..6a51574d45 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs @@ -79,7 +79,7 @@ pub(crate) fn unnecessary_collection_call( } _ => return, }; - if !checker.semantic_model().is_builtin(id) { + if !checker.semantic().is_builtin(id) { return; } let mut diagnostic = Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs index 498e86edc4..56de6768ce 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs @@ -56,7 +56,7 @@ fn add_diagnostic(checker: &mut Checker, expr: &Expr) { Expr::DictComp(_) => "dict", _ => return, }; - if !checker.semantic_model().is_builtin(id) { + if !checker.semantic().is_builtin(id) { return; } let mut diagnostic = Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs index c3aac344dc..6bcdb7864e 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs @@ -76,7 +76,7 @@ pub(crate) fn unnecessary_comprehension_any_all( if is_async_generator(elt) { return; } - if !checker.semantic_model().is_builtin(id) { + if !checker.semantic().is_builtin(id) { return; } let mut diagnostic = Diagnostic::new(UnnecessaryComprehensionAnyAll, args[0].range()); diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs index 96cec22cf0..1ea1ae62fc 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs @@ -90,7 +90,7 @@ pub(crate) fn unnecessary_double_cast_or_process( let Some(inner) = helpers::expr_name(func) else { return; }; - if !checker.semantic_model().is_builtin(inner) || !checker.semantic_model().is_builtin(outer) { + if !checker.semantic().is_builtin(inner) || !checker.semantic().is_builtin(outer) { return; } diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs index 4cdd85512d..d5f9cea172 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs @@ -52,7 +52,7 @@ pub(crate) fn unnecessary_generator_list( let Some(argument) = helpers::exactly_one_argument_with_matching_function("list", func, args, keywords) else { return; }; - if !checker.semantic_model().is_builtin("list") { + if !checker.semantic().is_builtin("list") { return; } if let Expr::GeneratorExp(_) = argument { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs index 345a6c0f91..65af9cb79d 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs @@ -52,7 +52,7 @@ pub(crate) fn unnecessary_generator_set( let Some(argument) = helpers::exactly_one_argument_with_matching_function("set", func, args, keywords) else { return; }; - if !checker.semantic_model().is_builtin("set") { + if !checker.semantic().is_builtin("set") { return; } if let Expr::GeneratorExp(_) = argument { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs index 597253875b..45ef0f4ae0 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs @@ -48,7 +48,7 @@ pub(crate) fn unnecessary_list_call( let Some(argument) = helpers::first_argument_with_matching_function("list", func, args) else { return; }; - if !checker.semantic_model().is_builtin("list") { + if !checker.semantic().is_builtin("list") { return; } if !argument.is_list_comp_expr() { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs index e30434bbe3..e8cc9b954f 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs @@ -50,7 +50,7 @@ pub(crate) fn unnecessary_list_comprehension_dict( let Some(argument) = helpers::exactly_one_argument_with_matching_function("dict", func, args, keywords) else { return; }; - if !checker.semantic_model().is_builtin("dict") { + if !checker.semantic().is_builtin("dict") { return; } let Expr::ListComp(ast::ExprListComp { elt, .. }) = argument else { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs index 8506e71249..1dc3618654 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs @@ -50,7 +50,7 @@ pub(crate) fn unnecessary_list_comprehension_set( let Some(argument) = helpers::exactly_one_argument_with_matching_function("set", func, args, keywords) else { return; }; - if !checker.semantic_model().is_builtin("set") { + if !checker.semantic().is_builtin("set") { return; } if argument.is_list_comp_expr() { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs index 370bedf38f..41e4866233 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs @@ -57,7 +57,7 @@ pub(crate) fn unnecessary_literal_dict( let Some(argument) = helpers::exactly_one_argument_with_matching_function("dict", func, args, keywords) else { return; }; - if !checker.semantic_model().is_builtin("dict") { + if !checker.semantic().is_builtin("dict") { return; } let (kind, elts) = match argument { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs index 9519109ac9..6f3cf56fb3 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs @@ -58,7 +58,7 @@ pub(crate) fn unnecessary_literal_set( let Some(argument) = helpers::exactly_one_argument_with_matching_function("set", func, args, keywords) else { return; }; - if !checker.semantic_model().is_builtin("set") { + if !checker.semantic().is_builtin("set") { return; } let kind = match argument { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs index cc9ba2d5ce..119f53330b 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs @@ -76,7 +76,7 @@ pub(crate) fn unnecessary_literal_within_dict_call( let Some(argument) = helpers::first_argument_with_matching_function("dict", func, args) else { return; }; - if !checker.semantic_model().is_builtin("dict") { + if !checker.semantic().is_builtin("dict") { return; } let argument_kind = match argument { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs index d1c240d55f..febd2ce931 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs @@ -79,7 +79,7 @@ pub(crate) fn unnecessary_literal_within_list_call( let Some(argument) = helpers::first_argument_with_matching_function("list", func, args) else { return; }; - if !checker.semantic_model().is_builtin("list") { + if !checker.semantic().is_builtin("list") { return; } let argument_kind = match argument { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs index cd61c1943f..187e1ae3e8 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs @@ -80,7 +80,7 @@ pub(crate) fn unnecessary_literal_within_tuple_call( let Some(argument) = helpers::first_argument_with_matching_function("tuple", func, args) else { return; }; - if !checker.semantic_model().is_builtin("tuple") { + if !checker.semantic().is_builtin("tuple") { return; } let argument_kind = match argument { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_map.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_map.rs index 086a3137a4..8a54343bbf 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_map.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_map.rs @@ -88,7 +88,7 @@ pub(crate) fn unnecessary_map( }; match id { "map" => { - if !checker.semantic_model().is_builtin(id) { + if !checker.semantic().is_builtin(id) { return; } @@ -119,7 +119,7 @@ pub(crate) fn unnecessary_map( } } "list" | "set" => { - if !checker.semantic_model().is_builtin(id) { + if !checker.semantic().is_builtin(id) { return; } @@ -149,7 +149,7 @@ pub(crate) fn unnecessary_map( } } "dict" => { - if !checker.semantic_model().is_builtin(id) { + if !checker.semantic().is_builtin(id) { return; } diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs index 8659025978..fc9e678e44 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs @@ -58,7 +58,7 @@ pub(crate) fn unnecessary_subscript_reversal( if !(id == "set" || id == "sorted" || id == "reversed") { return; } - if !checker.semantic_model().is_builtin(id) { + if !checker.semantic().is_builtin(id) { return; } let Expr::Subscript(ast::ExprSubscript { slice, .. }) = first_arg else { diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_date_fromtimestamp.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_date_fromtimestamp.rs index 3029801216..66a6422200 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_date_fromtimestamp.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_date_fromtimestamp.rs @@ -27,7 +27,7 @@ impl Violation for CallDateFromtimestamp { /// Use `datetime.datetime.fromtimestamp(, tz=).date()` instead. pub(crate) fn call_date_fromtimestamp(checker: &mut Checker, func: &Expr, location: TextRange) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["datetime", "date", "fromtimestamp"] diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_date_today.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_date_today.rs index 461fa06761..d159710b99 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_date_today.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_date_today.rs @@ -27,7 +27,7 @@ impl Violation for CallDateToday { /// Use `datetime.datetime.now(tz=).date()` instead. pub(crate) fn call_date_today(checker: &mut Checker, func: &Expr, location: TextRange) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["datetime", "date", "today"] diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_fromtimestamp.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_fromtimestamp.rs index 4ff08ba885..f75dde8d45 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_fromtimestamp.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_fromtimestamp.rs @@ -28,7 +28,7 @@ pub(crate) fn call_datetime_fromtimestamp( location: TextRange, ) { if !checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["datetime", "datetime", "fromtimestamp"] diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_now_without_tzinfo.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_now_without_tzinfo.rs index 46202fb6a2..15b930d6d2 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_now_without_tzinfo.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_now_without_tzinfo.rs @@ -26,7 +26,7 @@ pub(crate) fn call_datetime_now_without_tzinfo( location: TextRange, ) { if !checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["datetime", "datetime", "now"] diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_strptime_without_zone.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_strptime_without_zone.rs index 2cc4fb0b99..5432d11563 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_strptime_without_zone.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_strptime_without_zone.rs @@ -28,7 +28,7 @@ pub(crate) fn call_datetime_strptime_without_zone( location: TextRange, ) { if !checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["datetime", "datetime", "strptime"] @@ -49,7 +49,7 @@ pub(crate) fn call_datetime_strptime_without_zone( } }; - let (Some(grandparent), Some(parent)) = (checker.semantic_model().expr_grandparent(), checker.semantic_model().expr_parent()) else { + let (Some(grandparent), Some(parent)) = (checker.semantic().expr_grandparent(), checker.semantic().expr_parent()) else { checker.diagnostics.push(Diagnostic::new( CallDatetimeStrptimeWithoutZone, location, diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_today.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_today.rs index 5c42c7c176..e566d38455 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_today.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_today.rs @@ -27,7 +27,7 @@ impl Violation for CallDatetimeToday { /// Use `datetime.datetime.now(tz=)` instead. pub(crate) fn call_datetime_today(checker: &mut Checker, func: &Expr, location: TextRange) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["datetime", "datetime", "today"] diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcfromtimestamp.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcfromtimestamp.rs index ffa73e5416..db7530cc42 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcfromtimestamp.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcfromtimestamp.rs @@ -34,7 +34,7 @@ pub(crate) fn call_datetime_utcfromtimestamp( location: TextRange, ) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["datetime", "datetime", "utcfromtimestamp"] diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcnow.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcnow.rs index 33d89f8673..8444243061 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcnow.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcnow.rs @@ -29,7 +29,7 @@ impl Violation for CallDatetimeUtcnow { /// current time in UTC is by calling `datetime.now(timezone.utc)`. pub(crate) fn call_datetime_utcnow(checker: &mut Checker, func: &Expr, location: TextRange) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["datetime", "datetime", "utcnow"] diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs index af7eabf837..e37b47946d 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs @@ -25,7 +25,7 @@ pub(crate) fn call_datetime_without_tzinfo( location: TextRange, ) { if !checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["datetime", "datetime"] diff --git a/crates/ruff/src/rules/flake8_debugger/rules/debugger.rs b/crates/ruff/src/rules/flake8_debugger/rules/debugger.rs index 0dfdc9ce83..e0552c1bcd 100644 --- a/crates/ruff/src/rules/flake8_debugger/rules/debugger.rs +++ b/crates/ruff/src/rules/flake8_debugger/rules/debugger.rs @@ -44,7 +44,7 @@ const DEBUGGERS: &[&[&str]] = &[ /// Checks for the presence of a debugger call. pub(crate) fn debugger_call(checker: &mut Checker, expr: &Expr, func: &Expr) { if let Some(target) = checker - .semantic_model() + .semantic() .resolve_call_path(func) .and_then(|call_path| { DEBUGGERS diff --git a/crates/ruff/src/rules/flake8_django/rules/all_with_model_form.rs b/crates/ruff/src/rules/flake8_django/rules/all_with_model_form.rs index da019f071a..3a3769bda8 100644 --- a/crates/ruff/src/rules/flake8_django/rules/all_with_model_form.rs +++ b/crates/ruff/src/rules/flake8_django/rules/all_with_model_form.rs @@ -54,7 +54,7 @@ pub(crate) fn all_with_model_form( ) -> Option { if !bases .iter() - .any(|base| is_model_form(checker.semantic_model(), base)) + .any(|base| is_model_form(base, checker.semantic())) { return None; } diff --git a/crates/ruff/src/rules/flake8_django/rules/exclude_with_model_form.rs b/crates/ruff/src/rules/flake8_django/rules/exclude_with_model_form.rs index af229a6a32..c920525a19 100644 --- a/crates/ruff/src/rules/flake8_django/rules/exclude_with_model_form.rs +++ b/crates/ruff/src/rules/flake8_django/rules/exclude_with_model_form.rs @@ -52,7 +52,7 @@ pub(crate) fn exclude_with_model_form( ) -> Option { if !bases .iter() - .any(|base| is_model_form(checker.semantic_model(), base)) + .any(|base| is_model_form(base, checker.semantic())) { return None; } diff --git a/crates/ruff/src/rules/flake8_django/rules/helpers.rs b/crates/ruff/src/rules/flake8_django/rules/helpers.rs index b12419a808..5c45066a02 100644 --- a/crates/ruff/src/rules/flake8_django/rules/helpers.rs +++ b/crates/ruff/src/rules/flake8_django/rules/helpers.rs @@ -3,23 +3,23 @@ use rustpython_parser::ast::Expr; use ruff_python_semantic::SemanticModel; /// Return `true` if a Python class appears to be a Django model, based on its base classes. -pub(super) fn is_model(model: &SemanticModel, base: &Expr) -> bool { - model.resolve_call_path(base).map_or(false, |call_path| { +pub(super) fn is_model(base: &Expr, semantic: &SemanticModel) -> bool { + semantic.resolve_call_path(base).map_or(false, |call_path| { call_path.as_slice() == ["django", "db", "models", "Model"] }) } /// Return `true` if a Python class appears to be a Django model form, based on its base classes. -pub(super) fn is_model_form(model: &SemanticModel, base: &Expr) -> bool { - model.resolve_call_path(base).map_or(false, |call_path| { +pub(super) fn is_model_form(base: &Expr, semantic: &SemanticModel) -> bool { + semantic.resolve_call_path(base).map_or(false, |call_path| { call_path.as_slice() == ["django", "forms", "ModelForm"] || call_path.as_slice() == ["django", "forms", "models", "ModelForm"] }) } /// Return `true` if the expression is constructor for a Django model field. -pub(super) fn is_model_field(model: &SemanticModel, expr: &Expr) -> bool { - model.resolve_call_path(expr).map_or(false, |call_path| { +pub(super) fn is_model_field(expr: &Expr, semantic: &SemanticModel) -> bool { + semantic.resolve_call_path(expr).map_or(false, |call_path| { call_path .as_slice() .starts_with(&["django", "db", "models"]) @@ -28,10 +28,10 @@ pub(super) fn is_model_field(model: &SemanticModel, expr: &Expr) -> bool { /// Return the name of the field type, if the expression is constructor for a Django model field. pub(super) fn get_model_field_name<'a>( - model: &'a SemanticModel, expr: &'a Expr, + semantic: &'a SemanticModel, ) -> Option<&'a str> { - model.resolve_call_path(expr).and_then(|call_path| { + semantic.resolve_call_path(expr).and_then(|call_path| { let call_path = call_path.as_slice(); if !call_path.starts_with(&["django", "db", "models"]) { return None; diff --git a/crates/ruff/src/rules/flake8_django/rules/locals_in_render_function.rs b/crates/ruff/src/rules/flake8_django/rules/locals_in_render_function.rs index 0779e7462b..acd7074222 100644 --- a/crates/ruff/src/rules/flake8_django/rules/locals_in_render_function.rs +++ b/crates/ruff/src/rules/flake8_django/rules/locals_in_render_function.rs @@ -51,7 +51,7 @@ pub(crate) fn locals_in_render_function( keywords: &[Keyword], ) { if !checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["django", "shortcuts", "render"] @@ -61,7 +61,7 @@ pub(crate) fn locals_in_render_function( } let locals = if args.len() >= 3 { - if !is_locals_call(checker.semantic_model(), &args[2]) { + if !is_locals_call(&args[2], checker.semantic()) { return; } &args[2] @@ -69,7 +69,7 @@ pub(crate) fn locals_in_render_function( .iter() .find(|keyword| keyword.arg.as_ref().map_or(false, |arg| arg == "context")) { - if !is_locals_call(checker.semantic_model(), &keyword.value) { + if !is_locals_call(&keyword.value, checker.semantic()) { return; } &keyword.value @@ -83,11 +83,11 @@ pub(crate) fn locals_in_render_function( )); } -fn is_locals_call(model: &SemanticModel, expr: &Expr) -> bool { +fn is_locals_call(expr: &Expr, semantic: &SemanticModel) -> bool { let Expr::Call(ast::ExprCall { func, .. }) = expr else { return false }; - model + semantic .resolve_call_path(func) .map_or(false, |call_path| call_path.as_slice() == ["", "locals"]) } diff --git a/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs b/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs index 586928fa00..c0ca4d99e9 100644 --- a/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs +++ b/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs @@ -56,7 +56,7 @@ pub(crate) fn model_without_dunder_str( body: &[Stmt], class_location: &Stmt, ) -> Option { - if !checker_applies(checker.semantic_model(), bases, body) { + if !is_non_abstract_model(bases, body, checker.semantic()) { return None; } if !has_dunder_method(body) { @@ -80,12 +80,12 @@ fn has_dunder_method(body: &[Stmt]) -> bool { }) } -fn checker_applies(model: &SemanticModel, bases: &[Expr], body: &[Stmt]) -> bool { +fn is_non_abstract_model(bases: &[Expr], body: &[Stmt], semantic: &SemanticModel) -> bool { for base in bases.iter() { if is_model_abstract(body) { continue; } - if helpers::is_model(model, base) { + if helpers::is_model(base, semantic) { return true; } } diff --git a/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs b/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs index d8ccedb65b..35b8d66c14 100644 --- a/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs +++ b/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs @@ -84,7 +84,7 @@ fn is_nullable_field<'a>(checker: &'a Checker, value: &'a Expr) -> Option<&'a st return None; }; - let Some(valid_field_name) = helpers::get_model_field_name(checker.semantic_model(), func) else { + let Some(valid_field_name) = helpers::get_model_field_name(func, checker.semantic()) else { return None; }; diff --git a/crates/ruff/src/rules/flake8_django/rules/unordered_body_content_in_model.rs b/crates/ruff/src/rules/flake8_django/rules/unordered_body_content_in_model.rs index b3b198624c..6404a105f6 100644 --- a/crates/ruff/src/rules/flake8_django/rules/unordered_body_content_in_model.rs +++ b/crates/ruff/src/rules/flake8_django/rules/unordered_body_content_in_model.rs @@ -100,11 +100,11 @@ impl fmt::Display for ContentType { } } -fn get_element_type(model: &SemanticModel, element: &Stmt) -> Option { +fn get_element_type(element: &Stmt, semantic: &SemanticModel) -> Option { match element { Stmt::Assign(ast::StmtAssign { targets, value, .. }) => { if let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() { - if helpers::is_model_field(model, func) { + if helpers::is_model_field(func, semantic) { return Some(ContentType::FieldDeclaration); } } @@ -145,13 +145,13 @@ pub(crate) fn unordered_body_content_in_model( ) { if !bases .iter() - .any(|base| helpers::is_model(checker.semantic_model(), base)) + .any(|base| helpers::is_model(base, checker.semantic())) { return; } let mut elements_type_found = Vec::new(); for element in body.iter() { - let Some(current_element_type) = get_element_type(checker.semantic_model(), element) else { + let Some(current_element_type) = get_element_type(element, checker.semantic()) else { continue; }; let Some(&element_type) = elements_type_found diff --git a/crates/ruff/src/rules/flake8_errmsg/rules/string_in_exception.rs b/crates/ruff/src/rules/flake8_errmsg/rules/string_in_exception.rs index b1aca25362..7cf51caf11 100644 --- a/crates/ruff/src/rules/flake8_errmsg/rules/string_in_exception.rs +++ b/crates/ruff/src/rules/flake8_errmsg/rules/string_in_exception.rs @@ -190,7 +190,7 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr if let Some(indentation) = whitespace::indentation(checker.locator, stmt) { - if checker.semantic_model().is_available("msg") { + if checker.semantic().is_available("msg") { diagnostic.set_fix(generate_fix( stmt, first, @@ -213,7 +213,7 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr if let Some(indentation) = whitespace::indentation(checker.locator, stmt) { - if checker.semantic_model().is_available("msg") { + if checker.semantic().is_available("msg") { diagnostic.set_fix(generate_fix( stmt, first, @@ -240,7 +240,7 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr if let Some(indentation) = whitespace::indentation(checker.locator, stmt) { - if checker.semantic_model().is_available("msg") { + if checker.semantic().is_available("msg") { diagnostic.set_fix(generate_fix( stmt, first, diff --git a/crates/ruff/src/rules/flake8_future_annotations/rules/future_rewritable_type_annotation.rs b/crates/ruff/src/rules/flake8_future_annotations/rules/future_rewritable_type_annotation.rs index 1594938fec..6a93534241 100644 --- a/crates/ruff/src/rules/flake8_future_annotations/rules/future_rewritable_type_annotation.rs +++ b/crates/ruff/src/rules/flake8_future_annotations/rules/future_rewritable_type_annotation.rs @@ -65,7 +65,7 @@ impl Violation for FutureRewritableTypeAnnotation { /// FA100 pub(crate) fn future_rewritable_type_annotation(checker: &mut Checker, expr: &Expr) { let name = checker - .semantic_model() + .semantic() .resolve_call_path(expr) .map(|binding| format_call_path(&binding)); diff --git a/crates/ruff/src/rules/flake8_logging_format/rules/logging_call.rs b/crates/ruff/src/rules/flake8_logging_format/rules/logging_call.rs index cd92ae23a7..5dc28bbb3d 100644 --- a/crates/ruff/src/rules/flake8_logging_format/rules/logging_call.rs +++ b/crates/ruff/src/rules/flake8_logging_format/rules/logging_call.rs @@ -106,7 +106,7 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) { } Expr::Call(ast::ExprCall { func, keywords, .. }) => { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| call_path.as_slice() == ["", "dict"]) { @@ -151,7 +151,7 @@ pub(crate) fn logging_call( args: &[Expr], keywords: &[Keyword], ) { - if !logging::is_logger_candidate(func, checker.semantic_model()) { + if !logging::is_logger_candidate(func, checker.semantic()) { return; } @@ -193,10 +193,10 @@ pub(crate) fn logging_call( // G201, G202 if checker.any_enabled(&[Rule::LoggingExcInfo, Rule::LoggingRedundantExcInfo]) { - if !checker.semantic_model().in_exception_handler() { + if !checker.semantic().in_exception_handler() { return; } - let Some(exc_info) = logging::exc_info(keywords, checker.semantic_model()) else { + let Some(exc_info) = logging::exc_info(keywords, checker.semantic()) else { return; }; if let LoggingCallType::LevelCall(logging_level) = logging_call_type { diff --git a/crates/ruff/src/rules/flake8_pie/rules/non_unique_enums.rs b/crates/ruff/src/rules/flake8_pie/rules/non_unique_enums.rs index 47e1a427a5..53697bb340 100644 --- a/crates/ruff/src/rules/flake8_pie/rules/non_unique_enums.rs +++ b/crates/ruff/src/rules/flake8_pie/rules/non_unique_enums.rs @@ -66,7 +66,7 @@ pub(crate) fn non_unique_enums<'a, 'b>( if !bases.iter().any(|expr| { checker - .semantic_model() + .semantic() .resolve_call_path(expr) .map_or(false, |call_path| call_path.as_slice() == ["enum", "Enum"]) }) { @@ -81,7 +81,7 @@ pub(crate) fn non_unique_enums<'a, 'b>( if let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| call_path.as_slice() == ["enum", "auto"]) { diff --git a/crates/ruff/src/rules/flake8_pie/rules/reimplemented_list_builtin.rs b/crates/ruff/src/rules/flake8_pie/rules/reimplemented_list_builtin.rs index c7e562a36a..0e53e5febf 100644 --- a/crates/ruff/src/rules/flake8_pie/rules/reimplemented_list_builtin.rs +++ b/crates/ruff/src/rules/flake8_pie/rules/reimplemented_list_builtin.rs @@ -69,7 +69,7 @@ pub(crate) fn reimplemented_list_builtin(checker: &mut Checker, expr: &ExprLambd if elts.is_empty() { let mut diagnostic = Diagnostic::new(ReimplementedListBuiltin, expr.range()); if checker.patch(diagnostic.kind.rule()) { - if checker.semantic_model().is_builtin("list") { + if checker.semantic().is_builtin("list") { diagnostic.set_fix(Fix::automatic(Edit::range_replacement( "list".to_string(), expr.range(), diff --git a/crates/ruff/src/rules/flake8_print/rules/print_call.rs b/crates/ruff/src/rules/flake8_print/rules/print_call.rs index 13993a202c..23b4d95050 100644 --- a/crates/ruff/src/rules/flake8_print/rules/print_call.rs +++ b/crates/ruff/src/rules/flake8_print/rules/print_call.rs @@ -78,7 +78,7 @@ impl Violation for PPrint { /// T201, T203 pub(crate) fn print_call(checker: &mut Checker, func: &Expr, keywords: &[Keyword]) { let diagnostic = { - let call_path = checker.semantic_model().resolve_call_path(func); + let call_path = checker.semantic().resolve_call_path(func); if call_path .as_ref() .map_or(false, |call_path| *call_path.as_slice() == ["", "print"]) @@ -90,14 +90,13 @@ pub(crate) fn print_call(checker: &mut Checker, func: &Expr, keywords: &[Keyword .find(|keyword| keyword.arg.as_ref().map_or(false, |arg| arg == "file")) { if !is_const_none(&keyword.value) { - if checker - .semantic_model() - .resolve_call_path(&keyword.value) - .map_or(true, |call_path| { + if checker.semantic().resolve_call_path(&keyword.value).map_or( + true, + |call_path| { call_path.as_slice() != ["sys", "stdout"] && call_path.as_slice() != ["sys", "stderr"] - }) - { + }, + ) { return; } } diff --git a/crates/ruff/src/rules/flake8_pyi/rules/any_eq_ne_annotation.rs b/crates/ruff/src/rules/flake8_pyi/rules/any_eq_ne_annotation.rs index 03235b31be..0779bb6575 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/any_eq_ne_annotation.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/any_eq_ne_annotation.rs @@ -66,14 +66,11 @@ pub(crate) fn any_eq_ne_annotation(checker: &mut Checker, name: &str, args: &Arg return; }; - if !checker.semantic_model().scope().kind.is_class() { + if !checker.semantic().scope().kind.is_class() { return; } - if checker - .semantic_model() - .match_typing_expr(annotation, "Any") - { + if checker.semantic().match_typing_expr(annotation, "Any") { let mut diagnostic = Diagnostic::new( AnyEqNeAnnotation { method_name: name.to_string(), @@ -82,7 +79,7 @@ pub(crate) fn any_eq_ne_annotation(checker: &mut Checker, name: &str, args: &Arg ); if checker.patch(diagnostic.kind.rule()) { // Ex) `def __eq__(self, obj: Any): ...` - if checker.semantic_model().is_builtin("object") { + if checker.semantic().is_builtin("object") { diagnostic.set_fix(Fix::automatic(Edit::range_replacement( "object".to_string(), annotation.range(), diff --git a/crates/ruff/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs b/crates/ruff/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs index 8d923d1cfa..a75dd025e3 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs @@ -69,7 +69,7 @@ pub(crate) fn bad_version_info_comparison( }; if !checker - .semantic_model() + .semantic() .resolve_call_path(left) .map_or(false, |call_path| { call_path.as_slice() == ["sys", "version_info"] diff --git a/crates/ruff/src/rules/flake8_pyi/rules/collections_named_tuple.rs b/crates/ruff/src/rules/flake8_pyi/rules/collections_named_tuple.rs index 7f171b7558..9accde17c3 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/collections_named_tuple.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/collections_named_tuple.rs @@ -51,7 +51,7 @@ impl Violation for CollectionsNamedTuple { /// PYI024 pub(crate) fn collections_named_tuple(checker: &mut Checker, expr: &Expr) { if checker - .semantic_model() + .semantic() .resolve_call_path(expr) .map_or(false, |call_path| { matches!(call_path.as_slice(), ["collections", "namedtuple"]) diff --git a/crates/ruff/src/rules/flake8_pyi/rules/iter_method_return_iterable.rs b/crates/ruff/src/rules/flake8_pyi/rules/iter_method_return_iterable.rs index b60b500afb..db3aa58bed 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/iter_method_return_iterable.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/iter_method_return_iterable.rs @@ -101,7 +101,7 @@ pub(crate) fn iter_method_return_iterable(checker: &mut Checker, definition: &De }; if checker - .semantic_model() + .semantic() .resolve_call_path(annotation) .map_or(false, |call_path| { if async_ { diff --git a/crates/ruff/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs b/crates/ruff/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs index 8fcb45d403..c45275f9db 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs @@ -56,10 +56,7 @@ pub(crate) fn no_return_argument_annotation(checker: &mut Checker, args: &Argume ) .filter_map(|arg| arg.annotation.as_ref()) { - if checker - .semantic_model() - .match_typing_expr(annotation, "NoReturn") - { + if checker.semantic().match_typing_expr(annotation, "NoReturn") { checker.diagnostics.push(Diagnostic::new( NoReturnArgumentAnnotationInStub { module: if checker.settings.target_version >= Py311 { diff --git a/crates/ruff/src/rules/flake8_pyi/rules/non_self_return_type.rs b/crates/ruff/src/rules/flake8_pyi/rules/non_self_return_type.rs index fdaeb56510..5a3bb60e74 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/non_self_return_type.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/non_self_return_type.rs @@ -118,7 +118,7 @@ pub(crate) fn non_self_return_type( args: &Arguments, async_: bool, ) { - let ScopeKind::Class(class_def) = checker.semantic_model().scope().kind else { + let ScopeKind::Class(class_def) = checker.semantic().scope().kind else { return; }; @@ -131,8 +131,8 @@ pub(crate) fn non_self_return_type( }; // Skip any abstract or overloaded methods. - if is_abstract(checker.semantic_model(), decorator_list) - || is_overload(checker.semantic_model(), decorator_list) + if is_abstract(decorator_list, checker.semantic()) + || is_overload(decorator_list, checker.semantic()) { return; } @@ -140,7 +140,7 @@ pub(crate) fn non_self_return_type( if async_ { if name == "__aenter__" && is_name(returns, &class_def.name) - && !is_final(checker.semantic_model(), &class_def.decorator_list) + && !is_final(&class_def.decorator_list, checker.semantic()) { checker.diagnostics.push(Diagnostic::new( NonSelfReturnType { @@ -155,7 +155,7 @@ pub(crate) fn non_self_return_type( // In-place methods that are expected to return `Self`. if INPLACE_BINOP_METHODS.contains(&name) { - if !is_self(returns, checker.semantic_model()) { + if !is_self(returns, checker.semantic()) { checker.diagnostics.push(Diagnostic::new( NonSelfReturnType { class_name: class_def.name.to_string(), @@ -169,7 +169,7 @@ pub(crate) fn non_self_return_type( if is_name(returns, &class_def.name) { if matches!(name, "__enter__" | "__new__") - && !is_final(checker.semantic_model(), &class_def.decorator_list) + && !is_final(&class_def.decorator_list, checker.semantic()) { checker.diagnostics.push(Diagnostic::new( NonSelfReturnType { @@ -184,8 +184,8 @@ pub(crate) fn non_self_return_type( match name { "__iter__" => { - if is_iterable(returns, checker.semantic_model()) - && is_iterator(&class_def.bases, checker.semantic_model()) + if is_iterable(returns, checker.semantic()) + && is_iterator(&class_def.bases, checker.semantic()) { checker.diagnostics.push(Diagnostic::new( NonSelfReturnType { @@ -197,8 +197,8 @@ pub(crate) fn non_self_return_type( } } "__aiter__" => { - if is_async_iterable(returns, checker.semantic_model()) - && is_async_iterator(&class_def.bases, checker.semantic_model()) + if is_async_iterable(returns, checker.semantic()) + && is_async_iterator(&class_def.bases, checker.semantic()) { checker.diagnostics.push(Diagnostic::new( NonSelfReturnType { @@ -238,14 +238,14 @@ fn is_name(expr: &Expr, name: &str) -> bool { } /// Return `true` if the given expression resolves to `typing.Self`. -fn is_self(expr: &Expr, model: &SemanticModel) -> bool { - model.match_typing_expr(expr, "Self") +fn is_self(expr: &Expr, semantic: &SemanticModel) -> bool { + semantic.match_typing_expr(expr, "Self") } /// Return `true` if the given class extends `collections.abc.Iterator`. -fn is_iterator(bases: &[Expr], model: &SemanticModel) -> bool { +fn is_iterator(bases: &[Expr], semantic: &SemanticModel) -> bool { bases.iter().any(|expr| { - model + semantic .resolve_call_path(map_subscript(expr)) .map_or(false, |call_path| { matches!( @@ -257,8 +257,8 @@ fn is_iterator(bases: &[Expr], model: &SemanticModel) -> bool { } /// Return `true` if the given expression resolves to `collections.abc.Iterable`. -fn is_iterable(expr: &Expr, model: &SemanticModel) -> bool { - model +fn is_iterable(expr: &Expr, semantic: &SemanticModel) -> bool { + semantic .resolve_call_path(map_subscript(expr)) .map_or(false, |call_path| { matches!( @@ -270,9 +270,9 @@ fn is_iterable(expr: &Expr, model: &SemanticModel) -> bool { } /// Return `true` if the given class extends `collections.abc.AsyncIterator`. -fn is_async_iterator(bases: &[Expr], model: &SemanticModel) -> bool { +fn is_async_iterator(bases: &[Expr], semantic: &SemanticModel) -> bool { bases.iter().any(|expr| { - model + semantic .resolve_call_path(map_subscript(expr)) .map_or(false, |call_path| { matches!( @@ -284,8 +284,8 @@ fn is_async_iterator(bases: &[Expr], model: &SemanticModel) -> bool { } /// Return `true` if the given expression resolves to `collections.abc.AsyncIterable`. -fn is_async_iterable(expr: &Expr, model: &SemanticModel) -> bool { - model +fn is_async_iterable(expr: &Expr, semantic: &SemanticModel) -> bool { + semantic .resolve_call_path(map_subscript(expr)) .map_or(false, |call_path| { matches!( diff --git a/crates/ruff/src/rules/flake8_pyi/rules/prefix_type_params.rs b/crates/ruff/src/rules/flake8_pyi/rules/prefix_type_params.rs index e6c561191e..07f62306b7 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/prefix_type_params.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/prefix_type_params.rs @@ -70,12 +70,12 @@ pub(crate) fn prefix_type_params(checker: &mut Checker, value: &Expr, targets: & }; if let Expr::Call(ast::ExprCall { func, .. }) = value { - let Some(kind) = checker.semantic_model().resolve_call_path(func).and_then(|call_path| { - if checker.semantic_model().match_typing_call_path(&call_path, "ParamSpec") { + let Some(kind) = checker.semantic().resolve_call_path(func).and_then(|call_path| { + if checker.semantic().match_typing_call_path(&call_path, "ParamSpec") { Some(VarKind::ParamSpec) - } else if checker.semantic_model().match_typing_call_path(&call_path, "TypeVar") { + } else if checker.semantic().match_typing_call_path(&call_path, "TypeVar") { Some(VarKind::TypeVar) - } else if checker.semantic_model().match_typing_call_path(&call_path, "TypeVarTuple") { + } else if checker.semantic().match_typing_call_path(&call_path, "TypeVarTuple") { Some(VarKind::TypeVarTuple) } else { None diff --git a/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs b/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs index eff56ed300..c7299a7656 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs @@ -123,7 +123,7 @@ fn is_valid_default_value_with_annotation( default: &Expr, allow_container: bool, locator: &Locator, - model: &SemanticModel, + semantic: &SemanticModel, ) -> bool { match default { Expr::Constant(_) => { @@ -136,7 +136,7 @@ fn is_valid_default_value_with_annotation( && elts.len() <= 10 && elts .iter() - .all(|e| is_valid_default_value_with_annotation(e, false, locator, model)); + .all(|e| is_valid_default_value_with_annotation(e, false, locator, semantic)); } Expr::Dict(ast::ExprDict { keys, @@ -147,8 +147,8 @@ fn is_valid_default_value_with_annotation( && keys.len() <= 10 && keys.iter().zip(values).all(|(k, v)| { k.as_ref().map_or(false, |k| { - is_valid_default_value_with_annotation(k, false, locator, model) - }) && is_valid_default_value_with_annotation(v, false, locator, model) + is_valid_default_value_with_annotation(k, false, locator, semantic) + }) && is_valid_default_value_with_annotation(v, false, locator, semantic) }); } Expr::UnaryOp(ast::ExprUnaryOp { @@ -164,12 +164,15 @@ fn is_valid_default_value_with_annotation( }) => return true, // Ex) `-math.inf`, `-math.pi`, etc. Expr::Attribute(_) => { - if model.resolve_call_path(operand).map_or(false, |call_path| { - ALLOWED_MATH_ATTRIBUTES_IN_DEFAULTS.iter().any(|target| { - // reject `-math.nan` - call_path.as_slice() == *target && *target != ["math", "nan"] + if semantic + .resolve_call_path(operand) + .map_or(false, |call_path| { + ALLOWED_MATH_ATTRIBUTES_IN_DEFAULTS.iter().any(|target| { + // reject `-math.nan` + call_path.as_slice() == *target && *target != ["math", "nan"] + }) }) - }) { + { return true; } } @@ -214,12 +217,15 @@ fn is_valid_default_value_with_annotation( } // Ex) `math.inf`, `sys.stdin`, etc. Expr::Attribute(_) => { - if model.resolve_call_path(default).map_or(false, |call_path| { - ALLOWED_MATH_ATTRIBUTES_IN_DEFAULTS - .iter() - .chain(ALLOWED_ATTRIBUTES_IN_DEFAULTS.iter()) - .any(|target| call_path.as_slice() == *target) - }) { + if semantic + .resolve_call_path(default) + .map_or(false, |call_path| { + ALLOWED_MATH_ATTRIBUTES_IN_DEFAULTS + .iter() + .chain(ALLOWED_ATTRIBUTES_IN_DEFAULTS.iter()) + .any(|target| call_path.as_slice() == *target) + }) + { return true; } } @@ -265,11 +271,11 @@ fn is_valid_default_value_without_annotation(default: &Expr) -> bool { /// Returns `true` if an [`Expr`] appears to be `TypeVar`, `TypeVarTuple`, `NewType`, or `ParamSpec` /// call. -fn is_type_var_like_call(model: &SemanticModel, expr: &Expr) -> bool { +fn is_type_var_like_call(expr: &Expr, semantic: &SemanticModel) -> bool { let Expr::Call(ast::ExprCall { func, .. } )= expr else { return false; }; - model.resolve_call_path(func).map_or(false, |call_path| { + semantic.resolve_call_path(func).map_or(false, |call_path| { matches!( call_path.as_slice(), [ @@ -282,11 +288,11 @@ fn is_type_var_like_call(model: &SemanticModel, expr: &Expr) -> bool { /// Returns `true` if this is a "special" assignment which must have a value (e.g., an assignment to /// `__all__`). -fn is_special_assignment(model: &SemanticModel, target: &Expr) -> bool { +fn is_special_assignment(target: &Expr, semantic: &SemanticModel) -> bool { if let Expr::Name(ast::ExprName { id, .. }) = target { match id.as_str() { - "__all__" => model.scope().kind.is_module(), - "__match_args__" | "__slots__" => model.scope().kind.is_class(), + "__all__" => semantic.scope().kind.is_module(), + "__match_args__" | "__slots__" => semantic.scope().kind.is_class(), _ => false, } } else { @@ -295,9 +301,9 @@ fn is_special_assignment(model: &SemanticModel, target: &Expr) -> bool { } /// Returns `true` if the a class is an enum, based on its base classes. -fn is_enum(model: &SemanticModel, bases: &[Expr]) -> bool { +fn is_enum(bases: &[Expr], semantic: &SemanticModel) -> bool { return bases.iter().any(|expr| { - model.resolve_call_path(expr).map_or(false, |call_path| { + semantic.resolve_call_path(expr).map_or(false, |call_path| { matches!( call_path.as_slice(), [ @@ -323,7 +329,7 @@ pub(crate) fn typed_argument_simple_defaults(checker: &mut Checker, args: &Argum default, true, checker.locator, - checker.semantic_model(), + checker.semantic(), ) { let mut diagnostic = Diagnostic::new(TypedArgumentDefaultInStub, default.range()); @@ -354,7 +360,7 @@ pub(crate) fn typed_argument_simple_defaults(checker: &mut Checker, args: &Argum default, true, checker.locator, - checker.semantic_model(), + checker.semantic(), ) { let mut diagnostic = Diagnostic::new(TypedArgumentDefaultInStub, default.range()); @@ -388,7 +394,7 @@ pub(crate) fn argument_simple_defaults(checker: &mut Checker, args: &Arguments) default, true, checker.locator, - checker.semantic_model(), + checker.semantic(), ) { let mut diagnostic = Diagnostic::new(ArgumentDefaultInStub, default.range()); @@ -419,7 +425,7 @@ pub(crate) fn argument_simple_defaults(checker: &mut Checker, args: &Arguments) default, true, checker.locator, - checker.semantic_model(), + checker.semantic(), ) { let mut diagnostic = Diagnostic::new(ArgumentDefaultInStub, default.range()); @@ -448,21 +454,16 @@ pub(crate) fn assignment_default_in_stub(checker: &mut Checker, targets: &[Expr] if !target.is_name_expr() { return; } - if is_special_assignment(checker.semantic_model(), target) { + if is_special_assignment(target, checker.semantic()) { return; } - if is_type_var_like_call(checker.semantic_model(), value) { + if is_type_var_like_call(value, checker.semantic()) { return; } if is_valid_default_value_without_annotation(value) { return; } - if is_valid_default_value_with_annotation( - value, - true, - checker.locator, - checker.semantic_model(), - ) { + if is_valid_default_value_with_annotation(value, true, checker.locator, checker.semantic()) { return; } @@ -484,23 +485,18 @@ pub(crate) fn annotated_assignment_default_in_stub( annotation: &Expr, ) { if checker - .semantic_model() + .semantic() .match_typing_expr(annotation, "TypeAlias") { return; } - if is_special_assignment(checker.semantic_model(), target) { + if is_special_assignment(target, checker.semantic()) { return; } - if is_type_var_like_call(checker.semantic_model(), value) { + if is_type_var_like_call(value, checker.semantic()) { return; } - if is_valid_default_value_with_annotation( - value, - true, - checker.locator, - checker.semantic_model(), - ) { + if is_valid_default_value_with_annotation(value, true, checker.locator, checker.semantic()) { return; } @@ -527,27 +523,21 @@ pub(crate) fn unannotated_assignment_in_stub( let Expr::Name(ast::ExprName { id, .. }) = target else { return; }; - if is_special_assignment(checker.semantic_model(), target) { + if is_special_assignment(target, checker.semantic()) { return; } - if is_type_var_like_call(checker.semantic_model(), value) { + if is_type_var_like_call(value, checker.semantic()) { return; } if is_valid_default_value_without_annotation(value) { return; } - if !is_valid_default_value_with_annotation( - value, - true, - checker.locator, - checker.semantic_model(), - ) { + if !is_valid_default_value_with_annotation(value, true, checker.locator, checker.semantic()) { return; } - if let ScopeKind::Class(ast::StmtClassDef { bases, .. }) = checker.semantic_model().scope().kind - { - if is_enum(checker.semantic_model(), bases) { + if let ScopeKind::Class(ast::StmtClassDef { bases, .. }) = checker.semantic().scope().kind { + if is_enum(bases, checker.semantic()) { return; } } @@ -569,7 +559,7 @@ pub(crate) fn unassigned_special_variable_in_stub( return; }; - if !is_special_assignment(checker.semantic_model(), target) { + if !is_special_assignment(target, checker.semantic()) { return; } diff --git a/crates/ruff/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs b/crates/ruff/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs index 88f204fcc3..0d40ff8f9f 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs @@ -62,7 +62,7 @@ pub(crate) fn str_or_repr_defined_in_stub(checker: &mut Checker, stmt: &Stmt) { return; } - if !checker.semantic_model().scope().kind.is_class() { + if !checker.semantic().scope().kind.is_class() { return; } @@ -72,12 +72,12 @@ pub(crate) fn str_or_repr_defined_in_stub(checker: &mut Checker, stmt: &Stmt) { return; } - if is_abstract(checker.semantic_model(), decorator_list) { + if is_abstract(decorator_list, checker.semantic()) { return; } if checker - .semantic_model() + .semantic() .resolve_call_path(returns) .map_or(true, |call_path| { !matches!(call_path.as_slice(), ["" | "builtins", "str"]) @@ -93,8 +93,8 @@ pub(crate) fn str_or_repr_defined_in_stub(checker: &mut Checker, stmt: &Stmt) { identifier_range(stmt, checker.locator), ); if checker.patch(diagnostic.kind.rule()) { - let stmt = checker.semantic_model().stmt(); - let parent = checker.semantic_model().stmt_parent(); + let stmt = checker.semantic().stmt(); + let parent = checker.semantic().stmt_parent(); let edit = delete_stmt( stmt, parent, @@ -103,7 +103,7 @@ pub(crate) fn str_or_repr_defined_in_stub(checker: &mut Checker, stmt: &Stmt) { checker.stylist, ); diagnostic.set_fix( - Fix::automatic(edit).isolate(checker.isolation(checker.semantic_model().stmt_parent())), + Fix::automatic(edit).isolate(checker.isolation(checker.semantic().stmt_parent())), ); } checker.diagnostics.push(diagnostic); diff --git a/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs b/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs index 1efb416a0a..3aa892bb27 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs @@ -103,7 +103,7 @@ pub(crate) fn unrecognized_platform( let diagnostic_unrecognized_platform_check = Diagnostic::new(UnrecognizedPlatformCheck, expr.range()); if !checker - .semantic_model() + .semantic() .resolve_call_path(left) .map_or(false, |call_path| { call_path.as_slice() == ["sys", "platform"] diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/assertion.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/assertion.rs index ee2f4f7c10..ef73693881 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/assertion.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/assertion.rs @@ -194,9 +194,9 @@ pub(crate) fn unittest_assertion( if checker.patch(diagnostic.kind.rule()) { // We're converting an expression to a statement, so avoid applying the fix if // the assertion is part of a larger expression. - if checker.semantic_model().stmt().is_expr_stmt() - && checker.semantic_model().expr_parent().is_none() - && !checker.semantic_model().scope().kind.is_lambda() + if checker.semantic().stmt().is_expr_stmt() + && checker.semantic().expr_parent().is_none() + && !checker.semantic().scope().kind.is_lambda() && !has_comments_in(expr.range(), checker.locator) { if let Ok(stmt) = unittest_assert.generate_assert(args, keywords) { @@ -219,7 +219,7 @@ pub(crate) fn unittest_assertion( /// PT015 pub(crate) fn assert_falsy(checker: &mut Checker, stmt: &Stmt, test: &Expr) { - if Truthiness::from_expr(test, |id| checker.semantic_model().is_builtin(id)).is_falsey() { + if Truthiness::from_expr(test, |id| checker.semantic().is_builtin(id)).is_falsey() { checker .diagnostics .push(Diagnostic::new(PytestAssertAlwaysFalse, stmt.range())); diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/fail.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/fail.rs index 5f11d6f2f6..7c840db2a1 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/fail.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/fail.rs @@ -19,7 +19,7 @@ impl Violation for PytestFailWithoutMessage { } pub(crate) fn fail_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: &[Keyword]) { - if is_pytest_fail(checker.semantic_model(), func) { + if is_pytest_fail(func, checker.semantic()) { let call_args = SimpleCallArgs::new(args, keywords); // Allow either `pytest.fail(reason="...")` (introduced in pytest 7.0) or diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs index 6542628bf8..af1250bd87 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs @@ -245,11 +245,11 @@ where } fn get_fixture_decorator<'a>( - model: &SemanticModel, decorators: &'a [Decorator], + semantic: &SemanticModel, ) -> Option<&'a Decorator> { decorators.iter().find(|decorator| { - is_pytest_fixture(model, decorator) || is_pytest_yield_fixture(model, decorator) + is_pytest_fixture(decorator, semantic) || is_pytest_yield_fixture(decorator, semantic) }) } @@ -436,7 +436,7 @@ fn check_test_function_args(checker: &mut Checker, args: &Arguments) { /// PT020 fn check_fixture_decorator_name(checker: &mut Checker, decorator: &Decorator) { - if is_pytest_yield_fixture(checker.semantic_model(), decorator) { + if is_pytest_yield_fixture(decorator, checker.semantic()) { checker.diagnostics.push(Diagnostic::new( PytestDeprecatedYieldFixture, decorator.range(), @@ -504,7 +504,7 @@ pub(crate) fn fixture( decorators: &[Decorator], body: &[Stmt], ) { - let decorator = get_fixture_decorator(checker.semantic_model(), decorators); + let decorator = get_fixture_decorator(decorators, checker.semantic()); if let Some(decorator) = decorator { if checker.enabled(Rule::PytestFixtureIncorrectParenthesesStyle) || checker.enabled(Rule::PytestFixturePositionalArgs) @@ -522,7 +522,7 @@ pub(crate) fn fixture( if (checker.enabled(Rule::PytestMissingFixtureNameUnderscore) || checker.enabled(Rule::PytestIncorrectFixtureNameUnderscore) || checker.enabled(Rule::PytestUselessYieldFixture)) - && !is_abstract(checker.semantic_model(), decorators) + && !is_abstract(decorators, checker.semantic()) { check_fixture_returns(checker, stmt, name, body); } diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/helpers.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/helpers.rs index 826dbfd530..5c2a3c1449 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/helpers.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/helpers.rs @@ -20,41 +20,41 @@ pub(super) fn get_mark_decorators( }) } -pub(super) fn is_pytest_fail(model: &SemanticModel, call: &Expr) -> bool { - model.resolve_call_path(call).map_or(false, |call_path| { +pub(super) fn is_pytest_fail(call: &Expr, semantic: &SemanticModel) -> bool { + semantic.resolve_call_path(call).map_or(false, |call_path| { call_path.as_slice() == ["pytest", "fail"] }) } -pub(super) fn is_pytest_fixture(model: &SemanticModel, decorator: &Decorator) -> bool { - model +pub(super) fn is_pytest_fixture(decorator: &Decorator, semantic: &SemanticModel) -> bool { + semantic .resolve_call_path(map_callable(&decorator.expression)) .map_or(false, |call_path| { call_path.as_slice() == ["pytest", "fixture"] }) } -pub(super) fn is_pytest_yield_fixture(model: &SemanticModel, decorator: &Decorator) -> bool { - model +pub(super) fn is_pytest_yield_fixture(decorator: &Decorator, semantic: &SemanticModel) -> bool { + semantic .resolve_call_path(map_callable(&decorator.expression)) .map_or(false, |call_path| { call_path.as_slice() == ["pytest", "yield_fixture"] }) } -pub(super) fn is_pytest_parametrize(model: &SemanticModel, decorator: &Decorator) -> bool { - model +pub(super) fn is_pytest_parametrize(decorator: &Decorator, semantic: &SemanticModel) -> bool { + semantic .resolve_call_path(map_callable(&decorator.expression)) .map_or(false, |call_path| { call_path.as_slice() == ["pytest", "mark", "parametrize"] }) } -pub(super) fn keyword_is_literal(kw: &Keyword, literal: &str) -> bool { +pub(super) fn keyword_is_literal(keyword: &Keyword, literal: &str) -> bool { if let Expr::Constant(ast::ExprConstant { value: Constant::Str(string), .. - }) = &kw.value + }) = &keyword.value { string == literal } else { diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/parametrize.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/parametrize.rs index a0a3b2e75b..8db8d75c23 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/parametrize.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/parametrize.rs @@ -419,7 +419,7 @@ fn handle_value_rows( pub(crate) fn parametrize(checker: &mut Checker, decorators: &[Decorator]) { for decorator in decorators { - if is_pytest_parametrize(checker.semantic_model(), decorator) { + if is_pytest_parametrize(decorator, checker.semantic()) { if let Expr::Call(ast::ExprCall { args, .. }) = &decorator.expression { if checker.enabled(Rule::PytestParametrizeNamesWrongType) { if let Some(names) = args.get(0) { diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/raises.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/raises.rs index e2c25bf154..9e1b62a4b8 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/raises.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/raises.rs @@ -47,8 +47,8 @@ impl Violation for PytestRaisesWithoutException { } } -fn is_pytest_raises(func: &Expr, model: &SemanticModel) -> bool { - model.resolve_call_path(func).map_or(false, |call_path| { +fn is_pytest_raises(func: &Expr, semantic: &SemanticModel) -> bool { + semantic.resolve_call_path(func).map_or(false, |call_path| { call_path.as_slice() == ["pytest", "raises"] }) } @@ -64,7 +64,7 @@ const fn is_non_trivial_with_body(body: &[Stmt]) -> bool { } pub(crate) fn raises_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: &[Keyword]) { - if is_pytest_raises(func, checker.semantic_model()) { + if is_pytest_raises(func, checker.semantic()) { if checker.enabled(Rule::PytestRaisesWithoutException) { if args.is_empty() && keywords.is_empty() { checker @@ -100,7 +100,7 @@ pub(crate) fn complex_raises( let mut is_too_complex = false; let raises_called = items.iter().any(|item| match &item.context_expr { - Expr::Call(ast::ExprCall { func, .. }) => is_pytest_raises(func, checker.semantic_model()), + Expr::Call(ast::ExprCall { func, .. }) => is_pytest_raises(func, checker.semantic()), _ => false, }); @@ -141,7 +141,7 @@ pub(crate) fn complex_raises( /// PT011 fn exception_needs_match(checker: &mut Checker, exception: &Expr) { if let Some(call_path) = checker - .semantic_model() + .semantic() .resolve_call_path(exception) .and_then(|call_path| { let is_broad_exception = checker diff --git a/crates/ruff/src/rules/flake8_return/rules/function.rs b/crates/ruff/src/rules/flake8_return/rules/function.rs index 25b50a8162..502f76d7ed 100644 --- a/crates/ruff/src/rules/flake8_return/rules/function.rs +++ b/crates/ruff/src/rules/flake8_return/rules/function.rs @@ -398,12 +398,12 @@ const NORETURN_FUNCS: &[&[&str]] = &[ ]; /// Return `true` if the `func` is a known function that never returns. -fn is_noreturn_func(model: &SemanticModel, func: &Expr) -> bool { - model.resolve_call_path(func).map_or(false, |call_path| { +fn is_noreturn_func(func: &Expr, semantic: &SemanticModel) -> bool { + semantic.resolve_call_path(func).map_or(false, |call_path| { NORETURN_FUNCS .iter() .any(|target| call_path.as_slice() == *target) - || model.match_typing_call_path(&call_path, "assert_never") + || semantic.match_typing_call_path(&call_path, "assert_never") }) } @@ -489,7 +489,7 @@ fn implicit_return(checker: &mut Checker, stmt: &Stmt) { if matches!( value.as_ref(), Expr::Call(ast::ExprCall { func, .. }) - if is_noreturn_func(checker.semantic_model(), func) + if is_noreturn_func(func, checker.semantic()) ) => {} _ => { let mut diagnostic = Diagnostic::new(ImplicitReturn, stmt.range()); diff --git a/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs b/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs index fb8412aaf8..7e18208ac3 100644 --- a/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs +++ b/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs @@ -77,7 +77,7 @@ pub(crate) fn private_member_access(checker: &mut Checker, expr: &Expr) { // Ignore accesses on instances within special methods (e.g., `__eq__`). if let ScopeKind::Function(ast::StmtFunctionDef { name, .. }) = - checker.semantic_model().scope().kind + checker.semantic().scope().kind { if matches!( name.as_str(), @@ -151,7 +151,7 @@ pub(crate) fn private_member_access(checker: &mut Checker, expr: &Expr) { // Ignore accesses on class members from _within_ the class. if checker - .semantic_model() + .semantic() .scopes .iter() .rev() @@ -162,7 +162,7 @@ pub(crate) fn private_member_access(checker: &mut Checker, expr: &Expr) { .map_or(false, |name| { if call_path.as_slice() == [name.as_str()] { checker - .semantic_model() + .semantic() .find_binding(name) .map_or(false, |binding| { // TODO(charlie): Could the name ever be bound to a diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_bool_op.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_bool_op.rs index 3ed0b7492b..7a21a13ead 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_bool_op.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_bool_op.rs @@ -323,7 +323,7 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { if func_name != "isinstance" { continue; } - if !checker.semantic_model().is_builtin("isinstance") { + if !checker.semantic().is_builtin("isinstance") { continue; } @@ -356,7 +356,7 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { expr.range(), ); if checker.patch(diagnostic.kind.rule()) { - if !contains_effect(target, |id| checker.semantic_model().is_builtin(id)) { + if !contains_effect(target, |id| checker.semantic().is_builtin(id)) { // Grab the types used in each duplicate `isinstance` call (e.g., `int` and `str` // in `isinstance(obj, int) or isinstance(obj, str)`). let types: Vec<&Expr> = indices @@ -478,7 +478,7 @@ pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) { // Avoid rewriting (e.g.) `a == "foo" or a == f()`. if comparators .iter() - .any(|expr| contains_effect(expr, |id| checker.semantic_model().is_builtin(id))) + .any(|expr| contains_effect(expr, |id| checker.semantic().is_builtin(id))) { continue; } @@ -569,7 +569,7 @@ pub(crate) fn expr_and_not_expr(checker: &mut Checker, expr: &Expr) { return; } - if contains_effect(expr, |id| checker.semantic_model().is_builtin(id)) { + if contains_effect(expr, |id| checker.semantic().is_builtin(id)) { return; } @@ -624,7 +624,7 @@ pub(crate) fn expr_or_not_expr(checker: &mut Checker, expr: &Expr) { return; } - if contains_effect(expr, |id| checker.semantic_model().is_builtin(id)) { + if contains_effect(expr, |id| checker.semantic().is_builtin(id)) { return; } @@ -693,15 +693,14 @@ fn is_short_circuit( for (index, (value, next_value)) in values.iter().tuple_windows().enumerate() { // Keep track of the location of the furthest-right, truthy or falsey expression. - let value_truthiness = - Truthiness::from_expr(value, |id| checker.semantic_model().is_builtin(id)); + let value_truthiness = Truthiness::from_expr(value, |id| checker.semantic().is_builtin(id)); let next_value_truthiness = - Truthiness::from_expr(next_value, |id| checker.semantic_model().is_builtin(id)); + Truthiness::from_expr(next_value, |id| checker.semantic().is_builtin(id)); // Keep track of the location of the furthest-right, non-effectful expression. if value_truthiness.is_unknown() - && (!checker.semantic_model().in_boolean_test() - || contains_effect(value, |id| checker.semantic_model().is_builtin(id))) + && (!checker.semantic().in_boolean_test() + || contains_effect(value, |id| checker.semantic().is_builtin(id))) { location = next_value.start(); continue; @@ -721,7 +720,7 @@ fn is_short_circuit( value, TextRange::new(location, expr.end()), short_circuit_truthiness, - checker.semantic_model().in_boolean_test(), + checker.semantic().in_boolean_test(), checker, )); break; @@ -739,7 +738,7 @@ fn is_short_circuit( next_value, TextRange::new(location, expr.end()), short_circuit_truthiness, - checker.semantic_model().in_boolean_test(), + checker.semantic().in_boolean_test(), checker, )); break; diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs index f552b6f378..649b90596c 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs @@ -112,7 +112,7 @@ pub(crate) fn use_capital_environment_variables(checker: &mut Checker, expr: &Ex return; }; if !checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["os", "environ", "get"] diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_if.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_if.rs index 096bb354d0..14da927c36 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_if.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_if.rs @@ -449,7 +449,7 @@ pub(crate) fn needless_bool(checker: &mut Checker, stmt: &Stmt) { if matches!(if_return, Bool::True) && matches!(else_return, Bool::False) && !has_comments(stmt, checker.locator) - && (test.is_compare_expr() || checker.semantic_model().is_builtin("bool")) + && (test.is_compare_expr() || checker.semantic().is_builtin("bool")) { if test.is_compare_expr() { // If the condition is a comparison, we can replace it with the condition. @@ -508,9 +508,9 @@ fn ternary(target_var: &Expr, body_value: &Expr, test: &Expr, orelse_value: &Exp } /// Return `true` if the `Expr` contains a reference to `${module}.${target}`. -fn contains_call_path(model: &SemanticModel, expr: &Expr, target: &[&str]) -> bool { +fn contains_call_path(expr: &Expr, target: &[&str], semantic: &SemanticModel) -> bool { any_over_expr(expr, &|expr| { - model + semantic .resolve_call_path(expr) .map_or(false, |call_path| call_path.as_slice() == target) }) @@ -544,13 +544,13 @@ pub(crate) fn use_ternary_operator(checker: &mut Checker, stmt: &Stmt, parent: O } // Avoid suggesting ternary for `if sys.version_info >= ...`-style checks. - if contains_call_path(checker.semantic_model(), test, &["sys", "version_info"]) { + if contains_call_path(test, &["sys", "version_info"], checker.semantic()) { return; } // Avoid suggesting ternary for `if sys.platform.startswith("...")`-style // checks. - if contains_call_path(checker.semantic_model(), test, &["sys", "platform"]) { + if contains_call_path(test, &["sys", "platform"], checker.semantic()) { return; } @@ -747,7 +747,7 @@ pub(crate) fn manual_dict_lookup( return; }; if value.as_ref().map_or(false, |value| { - contains_effect(value, |id| checker.semantic_model().is_builtin(id)) + contains_effect(value, |id| checker.semantic().is_builtin(id)) }) { return; } @@ -820,7 +820,7 @@ pub(crate) fn manual_dict_lookup( return; }; if value.as_ref().map_or(false, |value| { - contains_effect(value, |id| checker.semantic_model().is_builtin(id)) + contains_effect(value, |id| checker.semantic().is_builtin(id)) }) { return; }; @@ -903,7 +903,7 @@ pub(crate) fn use_dict_get_with_default( } // Check that the default value is not "complex". - if contains_effect(default_value, |id| checker.semantic_model().is_builtin(id)) { + if contains_effect(default_value, |id| checker.semantic().is_builtin(id)) { return; } diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_ifexp.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_ifexp.rs index d10a58f8ac..7210e6b202 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_ifexp.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_ifexp.rs @@ -167,7 +167,7 @@ pub(crate) fn explicit_true_false_in_ifexpr( checker.generator().expr(&test.clone()), expr.range(), ))); - } else if checker.semantic_model().is_builtin("bool") { + } else if checker.semantic().is_builtin("bool") { let node = ast::ExprName { id: "bool".into(), ctx: ExprContext::Load, diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_unary_op.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_unary_op.rs index 9d04312b70..e303b1974f 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_unary_op.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_unary_op.rs @@ -150,14 +150,14 @@ pub(crate) fn negation_with_equal_op( if !matches!(&ops[..], [Cmpop::Eq]) { return; } - if is_exception_check(checker.semantic_model().stmt()) { + if is_exception_check(checker.semantic().stmt()) { return; } // Avoid flagging issues in dunder implementations. if let ScopeKind::Function(ast::StmtFunctionDef { name, .. }) | ScopeKind::AsyncFunction(ast::StmtAsyncFunctionDef { name, .. }) = - &checker.semantic_model().scope().kind + &checker.semantic().scope().kind { if DUNDER_METHODS.contains(&name.as_str()) { return; @@ -203,14 +203,14 @@ pub(crate) fn negation_with_not_equal_op( if !matches!(&ops[..], [Cmpop::NotEq]) { return; } - if is_exception_check(checker.semantic_model().stmt()) { + if is_exception_check(checker.semantic().stmt()) { return; } // Avoid flagging issues in dunder implementations. if let ScopeKind::Function(ast::StmtFunctionDef { name, .. }) | ScopeKind::AsyncFunction(ast::StmtAsyncFunctionDef { name, .. }) = - &checker.semantic_model().scope().kind + &checker.semantic().scope().kind { if DUNDER_METHODS.contains(&name.as_str()) { return; @@ -259,13 +259,13 @@ pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: Unaryop, o expr.range(), ); if checker.patch(diagnostic.kind.rule()) { - if checker.semantic_model().in_boolean_test() { + if checker.semantic().in_boolean_test() { #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( checker.generator().expr(operand), expr.range(), ))); - } else if checker.semantic_model().is_builtin("bool") { + } else if checker.semantic().is_builtin("bool") { let node = ast::ExprName { id: "bool".into(), ctx: ExprContext::Load, diff --git a/crates/ruff/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs b/crates/ruff/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs index ac19d8f374..7a6614f96c 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs @@ -42,8 +42,8 @@ impl Violation for OpenFileWithContextHandler { /// Return `true` if the current expression is nested in an `await /// exit_stack.enter_async_context` call. -fn match_async_exit_stack(model: &SemanticModel) -> bool { - let Some(expr) = model.expr_grandparent() else { +fn match_async_exit_stack(semantic: &SemanticModel) -> bool { + let Some(expr) = semantic.expr_grandparent() else { return false; }; let Expr::Await(ast::ExprAwait { value, range: _ }) = expr else { @@ -58,11 +58,11 @@ fn match_async_exit_stack(model: &SemanticModel) -> bool { if attr != "enter_async_context" { return false; } - for parent in model.parents() { + for parent in semantic.parents() { if let Stmt::With(ast::StmtWith { items, .. }) = parent { for item in items { if let Expr::Call(ast::ExprCall { func, .. }) = &item.context_expr { - if model.resolve_call_path(func).map_or(false, |call_path| { + if semantic.resolve_call_path(func).map_or(false, |call_path| { call_path.as_slice() == ["contextlib", "AsyncExitStack"] }) { return true; @@ -76,8 +76,8 @@ fn match_async_exit_stack(model: &SemanticModel) -> bool { /// Return `true` if the current expression is nested in an /// `exit_stack.enter_context` call. -fn match_exit_stack(model: &SemanticModel) -> bool { - let Some(expr) = model.expr_parent() else { +fn match_exit_stack(semantic: &SemanticModel) -> bool { + let Some(expr) = semantic.expr_parent() else { return false; }; let Expr::Call(ast::ExprCall { func, .. }) = expr else { @@ -89,11 +89,11 @@ fn match_exit_stack(model: &SemanticModel) -> bool { if attr != "enter_context" { return false; } - for parent in model.parents() { + for parent in semantic.parents() { if let Stmt::With(ast::StmtWith { items, .. }) = parent { for item in items { if let Expr::Call(ast::ExprCall { func, .. }) = &item.context_expr { - if model.resolve_call_path(func).map_or(false, |call_path| { + if semantic.resolve_call_path(func).map_or(false, |call_path| { call_path.as_slice() == ["contextlib", "ExitStack"] }) { return true; @@ -108,23 +108,23 @@ fn match_exit_stack(model: &SemanticModel) -> bool { /// SIM115 pub(crate) fn open_file_with_context_handler(checker: &mut Checker, func: &Expr) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| call_path.as_slice() == ["", "open"]) { - if checker.semantic_model().is_builtin("open") { + if checker.semantic().is_builtin("open") { // Ex) `with open("foo.txt") as f: ...` - if matches!(checker.semantic_model().stmt(), Stmt::With(_)) { + if matches!(checker.semantic().stmt(), Stmt::With(_)) { return; } // Ex) `with contextlib.ExitStack() as exit_stack: ...` - if match_exit_stack(checker.semantic_model()) { + if match_exit_stack(checker.semantic()) { return; } // Ex) `with contextlib.AsyncExitStack() as exit_stack: ...` - if match_async_exit_stack(checker.semantic_model()) { + if match_async_exit_stack(checker.semantic()) { return; } diff --git a/crates/ruff/src/rules/flake8_simplify/rules/reimplemented_builtin.rs b/crates/ruff/src/rules/flake8_simplify/rules/reimplemented_builtin.rs index 53e3b59718..0641da8aef 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/reimplemented_builtin.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/reimplemented_builtin.rs @@ -262,9 +262,7 @@ pub(crate) fn convert_for_loop_to_any_all( }, TextRange::new(stmt.start(), loop_info.terminal), ); - if checker.patch(diagnostic.kind.rule()) - && checker.semantic_model().is_builtin("any") - { + if checker.patch(diagnostic.kind.rule()) && checker.semantic().is_builtin("any") { #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::replacement( contents, @@ -355,9 +353,7 @@ pub(crate) fn convert_for_loop_to_any_all( }, TextRange::new(stmt.start(), loop_info.terminal), ); - if checker.patch(diagnostic.kind.rule()) - && checker.semantic_model().is_builtin("all") - { + if checker.patch(diagnostic.kind.rule()) && checker.semantic().is_builtin("all") { #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::replacement( contents, diff --git a/crates/ruff/src/rules/flake8_simplify/rules/suppressible_exception.rs b/crates/ruff/src/rules/flake8_simplify/rules/suppressible_exception.rs index 869a1298c7..6f738754a7 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/suppressible_exception.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/suppressible_exception.rs @@ -122,7 +122,7 @@ pub(crate) fn suppressible_exception( let (import_edit, binding) = checker.importer.get_or_import_symbol( &ImportRequest::import("contextlib", "suppress"), stmt.start(), - checker.semantic_model(), + checker.semantic(), )?; let replace_try = Edit::range_replacement( format!("with {binding}({exception})"), diff --git a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_namedtuple_subclass.rs b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_namedtuple_subclass.rs index 2928f8b9af..c43f9f35fd 100644 --- a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_namedtuple_subclass.rs +++ b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_namedtuple_subclass.rs @@ -68,7 +68,7 @@ pub(crate) fn no_slots_in_namedtuple_subclass( return false; }; checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { matches!(call_path.as_slice(), ["collections", "namedtuple"]) diff --git a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_str_subclass.rs b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_str_subclass.rs index 76580bb931..8c0ae80b90 100644 --- a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_str_subclass.rs +++ b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_str_subclass.rs @@ -52,7 +52,7 @@ impl Violation for NoSlotsInStrSubclass { pub(crate) fn no_slots_in_str_subclass(checker: &mut Checker, stmt: &Stmt, class: &StmtClassDef) { if class.bases.iter().any(|base| { checker - .semantic_model() + .semantic() .resolve_call_path(base) .map_or(false, |call_path| { matches!(call_path.as_slice(), ["" | "builtins", "str"]) diff --git a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_tuple_subclass.rs b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_tuple_subclass.rs index 3dea2b0057..a4705c2e25 100644 --- a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_tuple_subclass.rs +++ b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_tuple_subclass.rs @@ -52,12 +52,12 @@ impl Violation for NoSlotsInTupleSubclass { pub(crate) fn no_slots_in_tuple_subclass(checker: &mut Checker, stmt: &Stmt, class: &StmtClassDef) { if class.bases.iter().any(|base| { checker - .semantic_model() + .semantic() .resolve_call_path(map_subscript(base)) .map_or(false, |call_path| { matches!(call_path.as_slice(), ["" | "builtins", "tuple"]) || checker - .semantic_model() + .semantic() .match_typing_call_path(&call_path, "Tuple") }) }) { diff --git a/crates/ruff/src/rules/flake8_tidy_imports/rules/banned_api.rs b/crates/ruff/src/rules/flake8_tidy_imports/rules/banned_api.rs index 668f764354..6730ce8700 100644 --- a/crates/ruff/src/rules/flake8_tidy_imports/rules/banned_api.rs +++ b/crates/ruff/src/rules/flake8_tidy_imports/rules/banned_api.rs @@ -86,7 +86,7 @@ pub(crate) fn banned_attribute_access(checker: &mut Checker, expr: &Expr) { let banned_api = &checker.settings.flake8_tidy_imports.banned_api; if let Some((banned_path, ban)) = checker - .semantic_model() + .semantic() .resolve_call_path(expr) .and_then(|call_path| { banned_api diff --git a/crates/ruff/src/rules/flake8_type_checking/helpers.rs b/crates/ruff/src/rules/flake8_type_checking/helpers.rs index 085f89d029..d9c3ef6075 100644 --- a/crates/ruff/src/rules/flake8_type_checking/helpers.rs +++ b/crates/ruff/src/rules/flake8_type_checking/helpers.rs @@ -4,7 +4,7 @@ use ruff_python_ast::call_path::from_qualified_name; use ruff_python_ast::helpers::map_callable; use ruff_python_semantic::{Binding, BindingKind, ScopeKind, SemanticModel}; -pub(crate) fn is_valid_runtime_import(semantic_model: &SemanticModel, binding: &Binding) -> bool { +pub(crate) fn is_valid_runtime_import(binding: &Binding, semantic: &SemanticModel) -> bool { if matches!( binding.kind, BindingKind::Importation(..) @@ -12,39 +12,36 @@ pub(crate) fn is_valid_runtime_import(semantic_model: &SemanticModel, binding: & | BindingKind::SubmoduleImportation(..) ) { binding.context.is_runtime() - && binding.references().any(|reference_id| { - semantic_model - .reference(reference_id) - .context() - .is_runtime() - }) + && binding + .references() + .any(|reference_id| semantic.reference(reference_id).context().is_runtime()) } else { false } } pub(crate) fn runtime_evaluated( - semantic_model: &SemanticModel, base_classes: &[String], decorators: &[String], + semantic: &SemanticModel, ) -> bool { if !base_classes.is_empty() { - if runtime_evaluated_base_class(semantic_model, base_classes) { + if runtime_evaluated_base_class(base_classes, semantic) { return true; } } if !decorators.is_empty() { - if runtime_evaluated_decorators(semantic_model, decorators) { + if runtime_evaluated_decorators(decorators, semantic) { return true; } } false } -fn runtime_evaluated_base_class(semantic_model: &SemanticModel, base_classes: &[String]) -> bool { - if let ScopeKind::Class(ast::StmtClassDef { bases, .. }) = &semantic_model.scope().kind { +fn runtime_evaluated_base_class(base_classes: &[String], semantic: &SemanticModel) -> bool { + if let ScopeKind::Class(ast::StmtClassDef { bases, .. }) = &semantic.scope().kind { for base in bases.iter() { - if let Some(call_path) = semantic_model.resolve_call_path(base) { + if let Some(call_path) = semantic.resolve_call_path(base) { if base_classes .iter() .any(|base_class| from_qualified_name(base_class) == call_path) @@ -57,12 +54,10 @@ fn runtime_evaluated_base_class(semantic_model: &SemanticModel, base_classes: &[ false } -fn runtime_evaluated_decorators(semantic_model: &SemanticModel, decorators: &[String]) -> bool { - if let ScopeKind::Class(ast::StmtClassDef { decorator_list, .. }) = &semantic_model.scope().kind - { +fn runtime_evaluated_decorators(decorators: &[String], semantic: &SemanticModel) -> bool { + if let ScopeKind::Class(ast::StmtClassDef { decorator_list, .. }) = &semantic.scope().kind { for decorator in decorator_list.iter() { - if let Some(call_path) = - semantic_model.resolve_call_path(map_callable(&decorator.expression)) + if let Some(call_path) = semantic.resolve_call_path(map_callable(&decorator.expression)) { if decorators .iter() diff --git a/crates/ruff/src/rules/flake8_type_checking/rules/empty_type_checking_block.rs b/crates/ruff/src/rules/flake8_type_checking/rules/empty_type_checking_block.rs index 2e90e50284..88ed829041 100644 --- a/crates/ruff/src/rules/flake8_type_checking/rules/empty_type_checking_block.rs +++ b/crates/ruff/src/rules/flake8_type_checking/rules/empty_type_checking_block.rs @@ -60,8 +60,8 @@ pub(crate) fn empty_type_checking_block(checker: &mut Checker, stmt: &ast::StmtI let mut diagnostic = Diagnostic::new(EmptyTypeCheckingBlock, stmt.range()); if checker.patch(diagnostic.kind.rule()) { // Delete the entire type-checking block. - let stmt = checker.semantic_model().stmt(); - let parent = checker.semantic_model().stmt_parent(); + let stmt = checker.semantic().stmt(); + let parent = checker.semantic().stmt_parent(); let edit = autofix::edits::delete_stmt( stmt, parent, diff --git a/crates/ruff/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs b/crates/ruff/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs index 659e59ac2c..b9ffa0c236 100644 --- a/crates/ruff/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs +++ b/crates/ruff/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs @@ -73,7 +73,7 @@ pub(crate) fn runtime_import_in_type_checking_block( let mut ignores_by_statement: FxHashMap> = FxHashMap::default(); for binding_id in scope.binding_ids() { - let binding = checker.semantic_model().binding(binding_id); + let binding = checker.semantic().binding(binding_id); let Some(qualified_name) = binding.qualified_name() else { continue; @@ -86,7 +86,7 @@ pub(crate) fn runtime_import_in_type_checking_block( if binding.context.is_typing() && binding.references().any(|reference_id| { checker - .semantic_model() + .semantic() .reference(reference_id) .context() .is_runtime() @@ -99,8 +99,8 @@ pub(crate) fn runtime_import_in_type_checking_block( let import = Import { qualified_name, reference_id, - trimmed_range: binding.trimmed_range(checker.semantic_model(), checker.locator), - parent_range: binding.parent_range(checker.semantic_model()), + trimmed_range: binding.trimmed_range(checker.semantic(), checker.locator), + parent_range: binding.parent_range(checker.semantic()), }; if checker.rule_is_ignored( @@ -188,8 +188,8 @@ struct Import<'a> { /// Generate a [`Fix`] to remove runtime imports from a type-checking block. fn fix_imports(checker: &Checker, stmt_id: NodeId, imports: &[Import]) -> Result { - let stmt = checker.semantic_model().stmts[stmt_id]; - let parent = checker.semantic_model().stmts.parent(stmt); + let stmt = checker.semantic().stmts[stmt_id]; + let parent = checker.semantic().stmts.parent(stmt); let qualified_names: Vec<&str> = imports .iter() .map(|Import { qualified_name, .. }| *qualified_name) @@ -199,11 +199,7 @@ fn fix_imports(checker: &Checker, stmt_id: NodeId, imports: &[Import]) -> Result let at = imports .iter() .map(|Import { reference_id, .. }| { - checker - .semantic_model() - .reference(*reference_id) - .range() - .start() + checker.semantic().reference(*reference_id).range().start() }) .min() .expect("Expected at least one import"); diff --git a/crates/ruff/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs b/crates/ruff/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs index 97afe9c500..722a6bfbce 100644 --- a/crates/ruff/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs +++ b/crates/ruff/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs @@ -194,7 +194,7 @@ pub(crate) fn typing_only_runtime_import( FxHashMap::default(); for binding_id in scope.binding_ids() { - let binding = checker.semantic_model().binding(binding_id); + let binding = checker.semantic().binding(binding_id); // If we're in un-strict mode, don't flag typing-only imports that are // implicitly loaded by way of a valid runtime import. @@ -230,7 +230,7 @@ pub(crate) fn typing_only_runtime_import( if binding.context.is_runtime() && binding.references().all(|reference_id| { checker - .semantic_model() + .semantic() .reference(reference_id) .context() .is_typing() @@ -278,8 +278,8 @@ pub(crate) fn typing_only_runtime_import( let import = Import { qualified_name, reference_id, - trimmed_range: binding.trimmed_range(checker.semantic_model(), checker.locator), - parent_range: binding.parent_range(checker.semantic_model()), + trimmed_range: binding.trimmed_range(checker.semantic(), checker.locator), + parent_range: binding.parent_range(checker.semantic()), }; if checker.rule_is_ignored(rule_for(import_type), import.trimmed_range.start()) @@ -413,8 +413,8 @@ fn is_exempt(name: &str, exempt_modules: &[&str]) -> bool { /// Generate a [`Fix`] to remove typing-only imports from a runtime context. fn fix_imports(checker: &Checker, stmt_id: NodeId, imports: &[Import]) -> Result { - let stmt = checker.semantic_model().stmts[stmt_id]; - let parent = checker.semantic_model().stmts.parent(stmt); + let stmt = checker.semantic().stmts[stmt_id]; + let parent = checker.semantic().stmts.parent(stmt); let qualified_names: Vec<&str> = imports .iter() .map(|Import { qualified_name, .. }| *qualified_name) @@ -424,11 +424,7 @@ fn fix_imports(checker: &Checker, stmt_id: NodeId, imports: &[Import]) -> Result let at = imports .iter() .map(|Import { reference_id, .. }| { - checker - .semantic_model() - .reference(*reference_id) - .range() - .start() + checker.semantic().reference(*reference_id).range().start() }) .min() .expect("Expected at least one import"); @@ -450,7 +446,7 @@ fn fix_imports(checker: &Checker, stmt_id: NodeId, imports: &[Import]) -> Result qualified_names, }, at, - checker.semantic_model(), + checker.semantic(), )?; Ok( diff --git a/crates/ruff/src/rules/flake8_unused_arguments/rules/unused_arguments.rs b/crates/ruff/src/rules/flake8_unused_arguments/rules/unused_arguments.rs index eb1c845bd8..76c2d589f8 100644 --- a/crates/ruff/src/rules/flake8_unused_arguments/rules/unused_arguments.rs +++ b/crates/ruff/src/rules/flake8_unused_arguments/rules/unused_arguments.rs @@ -218,7 +218,7 @@ fn function( argumentable: Argumentable, args: &Arguments, values: &Scope, - model: &SemanticModel, + semantic: &SemanticModel, dummy_variable_rgx: &Regex, ignore_variadic_names: bool, ) -> Vec { @@ -237,7 +237,7 @@ fn function( .flatten() .skip(usize::from(ignore_variadic_names)), ); - call(argumentable, args, values, model, dummy_variable_rgx) + call(argumentable, args, values, semantic, dummy_variable_rgx) } /// Check a method for unused arguments. @@ -245,7 +245,7 @@ fn method( argumentable: Argumentable, args: &Arguments, values: &Scope, - model: &SemanticModel, + semantic: &SemanticModel, dummy_variable_rgx: &Regex, ignore_variadic_names: bool, ) -> Vec { @@ -265,21 +265,21 @@ fn method( .flatten() .skip(usize::from(ignore_variadic_names)), ); - call(argumentable, args, values, model, dummy_variable_rgx) + call(argumentable, args, values, semantic, dummy_variable_rgx) } fn call<'a>( argumentable: Argumentable, args: impl Iterator, values: &Scope, - model: &SemanticModel, + semantic: &SemanticModel, dummy_variable_rgx: &Regex, ) -> Vec { let mut diagnostics: Vec = vec![]; for arg in args { if let Some(binding) = values .get(arg.arg.as_str()) - .map(|binding_id| model.binding(binding_id)) + .map(|binding_id| semantic.binding(binding_id)) { if binding.kind.is_argument() && !binding.is_used() @@ -317,22 +317,22 @@ pub(crate) fn unused_arguments( .. }) => { match function_type::classify( - checker.semantic_model(), - parent, name, decorator_list, + parent, + checker.semantic(), &checker.settings.pep8_naming.classmethod_decorators, &checker.settings.pep8_naming.staticmethod_decorators, ) { function_type::FunctionType::Function => { if checker.enabled(Argumentable::Function.rule_code()) - && !visibility::is_overload(checker.semantic_model(), decorator_list) + && !visibility::is_overload(decorator_list, checker.semantic()) { function( Argumentable::Function, args, scope, - checker.semantic_model(), + checker.semantic(), &checker.settings.dummy_variable_rgx, checker .settings @@ -350,15 +350,15 @@ pub(crate) fn unused_arguments( || visibility::is_init(name) || visibility::is_new(name) || visibility::is_call(name)) - && !visibility::is_abstract(checker.semantic_model(), decorator_list) - && !visibility::is_override(checker.semantic_model(), decorator_list) - && !visibility::is_overload(checker.semantic_model(), decorator_list) + && !visibility::is_abstract(decorator_list, checker.semantic()) + && !visibility::is_override(decorator_list, checker.semantic()) + && !visibility::is_overload(decorator_list, checker.semantic()) { method( Argumentable::Method, args, scope, - checker.semantic_model(), + checker.semantic(), &checker.settings.dummy_variable_rgx, checker .settings @@ -376,15 +376,15 @@ pub(crate) fn unused_arguments( || visibility::is_init(name) || visibility::is_new(name) || visibility::is_call(name)) - && !visibility::is_abstract(checker.semantic_model(), decorator_list) - && !visibility::is_override(checker.semantic_model(), decorator_list) - && !visibility::is_overload(checker.semantic_model(), decorator_list) + && !visibility::is_abstract(decorator_list, checker.semantic()) + && !visibility::is_override(decorator_list, checker.semantic()) + && !visibility::is_overload(decorator_list, checker.semantic()) { method( Argumentable::ClassMethod, args, scope, - checker.semantic_model(), + checker.semantic(), &checker.settings.dummy_variable_rgx, checker .settings @@ -402,15 +402,15 @@ pub(crate) fn unused_arguments( || visibility::is_init(name) || visibility::is_new(name) || visibility::is_call(name)) - && !visibility::is_abstract(checker.semantic_model(), decorator_list) - && !visibility::is_override(checker.semantic_model(), decorator_list) - && !visibility::is_overload(checker.semantic_model(), decorator_list) + && !visibility::is_abstract(decorator_list, checker.semantic()) + && !visibility::is_override(decorator_list, checker.semantic()) + && !visibility::is_overload(decorator_list, checker.semantic()) { function( Argumentable::StaticMethod, args, scope, - checker.semantic_model(), + checker.semantic(), &checker.settings.dummy_variable_rgx, checker .settings @@ -429,7 +429,7 @@ pub(crate) fn unused_arguments( Argumentable::Lambda, args, scope, - checker.semantic_model(), + checker.semantic(), &checker.settings.dummy_variable_rgx, checker .settings diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs index 5862bd427c..98f25b193d 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs @@ -15,7 +15,7 @@ use crate::settings::types::PythonVersion; pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { if let Some(diagnostic_kind) = checker - .semantic_model() + .semantic() .resolve_call_path(expr) .and_then(|call_path| match call_path.as_slice() { ["os", "path", "abspath"] => Some(OsPathAbspath.into()), diff --git a/crates/ruff/src/rules/numpy/rules/deprecated_type_alias.rs b/crates/ruff/src/rules/numpy/rules/deprecated_type_alias.rs index 834400e5eb..a4bc1a07bd 100644 --- a/crates/ruff/src/rules/numpy/rules/deprecated_type_alias.rs +++ b/crates/ruff/src/rules/numpy/rules/deprecated_type_alias.rs @@ -48,25 +48,24 @@ impl AlwaysAutofixableViolation for NumpyDeprecatedTypeAlias { /// NPY001 pub(crate) fn deprecated_type_alias(checker: &mut Checker, expr: &Expr) { - if let Some(type_name) = - checker - .semantic_model() - .resolve_call_path(expr) - .and_then(|call_path| { - if call_path.as_slice() == ["numpy", "bool"] - || call_path.as_slice() == ["numpy", "int"] - || call_path.as_slice() == ["numpy", "float"] - || call_path.as_slice() == ["numpy", "complex"] - || call_path.as_slice() == ["numpy", "object"] - || call_path.as_slice() == ["numpy", "str"] - || call_path.as_slice() == ["numpy", "long"] - || call_path.as_slice() == ["numpy", "unicode"] - { - Some(call_path[1]) - } else { - None - } - }) + if let Some(type_name) = checker + .semantic() + .resolve_call_path(expr) + .and_then(|call_path| { + if call_path.as_slice() == ["numpy", "bool"] + || call_path.as_slice() == ["numpy", "int"] + || call_path.as_slice() == ["numpy", "float"] + || call_path.as_slice() == ["numpy", "complex"] + || call_path.as_slice() == ["numpy", "object"] + || call_path.as_slice() == ["numpy", "str"] + || call_path.as_slice() == ["numpy", "long"] + || call_path.as_slice() == ["numpy", "unicode"] + { + Some(call_path[1]) + } else { + None + } + }) { let mut diagnostic = Diagnostic::new( NumpyDeprecatedTypeAlias { diff --git a/crates/ruff/src/rules/numpy/rules/numpy_legacy_random.rs b/crates/ruff/src/rules/numpy/rules/numpy_legacy_random.rs index 0e52c39176..736685e813 100644 --- a/crates/ruff/src/rules/numpy/rules/numpy_legacy_random.rs +++ b/crates/ruff/src/rules/numpy/rules/numpy_legacy_random.rs @@ -58,13 +58,12 @@ impl Violation for NumpyLegacyRandom { /// NPY002 pub(crate) fn numpy_legacy_random(checker: &mut Checker, expr: &Expr) { - if let Some(method_name) = - checker - .semantic_model() - .resolve_call_path(expr) - .and_then(|call_path| { - // seeding state - if call_path.as_slice() == ["numpy", "random", "seed"] + if let Some(method_name) = checker + .semantic() + .resolve_call_path(expr) + .and_then(|call_path| { + // seeding state + if call_path.as_slice() == ["numpy", "random", "seed"] || call_path.as_slice() == ["numpy", "random", "get_state"] || call_path.as_slice() == ["numpy", "random", "set_state"] // simple random data @@ -115,12 +114,12 @@ pub(crate) fn numpy_legacy_random(checker: &mut Checker, expr: &Expr) { || call_path.as_slice() == ["numpy", "random", "wald"] || call_path.as_slice() == ["numpy", "random", "weibull"] || call_path.as_slice() == ["numpy", "random", "zipf"] - { - Some(call_path[2]) - } else { - None - } - }) + { + Some(call_path[2]) + } else { + None + } + }) { checker.diagnostics.push(Diagnostic::new( NumpyLegacyRandom { diff --git a/crates/ruff/src/rules/pandas_vet/helpers.rs b/crates/ruff/src/rules/pandas_vet/helpers.rs index 45240028d9..ec4400a978 100644 --- a/crates/ruff/src/rules/pandas_vet/helpers.rs +++ b/crates/ruff/src/rules/pandas_vet/helpers.rs @@ -15,7 +15,7 @@ pub(super) enum Resolution { } /// Test an [`Expr`] for relevance to Pandas-related operations. -pub(super) fn test_expression(expr: &Expr, model: &SemanticModel) -> Resolution { +pub(super) fn test_expression(expr: &Expr, semantic: &SemanticModel) -> Resolution { match expr { Expr::Constant(_) | Expr::Tuple(_) @@ -27,7 +27,7 @@ pub(super) fn test_expression(expr: &Expr, model: &SemanticModel) -> Resolution | Expr::DictComp(_) | Expr::GeneratorExp(_) => Resolution::IrrelevantExpression, Expr::Name(ast::ExprName { id, .. }) => { - model + semantic .find_binding(id) .map_or(Resolution::IrrelevantBinding, |binding| { match binding.kind { diff --git a/crates/ruff/src/rules/pandas_vet/rules/attr.rs b/crates/ruff/src/rules/pandas_vet/rules/attr.rs index ccdb5616b1..fd0de36a96 100644 --- a/crates/ruff/src/rules/pandas_vet/rules/attr.rs +++ b/crates/ruff/src/rules/pandas_vet/rules/attr.rs @@ -26,7 +26,7 @@ pub(crate) fn attr(checker: &mut Checker, attr: &str, value: &Expr, attr_expr: & }; // Avoid flagging on function calls (e.g., `df.values()`). - if let Some(parent) = checker.semantic_model().expr_parent() { + if let Some(parent) = checker.semantic().expr_parent() { if matches!(parent, Expr::Call(_)) { return; } @@ -35,7 +35,7 @@ pub(crate) fn attr(checker: &mut Checker, attr: &str, value: &Expr, attr_expr: & // Avoid flagging on non-DataFrames (e.g., `{"a": 1}.values`), and on irrelevant bindings // (like imports). if !matches!( - test_expression(value, checker.semantic_model()), + test_expression(value, checker.semantic()), Resolution::RelevantLocal ) { return; diff --git a/crates/ruff/src/rules/pandas_vet/rules/call.rs b/crates/ruff/src/rules/pandas_vet/rules/call.rs index ecea41b6f8..be7dfadf24 100644 --- a/crates/ruff/src/rules/pandas_vet/rules/call.rs +++ b/crates/ruff/src/rules/pandas_vet/rules/call.rs @@ -80,7 +80,7 @@ pub(crate) fn call(checker: &mut Checker, func: &Expr) { // Ignore irrelevant bindings (like imports). if !matches!( - test_expression(value, checker.semantic_model()), + test_expression(value, checker.semantic()), Resolution::RelevantLocal | Resolution::PandasModule ) { return; diff --git a/crates/ruff/src/rules/pandas_vet/rules/inplace_argument.rs b/crates/ruff/src/rules/pandas_vet/rules/inplace_argument.rs index 7b87ccc3b9..39b2cca800 100644 --- a/crates/ruff/src/rules/pandas_vet/rules/inplace_argument.rs +++ b/crates/ruff/src/rules/pandas_vet/rules/inplace_argument.rs @@ -60,12 +60,12 @@ pub(crate) fn inplace_argument( let mut is_checkable = false; let mut is_pandas = false; - if let Some(call_path) = checker.semantic_model().resolve_call_path(func) { + if let Some(call_path) = checker.semantic().resolve_call_path(func) { is_checkable = true; let module = call_path[0]; is_pandas = checker - .semantic_model() + .semantic() .find_binding(module) .map_or(false, |binding| { matches!( @@ -103,9 +103,9 @@ pub(crate) fn inplace_argument( // but we don't currently restore expression stacks when parsing deferred nodes, // and so the parent is lost. if !seen_star - && checker.semantic_model().stmt().is_expr_stmt() - && checker.semantic_model().expr_parent().is_none() - && !checker.semantic_model().scope().kind.is_lambda() + && checker.semantic().stmt().is_expr_stmt() + && checker.semantic().expr_parent().is_none() + && !checker.semantic().scope().kind.is_lambda() { if let Some(fix) = convert_inplace_argument_to_assignment( checker.locator, diff --git a/crates/ruff/src/rules/pandas_vet/rules/subscript.rs b/crates/ruff/src/rules/pandas_vet/rules/subscript.rs index 96430e0151..6bcbb8298b 100644 --- a/crates/ruff/src/rules/pandas_vet/rules/subscript.rs +++ b/crates/ruff/src/rules/pandas_vet/rules/subscript.rs @@ -54,7 +54,7 @@ pub(crate) fn subscript(checker: &mut Checker, value: &Expr, expr: &Expr) { // Avoid flagging on non-DataFrames (e.g., `{"a": 1}.at[0]`), and on irrelevant bindings // (like imports). if !matches!( - test_expression(value, checker.semantic_model()), + test_expression(value, checker.semantic()), Resolution::RelevantLocal ) { return; diff --git a/crates/ruff/src/rules/pep8_naming/helpers.rs b/crates/ruff/src/rules/pep8_naming/helpers.rs index 05de2560a3..93792ad0ab 100644 --- a/crates/ruff/src/rules/pep8_naming/helpers.rs +++ b/crates/ruff/src/rules/pep8_naming/helpers.rs @@ -22,14 +22,14 @@ pub(super) fn is_acronym(name: &str, asname: &str) -> bool { name.chars().filter(|c| c.is_uppercase()).join("") == asname } -pub(super) fn is_named_tuple_assignment(model: &SemanticModel, stmt: &Stmt) -> bool { +pub(super) fn is_named_tuple_assignment(stmt: &Stmt, semantic: &SemanticModel) -> bool { let Stmt::Assign(ast::StmtAssign { value, .. }) = stmt else { return false; }; let Expr::Call(ast::ExprCall {func, ..}) = value.as_ref() else { return false; }; - model.resolve_call_path(func).map_or(false, |call_path| { + semantic.resolve_call_path(func).map_or(false, |call_path| { matches!( call_path.as_slice(), ["collections", "namedtuple"] | ["typing", "NamedTuple"] @@ -37,35 +37,35 @@ pub(super) fn is_named_tuple_assignment(model: &SemanticModel, stmt: &Stmt) -> b }) } -pub(super) fn is_typed_dict_assignment(model: &SemanticModel, stmt: &Stmt) -> bool { +pub(super) fn is_typed_dict_assignment(stmt: &Stmt, semantic: &SemanticModel) -> bool { let Stmt::Assign(ast::StmtAssign { value, .. }) = stmt else { return false; }; let Expr::Call(ast::ExprCall {func, ..}) = value.as_ref() else { return false; }; - model.resolve_call_path(func).map_or(false, |call_path| { + semantic.resolve_call_path(func).map_or(false, |call_path| { call_path.as_slice() == ["typing", "TypedDict"] }) } -pub(super) fn is_type_var_assignment(model: &SemanticModel, stmt: &Stmt) -> bool { +pub(super) fn is_type_var_assignment(stmt: &Stmt, semantic: &SemanticModel) -> bool { let Stmt::Assign(ast::StmtAssign { value, .. }) = stmt else { return false; }; let Expr::Call(ast::ExprCall {func, ..}) = value.as_ref() else { return false; }; - model.resolve_call_path(func).map_or(false, |call_path| { + semantic.resolve_call_path(func).map_or(false, |call_path| { call_path.as_slice() == ["typing", "TypeVar"] || call_path.as_slice() == ["typing", "NewType"] }) } -pub(super) fn is_typed_dict_class(model: &SemanticModel, bases: &[Expr]) -> bool { +pub(super) fn is_typed_dict_class(bases: &[Expr], semantic: &SemanticModel) -> bool { bases .iter() - .any(|base| model.match_typing_expr(base, "TypedDict")) + .any(|base| semantic.match_typing_expr(base, "TypedDict")) } #[cfg(test)] diff --git a/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs b/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs index 66e9a597cb..e3fa06517a 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs @@ -64,10 +64,10 @@ pub(crate) fn invalid_first_argument_name_for_class_method( ) -> Option { if !matches!( function_type::classify( - checker.semantic_model(), - scope, name, decorator_list, + scope, + checker.semantic(), &checker.settings.pep8_naming.classmethod_decorators, &checker.settings.pep8_naming.staticmethod_decorators, ), diff --git a/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs b/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs index bb1fb0a520..95a1194e85 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs @@ -61,10 +61,10 @@ pub(crate) fn invalid_first_argument_name_for_method( ) -> Option { if !matches!( function_type::classify( - checker.semantic_model(), - scope, name, decorator_list, + scope, + checker.semantic(), &checker.settings.pep8_naming.classmethod_decorators, &checker.settings.pep8_naming.staticmethod_decorators, ), diff --git a/crates/ruff/src/rules/pep8_naming/rules/invalid_function_name.rs b/crates/ruff/src/rules/pep8_naming/rules/invalid_function_name.rs index 1f8a41887d..08be500680 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/invalid_function_name.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/invalid_function_name.rs @@ -55,7 +55,7 @@ pub(crate) fn invalid_function_name( name: &str, decorator_list: &[Decorator], ignore_names: &[IdentifierPattern], - model: &SemanticModel, + semantic: &SemanticModel, locator: &Locator, ) -> Option { // Ignore any explicitly-ignored function names. @@ -73,7 +73,7 @@ pub(crate) fn invalid_function_name( // Ignore any functions that are explicitly `@override`. These are defined elsewhere, // so if they're first-party, we'll flag them at the definition site. - if visibility::is_override(model, decorator_list) { + if visibility::is_override(decorator_list, semantic) { return None; } diff --git a/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs b/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs index 4fd006a82e..c43b384524 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs @@ -67,8 +67,8 @@ pub(crate) fn mixed_case_variable_in_class_scope( return; } if helpers::is_mixed_case(name) - && !helpers::is_named_tuple_assignment(checker.semantic_model(), stmt) - && !helpers::is_typed_dict_class(checker.semantic_model(), bases) + && !helpers::is_named_tuple_assignment(stmt, checker.semantic()) + && !helpers::is_typed_dict_class(bases, checker.semantic()) { checker.diagnostics.push(Diagnostic::new( MixedCaseVariableInClassScope { diff --git a/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_global_scope.rs b/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_global_scope.rs index 6ea71b349d..158f03eaea 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_global_scope.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_global_scope.rs @@ -75,8 +75,7 @@ pub(crate) fn mixed_case_variable_in_global_scope( { return; } - if helpers::is_mixed_case(name) - && !helpers::is_named_tuple_assignment(checker.semantic_model(), stmt) + if helpers::is_mixed_case(name) && !helpers::is_named_tuple_assignment(stmt, checker.semantic()) { checker.diagnostics.push(Diagnostic::new( MixedCaseVariableInGlobalScope { diff --git a/crates/ruff/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs b/crates/ruff/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs index f395e6fefd..147531a46b 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs @@ -66,9 +66,9 @@ pub(crate) fn non_lowercase_variable_in_function( } if name.to_lowercase() != name - && !helpers::is_named_tuple_assignment(checker.semantic_model(), stmt) - && !helpers::is_typed_dict_assignment(checker.semantic_model(), stmt) - && !helpers::is_type_var_assignment(checker.semantic_model(), stmt) + && !helpers::is_named_tuple_assignment(stmt, checker.semantic()) + && !helpers::is_typed_dict_assignment(stmt, checker.semantic()) + && !helpers::is_type_var_assignment(stmt, checker.semantic()) { checker.diagnostics.push(Diagnostic::new( NonLowercaseVariableInFunction { diff --git a/crates/ruff/src/rules/pycodestyle/rules/imports.rs b/crates/ruff/src/rules/pycodestyle/rules/imports.rs index b5b724329e..61e163354c 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/imports.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/imports.rs @@ -88,8 +88,7 @@ pub(crate) fn module_import_not_at_top_of_file( stmt: &Stmt, locator: &Locator, ) { - if checker.semantic_model().seen_import_boundary() && locator.is_at_start_of_line(stmt.start()) - { + if checker.semantic().seen_import_boundary() && locator.is_at_start_of_line(stmt.start()) { checker .diagnostics .push(Diagnostic::new(ModuleImportNotAtTopOfFile, stmt.range())); diff --git a/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs b/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs index 3982031e3e..29767501ed 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs @@ -78,7 +78,7 @@ pub(crate) fn lambda_assignment( // rewritten function definition to be equivalent. // See https://github.com/astral-sh/ruff/issues/3046 if checker.patch(diagnostic.kind.rule()) - && !checker.semantic_model().scope().kind.is_class() + && !checker.semantic().scope().kind.is_class() && !has_leading_content(stmt, checker.locator) && !has_trailing_content(stmt, checker.locator) { @@ -86,11 +86,11 @@ pub(crate) fn lambda_assignment( let indentation = leading_indentation(first_line); let mut indented = String::new(); for (idx, line) in function( - checker.semantic_model(), id, args, body, annotation, + checker.semantic(), checker.generator(), ) .universal_newlines() @@ -120,7 +120,7 @@ pub(crate) fn lambda_assignment( /// The `Callable` import can be from either `collections.abc` or `typing`. /// If an ellipsis is used for the argument types, an empty list is returned. /// The returned values are cloned, so they can be used as-is. -fn extract_types(model: &SemanticModel, annotation: &Expr) -> Option<(Vec, Expr)> { +fn extract_types(annotation: &Expr, semantic: &SemanticModel) -> Option<(Vec, Expr)> { let Expr::Subscript(ast::ExprSubscript { value, slice, .. }) = &annotation else { return None; }; @@ -131,10 +131,13 @@ fn extract_types(model: &SemanticModel, annotation: &Expr) -> Option<(Vec, return None; } - if !model.resolve_call_path(value).map_or(false, |call_path| { - call_path.as_slice() == ["collections", "abc", "Callable"] - || model.match_typing_call_path(&call_path, "Callable") - }) { + if !semantic + .resolve_call_path(value) + .map_or(false, |call_path| { + call_path.as_slice() == ["collections", "abc", "Callable"] + || semantic.match_typing_call_path(&call_path, "Callable") + }) + { return None; } @@ -156,11 +159,11 @@ fn extract_types(model: &SemanticModel, annotation: &Expr) -> Option<(Vec, } fn function( - model: &SemanticModel, name: &str, args: &Arguments, body: &Expr, annotation: Option<&Expr>, + semantic: &SemanticModel, generator: Generator, ) -> String { let body = Stmt::Return(ast::StmtReturn { @@ -168,7 +171,7 @@ fn function( range: TextRange::default(), }); if let Some(annotation) = annotation { - if let Some((arg_types, return_type)) = extract_types(model, annotation) { + if let Some((arg_types, return_type)) = extract_types(annotation, semantic) { // A `lambda` expression can only have positional and positional-only // arguments. The order is always positional-only first, then positional. let new_posonlyargs = args diff --git a/crates/ruff/src/rules/pycodestyle/rules/type_comparison.rs b/crates/ruff/src/rules/pycodestyle/rules/type_comparison.rs index 7cec3e0cb4..1af0cc98f8 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/type_comparison.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/type_comparison.rs @@ -52,7 +52,7 @@ pub(crate) fn type_comparison( Expr::Call(ast::ExprCall { func, args, .. }) => { if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() { // Ex) `type(False)` - if id == "type" && checker.semantic_model().is_builtin("type") { + if id == "type" && checker.semantic().is_builtin("type") { if let Some(arg) = args.first() { // Allow comparison for types which are not obvious. if !matches!( @@ -76,12 +76,12 @@ pub(crate) fn type_comparison( if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() { // Ex) `types.NoneType` if id == "types" - && checker.semantic_model().resolve_call_path(value).map_or( - false, - |call_path| { + && checker + .semantic() + .resolve_call_path(value) + .map_or(false, |call_path| { call_path.first().map_or(false, |module| *module == "types") - }, - ) + }) { checker .diagnostics diff --git a/crates/ruff/src/rules/pydocstyle/helpers.rs b/crates/ruff/src/rules/pydocstyle/helpers.rs index 00d0eb8b93..f0632f86f8 100644 --- a/crates/ruff/src/rules/pydocstyle/helpers.rs +++ b/crates/ruff/src/rules/pydocstyle/helpers.rs @@ -40,9 +40,9 @@ pub(super) fn ends_with_backslash(line: &str) -> bool { /// Check decorator list to see if function should be ignored. pub(crate) fn should_ignore_definition( - model: &SemanticModel, definition: &Definition, ignore_decorators: &BTreeSet, + semantic: &SemanticModel, ) -> bool { if ignore_decorators.is_empty() { return false; @@ -55,7 +55,8 @@ pub(crate) fn should_ignore_definition( }) = definition { for decorator in cast::decorator_list(stmt) { - if let Some(call_path) = model.resolve_call_path(map_callable(&decorator.expression)) { + if let Some(call_path) = semantic.resolve_call_path(map_callable(&decorator.expression)) + { if ignore_decorators .iter() .any(|decorator| from_qualified_name(decorator) == call_path) diff --git a/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs b/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs index c612aad519..c986fb6ac8 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs @@ -27,7 +27,7 @@ pub(crate) fn if_needed(checker: &mut Checker, docstring: &Docstring) { }) = docstring.definition else { return; }; - if !is_overload(checker.semantic_model(), cast::decorator_list(stmt)) { + if !is_overload(cast::decorator_list(stmt), checker.semantic()) { return; } checker.diagnostics.push(Diagnostic::new( diff --git a/crates/ruff/src/rules/pydocstyle/rules/non_imperative_mood.rs b/crates/ruff/src/rules/pydocstyle/rules/non_imperative_mood.rs index 91b67899bb..ecda3d504a 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/non_imperative_mood.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/non_imperative_mood.rs @@ -41,9 +41,9 @@ pub(crate) fn non_imperative_mood( if is_test(cast::name(stmt)) || is_property( - checker.semantic_model(), cast::decorator_list(stmt), &property_decorators, + checker.semantic(), ) { return; diff --git a/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs b/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs index a1cbdb4412..7f2be87fff 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs @@ -158,7 +158,7 @@ pub(crate) fn not_missing( stmt, .. }) => { - if is_overload(checker.semantic_model(), cast::decorator_list(stmt)) { + if is_overload(cast::decorator_list(stmt), checker.semantic()) { true } else { if checker.enabled(Rule::UndocumentedPublicFunction) { @@ -175,8 +175,8 @@ pub(crate) fn not_missing( stmt, .. }) => { - if is_overload(checker.semantic_model(), cast::decorator_list(stmt)) - || is_override(checker.semantic_model(), cast::decorator_list(stmt)) + if is_overload(cast::decorator_list(stmt), checker.semantic()) + || is_override(cast::decorator_list(stmt), checker.semantic()) { true } else if is_init(cast::name(stmt)) { diff --git a/crates/ruff/src/rules/pydocstyle/rules/sections.rs b/crates/ruff/src/rules/pydocstyle/rules/sections.rs index 66f77fcade..30cbd6687c 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/sections.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/sections.rs @@ -722,7 +722,7 @@ fn missing_args(checker: &mut Checker, docstring: &Docstring, docstrings_args: & // If this is a non-static method, skip `cls` or `self`. usize::from( docstring.definition.is_method() - && !is_staticmethod(checker.semantic_model(), cast::decorator_list(stmt)), + && !is_staticmethod(cast::decorator_list(stmt), checker.semantic()), ), ) { diff --git a/crates/ruff/src/rules/pyflakes/rules/invalid_print_syntax.rs b/crates/ruff/src/rules/pyflakes/rules/invalid_print_syntax.rs index 651b03d737..bfbb796bf0 100644 --- a/crates/ruff/src/rules/pyflakes/rules/invalid_print_syntax.rs +++ b/crates/ruff/src/rules/pyflakes/rules/invalid_print_syntax.rs @@ -63,7 +63,7 @@ pub(crate) fn invalid_print_syntax(checker: &mut Checker, left: &Expr) { if id != "print" { return; } - if !checker.semantic_model().is_builtin("print") { + if !checker.semantic().is_builtin("print") { return; }; checker diff --git a/crates/ruff/src/rules/pyflakes/rules/return_outside_function.rs b/crates/ruff/src/rules/pyflakes/rules/return_outside_function.rs index b30512b0b9..54acb483fd 100644 --- a/crates/ruff/src/rules/pyflakes/rules/return_outside_function.rs +++ b/crates/ruff/src/rules/pyflakes/rules/return_outside_function.rs @@ -33,7 +33,7 @@ impl Violation for ReturnOutsideFunction { pub(crate) fn return_outside_function(checker: &mut Checker, stmt: &Stmt) { if matches!( - checker.semantic_model().scope().kind, + checker.semantic().scope().kind, ScopeKind::Class(_) | ScopeKind::Module ) { checker diff --git a/crates/ruff/src/rules/pyflakes/rules/undefined_local.rs b/crates/ruff/src/rules/pyflakes/rules/undefined_local.rs index dae0af9655..2312963920 100644 --- a/crates/ruff/src/rules/pyflakes/rules/undefined_local.rs +++ b/crates/ruff/src/rules/pyflakes/rules/undefined_local.rs @@ -46,7 +46,7 @@ impl Violation for UndefinedLocal { /// F823 pub(crate) fn undefined_local(checker: &mut Checker, name: &str) { // If the name hasn't already been defined in the current scope... - let current = checker.semantic_model().scope(); + let current = checker.semantic().scope(); if !current.kind.is_any_function() || current.has(name) { return; } @@ -57,7 +57,7 @@ pub(crate) fn undefined_local(checker: &mut Checker, name: &str) { // For every function and module scope above us... let local_access = checker - .semantic_model() + .semantic() .scopes .ancestors(parent) .find_map(|scope| { @@ -68,15 +68,12 @@ pub(crate) fn undefined_local(checker: &mut Checker, name: &str) { // If the name was defined in that scope... if let Some(binding) = scope .get(name) - .map(|binding_id| checker.semantic_model().binding(binding_id)) + .map(|binding_id| checker.semantic().binding(binding_id)) { // And has already been accessed in the current scope... if let Some(range) = binding.references().find_map(|reference_id| { - let reference = checker.semantic_model().reference(reference_id); - if checker - .semantic_model() - .is_current_scope(reference.scope_id()) - { + let reference = checker.semantic().reference(reference_id); + if checker.semantic().is_current_scope(reference.scope_id()) { Some(reference.range()) } else { None diff --git a/crates/ruff/src/rules/pyflakes/rules/unused_annotation.rs b/crates/ruff/src/rules/pyflakes/rules/unused_annotation.rs index 55c524edca..1f2e92f25d 100644 --- a/crates/ruff/src/rules/pyflakes/rules/unused_annotation.rs +++ b/crates/ruff/src/rules/pyflakes/rules/unused_annotation.rs @@ -34,12 +34,12 @@ impl Violation for UnusedAnnotation { /// F842 pub(crate) fn unused_annotation(checker: &mut Checker, scope: ScopeId) { - let scope = &checker.semantic_model().scopes[scope]; + let scope = &checker.semantic().scopes[scope]; let bindings: Vec<_> = scope .bindings() .filter_map(|(name, binding_id)| { - let binding = checker.semantic_model().binding(binding_id); + let binding = checker.semantic().binding(binding_id); if binding.kind.is_annotation() && !binding.is_used() && !checker.settings.dummy_variable_rgx.is_match(name) diff --git a/crates/ruff/src/rules/pyflakes/rules/unused_import.rs b/crates/ruff/src/rules/pyflakes/rules/unused_import.rs index 5471c84c63..b8d8e4be92 100644 --- a/crates/ruff/src/rules/pyflakes/rules/unused_import.rs +++ b/crates/ruff/src/rules/pyflakes/rules/unused_import.rs @@ -102,7 +102,7 @@ pub(crate) fn unused_import(checker: &Checker, scope: &Scope, diagnostics: &mut let mut ignored: FxHashMap<(NodeId, Exceptions), Vec> = FxHashMap::default(); for binding_id in scope.binding_ids() { - let binding = checker.semantic_model().binding(binding_id); + let binding = checker.semantic().binding(binding_id); if binding.is_used() || binding.is_explicit_export() { continue; @@ -118,8 +118,8 @@ pub(crate) fn unused_import(checker: &Checker, scope: &Scope, diagnostics: &mut let import = Import { qualified_name, - trimmed_range: binding.trimmed_range(checker.semantic_model(), checker.locator), - parent_range: binding.parent_range(checker.semantic_model()), + trimmed_range: binding.trimmed_range(checker.semantic(), checker.locator), + parent_range: binding.parent_range(checker.semantic()), }; if checker.rule_is_ignored(Rule::UnusedImport, import.trimmed_range.start()) @@ -222,8 +222,8 @@ struct Import<'a> { /// Generate a [`Fix`] to remove unused imports from a statement. fn fix_imports(checker: &Checker, stmt_id: NodeId, imports: &[Import]) -> Result { - let stmt = checker.semantic_model().stmts[stmt_id]; - let parent = checker.semantic_model().stmts.parent(stmt); + let stmt = checker.semantic().stmts[stmt_id]; + let parent = checker.semantic().stmts.parent(stmt); let edit = autofix::edits::remove_unused_imports( imports .iter() diff --git a/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs b/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs index 193a37255b..0909571255 100644 --- a/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs +++ b/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs @@ -199,7 +199,7 @@ fn remove_unused_variable( if let Some(target) = targets.iter().find(|target| range == target.range()) { if target.is_name_expr() { return if targets.len() > 1 - || contains_effect(value, |id| checker.semantic_model().is_builtin(id)) + || contains_effect(value, |id| checker.semantic().is_builtin(id)) { // If the expression is complex (`x = foo()`), remove the assignment, // but preserve the right-hand side. @@ -231,7 +231,7 @@ fn remove_unused_variable( }) = stmt { if target.is_name_expr() { - return if contains_effect(value, |id| checker.semantic_model().is_builtin(id)) { + return if contains_effect(value, |id| checker.semantic().is_builtin(id)) { // If the expression is complex (`x = foo()`), remove the assignment, // but preserve the right-hand side. let start = stmt.start(); @@ -285,14 +285,14 @@ fn remove_unused_variable( /// F841 pub(crate) fn unused_variable(checker: &mut Checker, scope: ScopeId) { - let scope = &checker.semantic_model().scopes[scope]; + let scope = &checker.semantic().scopes[scope]; if scope.uses_locals() && scope.kind.is_any_function() { return; } let bindings: Vec<_> = scope .bindings() - .map(|(name, binding_id)| (name, checker.semantic_model().binding(binding_id))) + .map(|(name, binding_id)| (name, checker.semantic().binding(binding_id))) .filter_map(|(name, binding)| { if (binding.kind.is_assignment() || binding.kind.is_named_expr_assignment()) && !binding.is_used() @@ -313,8 +313,8 @@ pub(crate) fn unused_variable(checker: &mut Checker, scope: ScopeId) { let mut diagnostic = Diagnostic::new(UnusedVariable { name }, range); if checker.patch(diagnostic.kind.rule()) { if let Some(source) = source { - let stmt = checker.semantic_model().stmts[source]; - let parent = checker.semantic_model().stmts.parent(stmt); + let stmt = checker.semantic().stmts[source]; + let parent = checker.semantic().stmts.parent(stmt); if let Some(fix) = remove_unused_variable(stmt, parent, range, checker) { diagnostic.set_fix(fix); } diff --git a/crates/ruff/src/rules/pyflakes/rules/yield_outside_function.rs b/crates/ruff/src/rules/pyflakes/rules/yield_outside_function.rs index d86faeb118..54fab4be14 100644 --- a/crates/ruff/src/rules/pyflakes/rules/yield_outside_function.rs +++ b/crates/ruff/src/rules/pyflakes/rules/yield_outside_function.rs @@ -55,7 +55,7 @@ impl Violation for YieldOutsideFunction { pub(crate) fn yield_outside_function(checker: &mut Checker, expr: &Expr) { if matches!( - checker.semantic_model().scope().kind, + checker.semantic().scope().kind, ScopeKind::Class(_) | ScopeKind::Module ) { let keyword = match expr { diff --git a/crates/ruff/src/rules/pygrep_hooks/rules/deprecated_log_warn.rs b/crates/ruff/src/rules/pygrep_hooks/rules/deprecated_log_warn.rs index ba941d1d85..cdf0490fb6 100644 --- a/crates/ruff/src/rules/pygrep_hooks/rules/deprecated_log_warn.rs +++ b/crates/ruff/src/rules/pygrep_hooks/rules/deprecated_log_warn.rs @@ -44,7 +44,7 @@ impl Violation for DeprecatedLogWarn { /// PGH002 pub(crate) fn deprecated_log_warn(checker: &mut Checker, func: &Expr) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["logging", "warn"] diff --git a/crates/ruff/src/rules/pygrep_hooks/rules/no_eval.rs b/crates/ruff/src/rules/pygrep_hooks/rules/no_eval.rs index 40b224a22c..70c8b57260 100644 --- a/crates/ruff/src/rules/pygrep_hooks/rules/no_eval.rs +++ b/crates/ruff/src/rules/pygrep_hooks/rules/no_eval.rs @@ -46,7 +46,7 @@ pub(crate) fn no_eval(checker: &mut Checker, func: &Expr) { if id != "eval" { return; } - if !checker.semantic_model().is_builtin("eval") { + if !checker.semantic().is_builtin("eval") { return; } checker diff --git a/crates/ruff/src/rules/pylint/helpers.rs b/crates/ruff/src/rules/pylint/helpers.rs index 4e5dba75da..37d48f5104 100644 --- a/crates/ruff/src/rules/pylint/helpers.rs +++ b/crates/ruff/src/rules/pylint/helpers.rs @@ -8,8 +8,8 @@ use ruff_python_semantic::{ScopeKind, SemanticModel}; use crate::settings::Settings; -pub(super) fn in_dunder_init(model: &SemanticModel, settings: &Settings) -> bool { - let scope = model.scope(); +pub(super) fn in_dunder_init(semantic: &SemanticModel, settings: &Settings) -> bool { + let scope = semantic.scope(); let ( ScopeKind::Function(ast::StmtFunctionDef { name, @@ -27,16 +27,16 @@ pub(super) fn in_dunder_init(model: &SemanticModel, settings: &Settings) -> bool if name != "__init__" { return false; } - let Some(parent) = scope.parent.map(|scope_id| &model.scopes[scope_id]) else { + let Some(parent) = scope.parent.map(|scope_id| &semantic.scopes[scope_id]) else { return false; }; if !matches!( function_type::classify( - model, - parent, name, decorator_list, + parent, + semantic, &settings.pep8_naming.classmethod_decorators, &settings.pep8_naming.staticmethod_decorators, ), diff --git a/crates/ruff/src/rules/pylint/rules/await_outside_async.rs b/crates/ruff/src/rules/pylint/rules/await_outside_async.rs index 0a7c2936aa..f0df96fcb0 100644 --- a/crates/ruff/src/rules/pylint/rules/await_outside_async.rs +++ b/crates/ruff/src/rules/pylint/rules/await_outside_async.rs @@ -44,7 +44,7 @@ impl Violation for AwaitOutsideAsync { /// PLE1142 pub(crate) fn await_outside_async(checker: &mut Checker, expr: &Expr) { - if !checker.semantic_model().in_async_context() { + if !checker.semantic().in_async_context() { checker .diagnostics .push(Diagnostic::new(AwaitOutsideAsync, expr.range())); diff --git a/crates/ruff/src/rules/pylint/rules/compare_to_empty_string.rs b/crates/ruff/src/rules/pylint/rules/compare_to_empty_string.rs index 8cde351c82..4872e0f807 100644 --- a/crates/ruff/src/rules/pylint/rules/compare_to_empty_string.rs +++ b/crates/ruff/src/rules/pylint/rules/compare_to_empty_string.rs @@ -98,7 +98,7 @@ pub(crate) fn compare_to_empty_string( ) { // Omit string comparison rules within subscripts. This is mostly commonly used within // DataFrame and np.ndarray indexing. - for parent in checker.semantic_model().expr_ancestors() { + for parent in checker.semantic().expr_ancestors() { if matches!(parent, Expr::Subscript(_)) { return; } diff --git a/crates/ruff/src/rules/pylint/rules/global_statement.rs b/crates/ruff/src/rules/pylint/rules/global_statement.rs index 1bdbe19e26..6a8613b639 100644 --- a/crates/ruff/src/rules/pylint/rules/global_statement.rs +++ b/crates/ruff/src/rules/pylint/rules/global_statement.rs @@ -55,11 +55,11 @@ impl Violation for GlobalStatement { /// PLW0603 pub(crate) fn global_statement(checker: &mut Checker, name: &str) { - let scope = checker.semantic_model().scope(); + let scope = checker.semantic().scope(); if let Some(binding_id) = scope.get(name) { - let binding = checker.semantic_model().binding(binding_id); + let binding = checker.semantic().binding(binding_id); if binding.kind.is_global() { - let source = checker.semantic_model().stmts[binding + let source = checker.semantic().stmts[binding .source .expect("`global` bindings should always have a `source`")]; let diagnostic = Diagnostic::new( diff --git a/crates/ruff/src/rules/pylint/rules/invalid_envvar_default.rs b/crates/ruff/src/rules/pylint/rules/invalid_envvar_default.rs index a70ae406d6..d99dc30aba 100644 --- a/crates/ruff/src/rules/pylint/rules/invalid_envvar_default.rs +++ b/crates/ruff/src/rules/pylint/rules/invalid_envvar_default.rs @@ -84,7 +84,7 @@ pub(crate) fn invalid_envvar_default( keywords: &[Keyword], ) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| call_path.as_slice() == ["os", "getenv"]) { diff --git a/crates/ruff/src/rules/pylint/rules/invalid_envvar_value.rs b/crates/ruff/src/rules/pylint/rules/invalid_envvar_value.rs index 2377de8466..6ee35e0bfd 100644 --- a/crates/ruff/src/rules/pylint/rules/invalid_envvar_value.rs +++ b/crates/ruff/src/rules/pylint/rules/invalid_envvar_value.rs @@ -81,7 +81,7 @@ pub(crate) fn invalid_envvar_value( keywords: &[Keyword], ) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| call_path.as_slice() == ["os", "getenv"]) { diff --git a/crates/ruff/src/rules/pylint/rules/invalid_str_return.rs b/crates/ruff/src/rules/pylint/rules/invalid_str_return.rs index 486c8a474e..9f43d0d96c 100644 --- a/crates/ruff/src/rules/pylint/rules/invalid_str_return.rs +++ b/crates/ruff/src/rules/pylint/rules/invalid_str_return.rs @@ -29,7 +29,7 @@ pub(crate) fn invalid_str_return(checker: &mut Checker, name: &str, body: &[Stmt return; } - if !checker.semantic_model().scope().kind.is_class() { + if !checker.semantic().scope().kind.is_class() { return; } diff --git a/crates/ruff/src/rules/pylint/rules/load_before_global_declaration.rs b/crates/ruff/src/rules/pylint/rules/load_before_global_declaration.rs index 5e936bf334..a408e8d4c6 100644 --- a/crates/ruff/src/rules/pylint/rules/load_before_global_declaration.rs +++ b/crates/ruff/src/rules/pylint/rules/load_before_global_declaration.rs @@ -54,7 +54,7 @@ impl Violation for LoadBeforeGlobalDeclaration { } /// PLE0118 pub(crate) fn load_before_global_declaration(checker: &mut Checker, name: &str, expr: &Expr) { - if let Some(stmt) = checker.semantic_model().global(name) { + if let Some(stmt) = checker.semantic().global(name) { if expr.start() < stmt.start() { #[allow(deprecated)] let location = checker.locator.compute_source_location(stmt.start()); diff --git a/crates/ruff/src/rules/pylint/rules/logging.rs b/crates/ruff/src/rules/pylint/rules/logging.rs index 6ddffccb20..157844d818 100644 --- a/crates/ruff/src/rules/pylint/rules/logging.rs +++ b/crates/ruff/src/rules/pylint/rules/logging.rs @@ -102,7 +102,7 @@ pub(crate) fn logging_call( return; } - if !logging::is_logger_candidate(func, checker.semantic_model()) { + if !logging::is_logger_candidate(func, checker.semantic()) { return; } diff --git a/crates/ruff/src/rules/pylint/rules/nested_min_max.rs b/crates/ruff/src/rules/pylint/rules/nested_min_max.rs index 4eab1a008d..4551376ef6 100644 --- a/crates/ruff/src/rules/pylint/rules/nested_min_max.rs +++ b/crates/ruff/src/rules/pylint/rules/nested_min_max.rs @@ -59,16 +59,20 @@ impl Violation for NestedMinMax { impl MinMax { /// Converts a function call [`Expr`] into a [`MinMax`] if it is a call to `min` or `max`. - fn try_from_call(func: &Expr, keywords: &[Keyword], model: &SemanticModel) -> Option { + fn try_from_call( + func: &Expr, + keywords: &[Keyword], + semantic: &SemanticModel, + ) -> Option { if !keywords.is_empty() { return None; } let Expr::Name(ast::ExprName { id, .. }) = func else { return None; }; - if id.as_str() == "min" && model.is_builtin("min") { + if id.as_str() == "min" && semantic.is_builtin("min") { Some(MinMax::Min) - } else if id.as_str() == "max" && model.is_builtin("max") { + } else if id.as_str() == "max" && semantic.is_builtin("max") { Some(MinMax::Max) } else { None @@ -87,8 +91,8 @@ impl std::fmt::Display for MinMax { /// Collect a new set of arguments to by either accepting existing args as-is or /// collecting child arguments, if it's a call to the same function. -fn collect_nested_args(model: &SemanticModel, min_max: MinMax, args: &[Expr]) -> Vec { - fn inner(model: &SemanticModel, min_max: MinMax, args: &[Expr], new_args: &mut Vec) { +fn collect_nested_args(min_max: MinMax, args: &[Expr], semantic: &SemanticModel) -> Vec { + fn inner(min_max: MinMax, args: &[Expr], semantic: &SemanticModel, new_args: &mut Vec) { for arg in args { if let Expr::Call(ast::ExprCall { func, @@ -106,8 +110,8 @@ fn collect_nested_args(model: &SemanticModel, min_max: MinMax, args: &[Expr]) -> new_args.push(new_arg); continue; } - if MinMax::try_from_call(func, keywords, model) == Some(min_max) { - inner(model, min_max, args, new_args); + if MinMax::try_from_call(func, keywords, semantic) == Some(min_max) { + inner(min_max, args, semantic, new_args); continue; } } @@ -116,7 +120,7 @@ fn collect_nested_args(model: &SemanticModel, min_max: MinMax, args: &[Expr]) -> } let mut new_args = Vec::with_capacity(args.len()); - inner(model, min_max, args, &mut new_args); + inner(min_max, args, semantic, &mut new_args); new_args } @@ -128,7 +132,7 @@ pub(crate) fn nested_min_max( args: &[Expr], keywords: &[Keyword], ) { - let Some(min_max) = MinMax::try_from_call(func, keywords, checker.semantic_model()) else { + let Some(min_max) = MinMax::try_from_call(func, keywords, checker.semantic()) else { return; }; @@ -142,15 +146,14 @@ pub(crate) fn nested_min_max( let Expr::Call(ast::ExprCall { func, keywords, ..} )= arg else { return false; }; - MinMax::try_from_call(func.as_ref(), keywords.as_ref(), checker.semantic_model()) - == Some(min_max) + MinMax::try_from_call(func.as_ref(), keywords.as_ref(), checker.semantic()) == Some(min_max) }) { let mut diagnostic = Diagnostic::new(NestedMinMax { func: min_max }, expr.range()); if checker.patch(diagnostic.kind.rule()) { if !has_comments(expr, checker.locator) { let flattened_expr = Expr::Call(ast::ExprCall { func: Box::new(func.clone()), - args: collect_nested_args(checker.semantic_model(), min_max, args), + args: collect_nested_args(min_max, args, checker.semantic()), keywords: keywords.to_owned(), range: TextRange::default(), }); diff --git a/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs b/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs index d63dd5025b..d068255511 100644 --- a/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs +++ b/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs @@ -59,7 +59,7 @@ pub(crate) fn property_with_parameters( { return; } - if checker.semantic_model().is_builtin("property") + if checker.semantic().is_builtin("property") && args .args .iter() diff --git a/crates/ruff/src/rules/pylint/rules/redefined_loop_name.rs b/crates/ruff/src/rules/pylint/rules/redefined_loop_name.rs index dce30a8956..5a3573952d 100644 --- a/crates/ruff/src/rules/pylint/rules/redefined_loop_name.rs +++ b/crates/ruff/src/rules/pylint/rules/redefined_loop_name.rs @@ -176,7 +176,7 @@ impl<'a, 'b> StatementVisitor<'b> for InnerForWithAssignTargetsVisitor<'a, 'b> { // Check for single-target assignments which are of the // form `x = cast(..., x)`. if targets.first().map_or(false, |target| { - assignment_is_cast_expr(self.context, value, target) + assignment_is_cast_expr(value, target, self.context) }) { return; } @@ -236,7 +236,7 @@ impl<'a, 'b> StatementVisitor<'b> for InnerForWithAssignTargetsVisitor<'a, 'b> { /// /// x = cast(int, x) /// ``` -fn assignment_is_cast_expr(model: &SemanticModel, value: &Expr, target: &Expr) -> bool { +fn assignment_is_cast_expr(value: &Expr, target: &Expr, semantic: &SemanticModel) -> bool { let Expr::Call(ast::ExprCall { func, args, .. }) = value else { return false; }; @@ -252,7 +252,7 @@ fn assignment_is_cast_expr(model: &SemanticModel, value: &Expr, target: &Expr) - if arg_id != target_id { return false; } - model.match_typing_expr(func, "cast") + semantic.match_typing_expr(func, "cast") } fn assignment_targets_from_expr<'a, U>( @@ -345,7 +345,7 @@ pub(crate) fn redefined_loop_name<'a, 'b>(checker: &'a mut Checker<'b>, node: &N }) .collect(); let mut visitor = InnerForWithAssignTargetsVisitor { - context: checker.semantic_model(), + context: checker.semantic(), dummy_variable_rgx: &checker.settings.dummy_variable_rgx, assignment_targets: vec![], }; @@ -365,7 +365,7 @@ pub(crate) fn redefined_loop_name<'a, 'b>(checker: &'a mut Checker<'b>, node: &N }) .collect(); let mut visitor = InnerForWithAssignTargetsVisitor { - context: checker.semantic_model(), + context: checker.semantic(), dummy_variable_rgx: &checker.settings.dummy_variable_rgx, assignment_targets: vec![], }; diff --git a/crates/ruff/src/rules/pylint/rules/repeated_isinstance_calls.rs b/crates/ruff/src/rules/pylint/rules/repeated_isinstance_calls.rs index 031eee89d2..0e578360af 100644 --- a/crates/ruff/src/rules/pylint/rules/repeated_isinstance_calls.rs +++ b/crates/ruff/src/rules/pylint/rules/repeated_isinstance_calls.rs @@ -79,7 +79,7 @@ pub(crate) fn repeated_isinstance_calls( let [obj, types] = &args[..] else { continue; }; - if !checker.semantic_model().is_builtin("isinstance") { + if !checker.semantic().is_builtin("isinstance") { return; } let (num_calls, matches) = obj_to_types diff --git a/crates/ruff/src/rules/pylint/rules/return_in_init.rs b/crates/ruff/src/rules/pylint/rules/return_in_init.rs index 0bd7cd7758..dbffa82463 100644 --- a/crates/ruff/src/rules/pylint/rules/return_in_init.rs +++ b/crates/ruff/src/rules/pylint/rules/return_in_init.rs @@ -62,7 +62,7 @@ pub(crate) fn return_in_init(checker: &mut Checker, stmt: &Stmt) { } } - if in_dunder_init(checker.semantic_model(), checker.settings) { + if in_dunder_init(checker.semantic(), checker.settings) { checker .diagnostics .push(Diagnostic::new(ReturnInInit, stmt.range())); diff --git a/crates/ruff/src/rules/pylint/rules/sys_exit_alias.rs b/crates/ruff/src/rules/pylint/rules/sys_exit_alias.rs index e9dccdd1cd..dedac5503e 100644 --- a/crates/ruff/src/rules/pylint/rules/sys_exit_alias.rs +++ b/crates/ruff/src/rules/pylint/rules/sys_exit_alias.rs @@ -65,7 +65,7 @@ pub(crate) fn sys_exit_alias(checker: &mut Checker, func: &Expr) { if id != name { continue; } - if !checker.semantic_model().is_builtin(name) { + if !checker.semantic().is_builtin(name) { continue; } let mut diagnostic = Diagnostic::new( @@ -79,7 +79,7 @@ pub(crate) fn sys_exit_alias(checker: &mut Checker, func: &Expr) { let (import_edit, binding) = checker.importer.get_or_import_symbol( &ImportRequest::import("sys", "exit"), func.start(), - checker.semantic_model(), + checker.semantic(), )?; let reference_edit = Edit::range_replacement(binding, func.range()); #[allow(deprecated)] diff --git a/crates/ruff/src/rules/pylint/rules/unexpected_special_method_signature.rs b/crates/ruff/src/rules/pylint/rules/unexpected_special_method_signature.rs index e22a2a2655..2790999a22 100644 --- a/crates/ruff/src/rules/pylint/rules/unexpected_special_method_signature.rs +++ b/crates/ruff/src/rules/pylint/rules/unexpected_special_method_signature.rs @@ -145,7 +145,7 @@ pub(crate) fn unexpected_special_method_signature( args: &Arguments, locator: &Locator, ) { - if !checker.semantic_model().scope().kind.is_class() { + if !checker.semantic().scope().kind.is_class() { return; } @@ -163,7 +163,7 @@ pub(crate) fn unexpected_special_method_signature( let optional_params = args.defaults.len(); let mandatory_params = actual_params - optional_params; - let Some(expected_params) = ExpectedParams::from_method(name, is_staticmethod(checker.semantic_model(), decorator_list)) else { + let Some(expected_params) = ExpectedParams::from_method(name, is_staticmethod(decorator_list, checker.semantic())) else { return; }; diff --git a/crates/ruff/src/rules/pylint/rules/yield_from_in_async_function.rs b/crates/ruff/src/rules/pylint/rules/yield_from_in_async_function.rs index 4895faa12a..9b329b3a19 100644 --- a/crates/ruff/src/rules/pylint/rules/yield_from_in_async_function.rs +++ b/crates/ruff/src/rules/pylint/rules/yield_from_in_async_function.rs @@ -38,7 +38,7 @@ impl Violation for YieldFromInAsyncFunction { /// PLE1700 pub(crate) fn yield_from_in_async_function(checker: &mut Checker, expr: &ExprYieldFrom) { - let scope = checker.semantic_model().scope(); + let scope = checker.semantic().scope(); if scope.kind.is_async_function() { checker .diagnostics diff --git a/crates/ruff/src/rules/pylint/rules/yield_in_init.rs b/crates/ruff/src/rules/pylint/rules/yield_in_init.rs index 9ee87e70a7..2fabc842cc 100644 --- a/crates/ruff/src/rules/pylint/rules/yield_in_init.rs +++ b/crates/ruff/src/rules/pylint/rules/yield_in_init.rs @@ -39,7 +39,7 @@ impl Violation for YieldInInit { /// PLE0100 pub(crate) fn yield_in_init(checker: &mut Checker, expr: &Expr) { - if in_dunder_init(checker.semantic_model(), checker.settings) { + if in_dunder_init(checker.semantic(), checker.settings) { checker .diagnostics .push(Diagnostic::new(YieldInInit, expr.range())); diff --git a/crates/ruff/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs b/crates/ruff/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs index b2fac6b580..08d348a065 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs @@ -36,9 +36,9 @@ impl Violation for ConvertNamedTupleFunctionalToClass { /// Return the typename, args, keywords, and base class. fn match_named_tuple_assign<'a>( - model: &SemanticModel, targets: &'a [Expr], value: &'a Expr, + semantic: &SemanticModel, ) -> Option<(&'a str, &'a [Expr], &'a [Keyword], &'a Expr)> { let target = targets.get(0)?; let Expr::Name(ast::ExprName { id: typename, .. }) = target else { @@ -52,7 +52,7 @@ fn match_named_tuple_assign<'a>( }) = value else { return None; }; - if !model.resolve_call_path(func).map_or(false, |call_path| { + if !semantic.resolve_call_path(func).map_or(false, |call_path| { call_path.as_slice() == ["typing", "NamedTuple"] }) { return None; @@ -189,7 +189,7 @@ pub(crate) fn convert_named_tuple_functional_to_class( value: &Expr, ) { let Some((typename, args, keywords, base_class)) = - match_named_tuple_assign(checker.semantic_model(), targets, value) else + match_named_tuple_assign(targets, value, checker.semantic()) else { return; }; diff --git a/crates/ruff/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs b/crates/ruff/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs index adaf6b033b..08ef961118 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs @@ -36,9 +36,9 @@ impl Violation for ConvertTypedDictFunctionalToClass { /// Return the class name, arguments, keywords and base class for a `TypedDict` /// assignment. fn match_typed_dict_assign<'a>( - model: &SemanticModel, targets: &'a [Expr], value: &'a Expr, + semantic: &SemanticModel, ) -> Option<(&'a str, &'a [Expr], &'a [Keyword], &'a Expr)> { let target = targets.get(0)?; let Expr::Name(ast::ExprName { id: class_name, .. }) = target else { @@ -52,7 +52,7 @@ fn match_typed_dict_assign<'a>( }) = value else { return None; }; - if !model.resolve_call_path(func).map_or(false, |call_path| { + if !semantic.resolve_call_path(func).map_or(false, |call_path| { call_path.as_slice() == ["typing", "TypedDict"] }) { return None; @@ -242,7 +242,7 @@ pub(crate) fn convert_typed_dict_functional_to_class( value: &Expr, ) { let Some((class_name, args, keywords, base_class)) = - match_typed_dict_assign(checker.semantic_model(), targets, value) else + match_typed_dict_assign(targets, value, checker.semantic()) else { return; }; diff --git a/crates/ruff/src/rules/pyupgrade/rules/datetime_utc_alias.rs b/crates/ruff/src/rules/pyupgrade/rules/datetime_utc_alias.rs index 16aa05a145..860e99bd79 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/datetime_utc_alias.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/datetime_utc_alias.rs @@ -28,7 +28,7 @@ impl Violation for DatetimeTimezoneUTC { /// UP017 pub(crate) fn datetime_utc_alias(checker: &mut Checker, expr: &Expr) { if checker - .semantic_model() + .semantic() .resolve_call_path(expr) .map_or(false, |call_path| { call_path.as_slice() == ["datetime", "timezone", "utc"] diff --git a/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs b/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs index 9ecf931f2c..c19377c187 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs @@ -38,7 +38,7 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list: if args.is_empty() && keywords.len() == 1 && checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["functools", "lru_cache"] @@ -68,7 +68,7 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list: let (import_edit, binding) = checker.importer.get_or_import_symbol( &ImportRequest::import("functools", "cache"), decorator.start(), - checker.semantic_model(), + checker.semantic(), )?; let reference_edit = Edit::range_replacement(binding, decorator.expression.range()); diff --git a/crates/ruff/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs b/crates/ruff/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs index 0f482afb58..8073666dcc 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs @@ -37,7 +37,7 @@ pub(crate) fn lru_cache_without_parameters(checker: &mut Checker, decorator_list if args.is_empty() && keywords.is_empty() && checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["functools", "lru_cache"] diff --git a/crates/ruff/src/rules/pyupgrade/rules/native_literals.rs b/crates/ruff/src/rules/pyupgrade/rules/native_literals.rs index a7849d2c4f..aac0f59c0d 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/native_literals.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/native_literals.rs @@ -62,11 +62,11 @@ pub(crate) fn native_literals( } // There's no way to rewrite, e.g., `f"{f'{str()}'}"` within a nested f-string. - if checker.semantic_model().in_nested_f_string() { + if checker.semantic().in_nested_f_string() { return; } - if (id == "str" || id == "bytes") && checker.semantic_model().is_builtin(id) { + if (id == "str" || id == "bytes") && checker.semantic().is_builtin(id) { let Some(arg) = args.get(0) else { let mut diagnostic = Diagnostic::new(NativeLiterals{literal_type:if id == "str" { LiteralType::Str diff --git a/crates/ruff/src/rules/pyupgrade/rules/open_alias.rs b/crates/ruff/src/rules/pyupgrade/rules/open_alias.rs index a49207bbb7..8577c0185e 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/open_alias.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/open_alias.rs @@ -25,13 +25,13 @@ impl Violation for OpenAlias { /// UP020 pub(crate) fn open_alias(checker: &mut Checker, expr: &Expr, func: &Expr) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| call_path.as_slice() == ["io", "open"]) { let mut diagnostic = Diagnostic::new(OpenAlias, expr.range()); if checker.patch(diagnostic.kind.rule()) { - if checker.semantic_model().is_available("open") { + if checker.semantic().is_available("open") { diagnostic.set_fix(Fix::suggested(Edit::range_replacement( "open".to_string(), func.range(), diff --git a/crates/ruff/src/rules/pyupgrade/rules/os_error_alias.rs b/crates/ruff/src/rules/pyupgrade/rules/os_error_alias.rs index 890dd665ed..81d995875b 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/os_error_alias.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/os_error_alias.rs @@ -39,8 +39,8 @@ const ALIASES: &[(&str, &str)] = &[ ]; /// Return `true` if an [`Expr`] is an alias of `OSError`. -fn is_alias(model: &SemanticModel, expr: &Expr) -> bool { - model.resolve_call_path(expr).map_or(false, |call_path| { +fn is_alias(expr: &Expr, semantic: &SemanticModel) -> bool { + semantic.resolve_call_path(expr).map_or(false, |call_path| { ALIASES .iter() .any(|(module, member)| call_path.as_slice() == [*module, *member]) @@ -48,8 +48,8 @@ fn is_alias(model: &SemanticModel, expr: &Expr) -> bool { } /// Return `true` if an [`Expr`] is `OSError`. -fn is_os_error(model: &SemanticModel, expr: &Expr) -> bool { - model +fn is_os_error(expr: &Expr, semantic: &SemanticModel) -> bool { + semantic .resolve_call_path(expr) .map_or(false, |call_path| call_path.as_slice() == ["", "OSError"]) } @@ -93,10 +93,7 @@ fn tuple_diagnostic(checker: &mut Checker, target: &Expr, aliases: &[&Expr]) { .collect(); // If `OSError` itself isn't already in the tuple, add it. - if elts - .iter() - .all(|elt| !is_os_error(checker.semantic_model(), elt)) - { + if elts.iter().all(|elt| !is_os_error(elt, checker.semantic())) { let node = ast::ExprName { id: "OSError".into(), ctx: ExprContext::Load, @@ -136,7 +133,7 @@ pub(crate) fn os_error_alias_handlers(checker: &mut Checker, handlers: &[Excepth }; match expr.as_ref() { Expr::Name(_) | Expr::Attribute(_) => { - if is_alias(checker.semantic_model(), expr) { + if is_alias(expr, checker.semantic()) { atom_diagnostic(checker, expr); } } @@ -144,7 +141,7 @@ pub(crate) fn os_error_alias_handlers(checker: &mut Checker, handlers: &[Excepth // List of aliases to replace with `OSError`. let mut aliases: Vec<&Expr> = vec![]; for elt in elts { - if is_alias(checker.semantic_model(), elt) { + if is_alias(elt, checker.semantic()) { aliases.push(elt); } } @@ -159,7 +156,7 @@ pub(crate) fn os_error_alias_handlers(checker: &mut Checker, handlers: &[Excepth /// UP024 pub(crate) fn os_error_alias_call(checker: &mut Checker, func: &Expr) { - if is_alias(checker.semantic_model(), func) { + if is_alias(func, checker.semantic()) { atom_diagnostic(checker, func); } } @@ -167,7 +164,7 @@ pub(crate) fn os_error_alias_call(checker: &mut Checker, func: &Expr) { /// UP024 pub(crate) fn os_error_alias_raise(checker: &mut Checker, expr: &Expr) { if matches!(expr, Expr::Name(_) | Expr::Attribute(_)) { - if is_alias(checker.semantic_model(), expr) { + if is_alias(expr, checker.semantic()) { atom_diagnostic(checker, expr); } } diff --git a/crates/ruff/src/rules/pyupgrade/rules/outdated_version_block.rs b/crates/ruff/src/rules/pyupgrade/rules/outdated_version_block.rs index 96e8d3ac0a..4623ea9cfa 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/outdated_version_block.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/outdated_version_block.rs @@ -188,8 +188,8 @@ fn fix_py2_block( // Delete the entire statement. If this is an `elif`, know it's the only child // of its parent, so avoid passing in the parent at all. Otherwise, // `delete_stmt` will erroneously include a `pass`. - let stmt = checker.semantic_model().stmt(); - let parent = checker.semantic_model().stmt_parent(); + let stmt = checker.semantic().stmt(); + let parent = checker.semantic().stmt_parent(); let edit = delete_stmt( stmt, if matches!(block.leading_token.tok, StartTok::If) { parent } else { None }, @@ -336,7 +336,7 @@ pub(crate) fn outdated_version_block( }; if !checker - .semantic_model() + .semantic() .resolve_call_path(left) .map_or(false, |call_path| { call_path.as_slice() == ["sys", "version_info"] diff --git a/crates/ruff/src/rules/pyupgrade/rules/redundant_open_modes.rs b/crates/ruff/src/rules/pyupgrade/rules/redundant_open_modes.rs index 9dabf61d24..b65019e999 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/redundant_open_modes.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/redundant_open_modes.rs @@ -173,7 +173,7 @@ fn create_remove_param_fix(locator: &Locator, expr: &Expr, mode_param: &Expr) -> /// UP015 pub(crate) fn redundant_open_modes(checker: &mut Checker, expr: &Expr) { // If `open` has been rebound, skip this check entirely. - if !checker.semantic_model().is_builtin(OPEN_FUNC_NAME) { + if !checker.semantic().is_builtin(OPEN_FUNC_NAME) { return; } let (mode_param, keywords): (Option<&Expr>, Vec) = match_open(expr); diff --git a/crates/ruff/src/rules/pyupgrade/rules/replace_stdout_stderr.rs b/crates/ruff/src/rules/pyupgrade/rules/replace_stdout_stderr.rs index b1aee43ed4..64dc64b113 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/replace_stdout_stderr.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/replace_stdout_stderr.rs @@ -61,7 +61,7 @@ pub(crate) fn replace_stdout_stderr( keywords: &[Keyword], ) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["subprocess", "run"] @@ -77,13 +77,13 @@ pub(crate) fn replace_stdout_stderr( // Verify that they're both set to `subprocess.PIPE`. if !checker - .semantic_model() + .semantic() .resolve_call_path(&stdout.value) .map_or(false, |call_path| { call_path.as_slice() == ["subprocess", "PIPE"] }) || !checker - .semantic_model() + .semantic() .resolve_call_path(&stderr.value) .map_or(false, |call_path| { call_path.as_slice() == ["subprocess", "PIPE"] diff --git a/crates/ruff/src/rules/pyupgrade/rules/replace_universal_newlines.rs b/crates/ruff/src/rules/pyupgrade/rules/replace_universal_newlines.rs index 23c0e49de0..e9ab4b80ae 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/replace_universal_newlines.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/replace_universal_newlines.rs @@ -25,7 +25,7 @@ impl AlwaysAutofixableViolation for ReplaceUniversalNewlines { /// UP021 pub(crate) fn replace_universal_newlines(checker: &mut Checker, func: &Expr, kwargs: &[Keyword]) { if checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| { call_path.as_slice() == ["subprocess", "run"] diff --git a/crates/ruff/src/rules/pyupgrade/rules/super_call_with_parameters.rs b/crates/ruff/src/rules/pyupgrade/rules/super_call_with_parameters.rs index 63b4db3443..a7098a0eab 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/super_call_with_parameters.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/super_call_with_parameters.rs @@ -42,14 +42,14 @@ pub(crate) fn super_call_with_parameters( if !is_super_call_with_arguments(func, args) { return; } - let scope = checker.semantic_model().scope(); + let scope = checker.semantic().scope(); // Check: are we in a Function scope? if !scope.kind.is_any_function() { return; } - let mut parents = checker.semantic_model().parents(); + let mut parents = checker.semantic().parents(); // For a `super` invocation to be unnecessary, the first argument needs to match // the enclosing class, and the second argument needs to match the first diff --git a/crates/ruff/src/rules/pyupgrade/rules/type_of_primitive.rs b/crates/ruff/src/rules/pyupgrade/rules/type_of_primitive.rs index 7f2c9a5964..c75fe15303 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/type_of_primitive.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/type_of_primitive.rs @@ -32,7 +32,7 @@ pub(crate) fn type_of_primitive(checker: &mut Checker, expr: &Expr, func: &Expr, return; } if !checker - .semantic_model() + .semantic() .resolve_call_path(func) .map_or(false, |call_path| call_path.as_slice() == ["", "type"]) { diff --git a/crates/ruff/src/rules/pyupgrade/rules/typing_text_str_alias.rs b/crates/ruff/src/rules/pyupgrade/rules/typing_text_str_alias.rs index 5b1a867cca..7c1110689b 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/typing_text_str_alias.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/typing_text_str_alias.rs @@ -23,7 +23,7 @@ impl AlwaysAutofixableViolation for TypingTextStrAlias { /// UP019 pub(crate) fn typing_text_str_alias(checker: &mut Checker, expr: &Expr) { if checker - .semantic_model() + .semantic() .resolve_call_path(expr) .map_or(false, |call_path| { call_path.as_slice() == ["typing", "Text"] diff --git a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs index b604684c1c..9353ad8c32 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs @@ -105,8 +105,8 @@ pub(crate) fn unnecessary_builtin_import( ); if checker.patch(diagnostic.kind.rule()) { diagnostic.try_set_fix(|| { - let stmt = checker.semantic_model().stmt(); - let parent = checker.semantic_model().stmt_parent(); + let stmt = checker.semantic().stmt(); + let parent = checker.semantic().stmt_parent(); let unused_imports: Vec = unused_imports .iter() .map(|alias| format!("{module}.{}", alias.name)) diff --git a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_future_import.rs b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_future_import.rs index 34cd3e5ca5..f3f1bbd609 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_future_import.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_future_import.rs @@ -88,8 +88,8 @@ pub(crate) fn unnecessary_future_import(checker: &mut Checker, stmt: &Stmt, name .iter() .map(|alias| format!("__future__.{}", alias.name)) .collect(); - let stmt = checker.semantic_model().stmt(); - let parent = checker.semantic_model().stmt_parent(); + let stmt = checker.semantic().stmt(); + let parent = checker.semantic().stmt_parent(); let edit = autofix::edits::remove_unused_imports( unused_imports.iter().map(String::as_str), stmt, diff --git a/crates/ruff/src/rules/pyupgrade/rules/use_pep585_annotation.rs b/crates/ruff/src/rules/pyupgrade/rules/use_pep585_annotation.rs index 20e09a7528..5c8305e185 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/use_pep585_annotation.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/use_pep585_annotation.rs @@ -47,11 +47,11 @@ pub(crate) fn use_pep585_annotation( expr.range(), ); if checker.patch(diagnostic.kind.rule()) { - if !checker.semantic_model().in_complex_string_type_definition() { + if !checker.semantic().in_complex_string_type_definition() { match replacement { ModuleMember::BuiltIn(name) => { // Built-in type, like `list`. - if checker.semantic_model().is_builtin(name) { + if checker.semantic().is_builtin(name) { diagnostic.set_fix(Fix::automatic(Edit::range_replacement( (*name).to_string(), expr.range(), @@ -64,7 +64,7 @@ pub(crate) fn use_pep585_annotation( let (import_edit, binding) = checker.importer.get_or_import_symbol( &ImportRequest::import_from(module, member), expr.start(), - checker.semantic_model(), + checker.semantic(), )?; let reference_edit = Edit::range_replacement(binding, expr.range()); Ok(Fix::suggested_edits(import_edit, [reference_edit])) diff --git a/crates/ruff/src/rules/pyupgrade/rules/use_pep604_annotation.rs b/crates/ruff/src/rules/pyupgrade/rules/use_pep604_annotation.rs index 789e89b685..67589ca86e 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/use_pep604_annotation.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/use_pep604_annotation.rs @@ -58,8 +58,8 @@ pub(crate) fn use_pep604_annotation( operator: Pep604Operator, ) { // Avoid fixing forward references, or types not in an annotation. - let fixable = checker.semantic_model().in_type_definition() - && !checker.semantic_model().in_complex_string_type_definition(); + let fixable = checker.semantic().in_type_definition() + && !checker.semantic().in_complex_string_type_definition(); match operator { Pep604Operator::Optional => { let mut diagnostic = Diagnostic::new(NonPEP604Annotation, expr.range()); diff --git a/crates/ruff/src/rules/pyupgrade/rules/use_pep604_isinstance.rs b/crates/ruff/src/rules/pyupgrade/rules/use_pep604_isinstance.rs index 89254e9145..c0f8d6d28b 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/use_pep604_isinstance.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/use_pep604_isinstance.rs @@ -74,7 +74,7 @@ pub(crate) fn use_pep604_isinstance( let Some(kind) = CallKind::from_name(id) else { return; }; - if !checker.semantic_model().is_builtin(id) { + if !checker.semantic().is_builtin(id) { return; }; if let Some(types) = args.get(1) { diff --git a/crates/ruff/src/rules/pyupgrade/rules/useless_metaclass_type.rs b/crates/ruff/src/rules/pyupgrade/rules/useless_metaclass_type.rs index 783bc520c8..104384c246 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/useless_metaclass_type.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/useless_metaclass_type.rs @@ -46,8 +46,8 @@ pub(crate) fn useless_metaclass_type( let mut diagnostic = Diagnostic::new(UselessMetaclassType, stmt.range()); if checker.patch(diagnostic.kind.rule()) { - let stmt = checker.semantic_model().stmt(); - let parent = checker.semantic_model().stmt_parent(); + let stmt = checker.semantic().stmt(); + let parent = checker.semantic().stmt_parent(); let edit = autofix::edits::delete_stmt( stmt, parent, diff --git a/crates/ruff/src/rules/pyupgrade/rules/useless_object_inheritance.rs b/crates/ruff/src/rules/pyupgrade/rules/useless_object_inheritance.rs index 6fa11e3a04..4c8788324b 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/useless_object_inheritance.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/useless_object_inheritance.rs @@ -38,7 +38,7 @@ pub(crate) fn useless_object_inheritance( if id != "object" { continue; } - if !checker.semantic_model().is_builtin("object") { + if !checker.semantic().is_builtin("object") { continue; } diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index c5b2196d53..ef2da7967b 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -131,7 +131,7 @@ fn concatenate_expressions(expr: &Expr) -> Option<(Expr, Type)> { pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Expr) { // If the expression is already a child of an addition, we'll have analyzed it already. if matches!( - checker.semantic_model().expr_parent(), + checker.semantic().expr_parent(), Some(Expr::BinOp(ast::ExprBinOp { op: Operator::Add, .. diff --git a/crates/ruff/src/rules/ruff/rules/explicit_f_string_type_conversion.rs b/crates/ruff/src/rules/ruff/rules/explicit_f_string_type_conversion.rs index 30046ab720..7561fc24ca 100644 --- a/crates/ruff/src/rules/ruff/rules/explicit_f_string_type_conversion.rs +++ b/crates/ruff/src/rules/ruff/rules/explicit_f_string_type_conversion.rs @@ -152,7 +152,7 @@ pub(crate) fn explicit_f_string_type_conversion( continue; }; - if !checker.semantic_model().is_builtin(id) { + if !checker.semantic().is_builtin(id) { continue; } diff --git a/crates/ruff/src/rules/ruff/rules/function_call_in_dataclass_default.rs b/crates/ruff/src/rules/ruff/rules/function_call_in_dataclass_default.rs index 54e0f88488..9aad4078e7 100644 --- a/crates/ruff/src/rules/ruff/rules/function_call_in_dataclass_default.rs +++ b/crates/ruff/src/rules/ruff/rules/function_call_in_dataclass_default.rs @@ -75,7 +75,7 @@ pub(crate) fn function_call_in_dataclass_default( checker: &mut Checker, class_def: &ast::StmtClassDef, ) { - if !is_dataclass(checker.semantic_model(), class_def) { + if !is_dataclass(class_def, checker.semantic()) { return; } @@ -95,9 +95,9 @@ pub(crate) fn function_call_in_dataclass_default( }) = statement { if let Expr::Call(ast::ExprCall { func, .. }) = expr.as_ref() { - if !is_class_var_annotation(checker.semantic_model(), annotation) - && !is_immutable_func(checker.semantic_model(), func, &extend_immutable_calls) - && !is_allowed_dataclass_function(checker.semantic_model(), func) + if !is_class_var_annotation(annotation, checker.semantic()) + && !is_immutable_func(func, checker.semantic(), &extend_immutable_calls) + && !is_allowed_dataclass_function(func, checker.semantic()) { checker.diagnostics.push(Diagnostic::new( FunctionCallInDataclassDefaultArgument { diff --git a/crates/ruff/src/rules/ruff/rules/helpers.rs b/crates/ruff/src/rules/ruff/rules/helpers.rs index 751bf32326..75a9b240d7 100644 --- a/crates/ruff/src/rules/ruff/rules/helpers.rs +++ b/crates/ruff/src/rules/ruff/rules/helpers.rs @@ -17,8 +17,8 @@ pub(super) fn is_mutable_expr(expr: &Expr) -> bool { const ALLOWED_DATACLASS_SPECIFIC_FUNCTIONS: &[&[&str]] = &[&["dataclasses", "field"]]; -pub(super) fn is_allowed_dataclass_function(model: &SemanticModel, func: &Expr) -> bool { - model.resolve_call_path(func).map_or(false, |call_path| { +pub(super) fn is_allowed_dataclass_function(func: &Expr, semantic: &SemanticModel) -> bool { + semantic.resolve_call_path(func).map_or(false, |call_path| { ALLOWED_DATACLASS_SPECIFIC_FUNCTIONS .iter() .any(|target| call_path.as_slice() == *target) @@ -26,17 +26,17 @@ pub(super) fn is_allowed_dataclass_function(model: &SemanticModel, func: &Expr) } /// Returns `true` if the given [`Expr`] is a `typing.ClassVar` annotation. -pub(super) fn is_class_var_annotation(model: &SemanticModel, annotation: &Expr) -> bool { +pub(super) fn is_class_var_annotation(annotation: &Expr, semantic: &SemanticModel) -> bool { let Expr::Subscript(ast::ExprSubscript { value, .. }) = &annotation else { return false; }; - model.match_typing_expr(value, "ClassVar") + semantic.match_typing_expr(value, "ClassVar") } /// Returns `true` if the given class is a dataclass. -pub(super) fn is_dataclass(model: &SemanticModel, class_def: &ast::StmtClassDef) -> bool { +pub(super) fn is_dataclass(class_def: &ast::StmtClassDef, semantic: &SemanticModel) -> bool { class_def.decorator_list.iter().any(|decorator| { - model + semantic .resolve_call_path(map_callable(&decorator.expression)) .map_or(false, |call_path| { call_path.as_slice() == ["dataclasses", "dataclass"] diff --git a/crates/ruff/src/rules/ruff/rules/implicit_optional.rs b/crates/ruff/src/rules/ruff/rules/implicit_optional.rs index 0b00b3adbf..f032db7101 100644 --- a/crates/ruff/src/rules/ruff/rules/implicit_optional.rs +++ b/crates/ruff/src/rules/ruff/rules/implicit_optional.rs @@ -145,20 +145,20 @@ enum TypingTarget<'a> { } impl<'a> TypingTarget<'a> { - fn try_from_expr(model: &SemanticModel, expr: &'a Expr) -> Option { + fn try_from_expr(expr: &'a Expr, semantic: &SemanticModel) -> Option { match expr { Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => { - if model.match_typing_expr(value, "Optional") { + if semantic.match_typing_expr(value, "Optional") { return Some(TypingTarget::Optional); } let Expr::Tuple(ast::ExprTuple { elts: elements, .. }) = slice.as_ref() else{ return None; }; - if model.match_typing_expr(value, "Literal") { + if semantic.match_typing_expr(value, "Literal") { Some(TypingTarget::Literal(elements.iter().collect())) - } else if model.match_typing_expr(value, "Union") { + } else if semantic.match_typing_expr(value, "Union") { Some(TypingTarget::Union(elements.iter().collect())) - } else if model.match_typing_expr(value, "Annotated") { + } else if semantic.match_typing_expr(value, "Annotated") { elements.first().map(TypingTarget::Annotated) } else { None @@ -171,8 +171,8 @@ impl<'a> TypingTarget<'a> { value: Constant::None, .. }) => Some(TypingTarget::None), - _ => model.resolve_call_path(expr).and_then(|call_path| { - if model.match_typing_call_path(&call_path, "Any") { + _ => semantic.resolve_call_path(expr).and_then(|call_path| { + if semantic.match_typing_call_path(&call_path, "Any") { Some(TypingTarget::Any) } else if matches!(call_path.as_slice(), ["" | "builtins", "object"]) { Some(TypingTarget::Object) @@ -184,40 +184,40 @@ impl<'a> TypingTarget<'a> { } /// Check if the [`TypingTarget`] explicitly allows `None`. - fn contains_none(&self, model: &SemanticModel) -> bool { + fn contains_none(&self, semantic: &SemanticModel) -> bool { match self { TypingTarget::None | TypingTarget::Optional | TypingTarget::Any | TypingTarget::Object => true, TypingTarget::Literal(elements) => elements.iter().any(|element| { - let Some(new_target) = TypingTarget::try_from_expr(model, element) else { + let Some(new_target) = TypingTarget::try_from_expr(element, semantic) else { return false; }; // Literal can only contain `None`, a literal value, other `Literal` // or an enum value. match new_target { TypingTarget::None => true, - TypingTarget::Literal(_) => new_target.contains_none(model), + TypingTarget::Literal(_) => new_target.contains_none(semantic), _ => false, } }), TypingTarget::Union(elements) => elements.iter().any(|element| { - let Some(new_target) = TypingTarget::try_from_expr(model, element) else { + let Some(new_target) = TypingTarget::try_from_expr(element, semantic) else { return false; }; match new_target { TypingTarget::None => true, - _ => new_target.contains_none(model), + _ => new_target.contains_none(semantic), } }), TypingTarget::Annotated(element) => { - let Some(new_target) = TypingTarget::try_from_expr(model, element) else { + let Some(new_target) = TypingTarget::try_from_expr(element, semantic) else { return false; }; match new_target { TypingTarget::None => true, - _ => new_target.contains_none(model), + _ => new_target.contains_none(semantic), } } } @@ -232,10 +232,10 @@ impl<'a> TypingTarget<'a> { /// /// This function assumes that the annotation is a valid typing annotation expression. fn type_hint_explicitly_allows_none<'a>( - model: &SemanticModel, annotation: &'a Expr, + semantic: &SemanticModel, ) -> Option<&'a Expr> { - let Some(target) = TypingTarget::try_from_expr(model, annotation) else { + let Some(target) = TypingTarget::try_from_expr(annotation, semantic) else { return Some(annotation); }; match target { @@ -245,9 +245,9 @@ fn type_hint_explicitly_allows_none<'a>( // return the inner type if it doesn't allow `None`. If `Annotated` // is found nested inside another type, then the outer type should // be returned. - TypingTarget::Annotated(expr) => type_hint_explicitly_allows_none(model, expr), + TypingTarget::Annotated(expr) => type_hint_explicitly_allows_none(expr, semantic), _ => { - if target.contains_none(model) { + if target.contains_none(semantic) { None } else { Some(annotation) @@ -280,7 +280,7 @@ fn generate_fix(checker: &Checker, conversion_type: ConversionType, expr: &Expr) let (import_edit, binding) = checker.importer.get_or_import_symbol( &ImportRequest::import_from("typing", "Optional"), expr.start(), - checker.semantic_model(), + checker.semantic(), )?; let new_expr = Expr::Subscript(ast::ExprSubscript { range: TextRange::default(), @@ -329,7 +329,7 @@ pub(crate) fn implicit_optional(checker: &mut Checker, arguments: &Arguments) { let Some(annotation) = &arg.annotation else { continue }; - let Some(expr) = type_hint_explicitly_allows_none(checker.semantic_model(), annotation) else { + let Some(expr) = type_hint_explicitly_allows_none(annotation, checker.semantic()) else { continue; }; let conversion_type = checker.settings.target_version.into(); diff --git a/crates/ruff/src/rules/ruff/rules/mutable_class_default.rs b/crates/ruff/src/rules/ruff/rules/mutable_class_default.rs index f126251352..113c3afc96 100644 --- a/crates/ruff/src/rules/ruff/rules/mutable_class_default.rs +++ b/crates/ruff/src/rules/ruff/rules/mutable_class_default.rs @@ -53,9 +53,9 @@ pub(crate) fn mutable_class_default(checker: &mut Checker, class_def: &ast::Stmt .. }) => { if is_mutable_expr(value) - && !is_class_var_annotation(checker.semantic_model(), annotation) - && !is_immutable_annotation(checker.semantic_model(), annotation) - && !is_dataclass(checker.semantic_model(), class_def) + && !is_class_var_annotation(annotation, checker.semantic()) + && !is_immutable_annotation(annotation, checker.semantic()) + && !is_dataclass(class_def, checker.semantic()) { checker .diagnostics diff --git a/crates/ruff/src/rules/ruff/rules/mutable_dataclass_default.rs b/crates/ruff/src/rules/ruff/rules/mutable_dataclass_default.rs index 63d4b6d397..ac30e0e214 100644 --- a/crates/ruff/src/rules/ruff/rules/mutable_dataclass_default.rs +++ b/crates/ruff/src/rules/ruff/rules/mutable_dataclass_default.rs @@ -63,7 +63,7 @@ impl Violation for MutableDataclassDefault { /// RUF008 pub(crate) fn mutable_dataclass_default(checker: &mut Checker, class_def: &ast::StmtClassDef) { - if !is_dataclass(checker.semantic_model(), class_def) { + if !is_dataclass(class_def, checker.semantic()) { return; } @@ -75,8 +75,8 @@ pub(crate) fn mutable_dataclass_default(checker: &mut Checker, class_def: &ast:: }) = statement { if is_mutable_expr(value) - && !is_class_var_annotation(checker.semantic_model(), annotation) - && !is_immutable_annotation(checker.semantic_model(), annotation) + && !is_class_var_annotation(annotation, checker.semantic()) + && !is_immutable_annotation(annotation, checker.semantic()) { checker .diagnostics diff --git a/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs b/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs index ee3c5b0d0c..3e6f60fd54 100644 --- a/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs +++ b/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs @@ -99,7 +99,7 @@ pub(crate) fn pairwise_over_zipped(checker: &mut Checker, func: &Expr, args: &[E } // Require the function to be the builtin `zip`. - if !(id == "zip" && checker.semantic_model().is_builtin(id)) { + if !(id == "zip" && checker.semantic().is_builtin(id)) { return; } diff --git a/crates/ruff/src/rules/tryceratops/helpers.rs b/crates/ruff/src/rules/tryceratops/helpers.rs index 2581f86e0c..d4a5655893 100644 --- a/crates/ruff/src/rules/tryceratops/helpers.rs +++ b/crates/ruff/src/rules/tryceratops/helpers.rs @@ -7,14 +7,14 @@ use ruff_python_semantic::SemanticModel; /// Collect `logging`-like calls from an AST. pub(super) struct LoggerCandidateVisitor<'a, 'b> { - semantic_model: &'a SemanticModel<'b>, + semantic: &'a SemanticModel<'b>, pub(super) calls: Vec<&'b ast::ExprCall>, } impl<'a, 'b> LoggerCandidateVisitor<'a, 'b> { - pub(super) fn new(semantic_model: &'a SemanticModel<'b>) -> Self { + pub(super) fn new(semantic: &'a SemanticModel<'b>) -> Self { LoggerCandidateVisitor { - semantic_model, + semantic, calls: Vec::new(), } } @@ -23,7 +23,7 @@ impl<'a, 'b> LoggerCandidateVisitor<'a, 'b> { impl<'a, 'b> Visitor<'b> for LoggerCandidateVisitor<'a, 'b> { fn visit_expr(&mut self, expr: &'b Expr) { if let Expr::Call(call) = expr { - if logging::is_logger_candidate(&call.func, self.semantic_model) { + if logging::is_logger_candidate(&call.func, self.semantic) { self.calls.push(call); } } diff --git a/crates/ruff/src/rules/tryceratops/rules/error_instead_of_exception.rs b/crates/ruff/src/rules/tryceratops/rules/error_instead_of_exception.rs index 09af41b601..a335c103f4 100644 --- a/crates/ruff/src/rules/tryceratops/rules/error_instead_of_exception.rs +++ b/crates/ruff/src/rules/tryceratops/rules/error_instead_of_exception.rs @@ -58,14 +58,14 @@ pub(crate) fn error_instead_of_exception(checker: &mut Checker, handlers: &[Exce for handler in handlers { let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = handler; let calls = { - let mut visitor = LoggerCandidateVisitor::new(checker.semantic_model()); + let mut visitor = LoggerCandidateVisitor::new(checker.semantic()); visitor.visit_body(body); visitor.calls }; for expr in calls { if let Expr::Attribute(ast::ExprAttribute { attr, .. }) = expr.func.as_ref() { if attr == "error" { - if exc_info(&expr.keywords, checker.semantic_model()).is_none() { + if exc_info(&expr.keywords, checker.semantic()).is_none() { checker .diagnostics .push(Diagnostic::new(ErrorInsteadOfException, expr.range())); diff --git a/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_class.rs b/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_class.rs index 46024b2db3..2156550cd0 100644 --- a/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_class.rs +++ b/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_class.rs @@ -63,7 +63,7 @@ impl Violation for RaiseVanillaClass { /// TRY002 pub(crate) fn raise_vanilla_class(checker: &mut Checker, expr: &Expr) { if checker - .semantic_model() + .semantic() .resolve_call_path(if let Expr::Call(ast::ExprCall { func, .. }) = expr { func } else { diff --git a/crates/ruff/src/rules/tryceratops/rules/try_consider_else.rs b/crates/ruff/src/rules/tryceratops/rules/try_consider_else.rs index 91e7624f94..ca866ff95c 100644 --- a/crates/ruff/src/rules/tryceratops/rules/try_consider_else.rs +++ b/crates/ruff/src/rules/tryceratops/rules/try_consider_else.rs @@ -66,7 +66,7 @@ pub(crate) fn try_consider_else( if let Some(stmt) = body.last() { if let Stmt::Return(ast::StmtReturn { value, range: _ }) = stmt { if let Some(value) = value { - if contains_effect(value, |id| checker.semantic_model().is_builtin(id)) { + if contains_effect(value, |id| checker.semantic().is_builtin(id)) { return; } } diff --git a/crates/ruff/src/rules/tryceratops/rules/type_check_without_type_error.rs b/crates/ruff/src/rules/tryceratops/rules/type_check_without_type_error.rs index f87d7b010a..a909a836a6 100644 --- a/crates/ruff/src/rules/tryceratops/rules/type_check_without_type_error.rs +++ b/crates/ruff/src/rules/tryceratops/rules/type_check_without_type_error.rs @@ -77,7 +77,7 @@ fn has_control_flow(stmt: &Stmt) -> bool { /// Returns `true` if an [`Expr`] is a call to check types. fn check_type_check_call(checker: &mut Checker, call: &Expr) -> bool { checker - .semantic_model() + .semantic() .resolve_call_path(call) .map_or(false, |call_path| { call_path.as_slice() == ["", "isinstance"] @@ -101,7 +101,7 @@ fn check_type_check_test(checker: &mut Checker, test: &Expr) -> bool { /// Returns `true` if `exc` is a reference to a builtin exception. fn is_builtin_exception(checker: &mut Checker, exc: &Expr) -> bool { return checker - .semantic_model() + .semantic() .resolve_call_path(exc) .map_or(false, |call_path| { [ diff --git a/crates/ruff/src/rules/tryceratops/rules/verbose_log_message.rs b/crates/ruff/src/rules/tryceratops/rules/verbose_log_message.rs index dd1dd7d34c..7153fe800a 100644 --- a/crates/ruff/src/rules/tryceratops/rules/verbose_log_message.rs +++ b/crates/ruff/src/rules/tryceratops/rules/verbose_log_message.rs @@ -67,7 +67,7 @@ pub(crate) fn verbose_log_message(checker: &mut Checker, handlers: &[Excepthandl // Find all calls to `logging.exception`. let calls = { - let mut visitor = LoggerCandidateVisitor::new(checker.semantic_model()); + let mut visitor = LoggerCandidateVisitor::new(checker.semantic()); visitor.visit_body(body); visitor.calls }; diff --git a/crates/ruff_python_semantic/src/analyze/function_type.rs b/crates/ruff_python_semantic/src/analyze/function_type.rs index 89f68a78ff..1a9851cb3f 100644 --- a/crates/ruff_python_semantic/src/analyze/function_type.rs +++ b/crates/ruff_python_semantic/src/analyze/function_type.rs @@ -19,10 +19,10 @@ pub enum FunctionType { /// Classify a function based on its scope, name, and decorators. pub fn classify( - model: &SemanticModel, - scope: &Scope, name: &str, decorator_list: &[Decorator], + scope: &Scope, + semantic: &SemanticModel, classmethod_decorators: &[String], staticmethod_decorators: &[String], ) -> FunctionType { @@ -32,7 +32,7 @@ pub fn classify( if decorator_list.iter().any(|decorator| { // The method is decorated with a static method decorator (like // `@staticmethod`). - model + semantic .resolve_call_path(map_callable(&decorator.expression)) .map_or(false, |call_path| { call_path.as_slice() == ["", "staticmethod"] @@ -46,7 +46,7 @@ pub fn classify( // Special-case class method, like `__new__`. || scope.bases.iter().any(|expr| { // The class itself extends a known metaclass, so all methods are class methods. - model.resolve_call_path(map_callable(expr)).map_or(false, |call_path| { + semantic.resolve_call_path(map_callable(expr)).map_or(false, |call_path| { METACLASS_BASES .iter() .any(|(module, member)| call_path.as_slice() == [*module, *member]) @@ -54,7 +54,7 @@ pub fn classify( }) || decorator_list.iter().any(|decorator| { // The method is decorated with a class method decorator (like `@classmethod`). - model.resolve_call_path(map_callable(&decorator.expression)).map_or(false, |call_path| { + semantic.resolve_call_path(map_callable(&decorator.expression)).map_or(false, |call_path| { call_path.as_slice() == ["", "classmethod"] || classmethod_decorators .iter() diff --git a/crates/ruff_python_semantic/src/analyze/logging.rs b/crates/ruff_python_semantic/src/analyze/logging.rs index 9dd4079ed6..1976565aa0 100644 --- a/crates/ruff_python_semantic/src/analyze/logging.rs +++ b/crates/ruff_python_semantic/src/analyze/logging.rs @@ -17,9 +17,9 @@ use crate::model::SemanticModel; /// # This is detected to be a logger candidate /// bar.error() /// ``` -pub fn is_logger_candidate(func: &Expr, model: &SemanticModel) -> bool { +pub fn is_logger_candidate(func: &Expr, semantic: &SemanticModel) -> bool { if let Expr::Attribute(ast::ExprAttribute { value, .. }) = func { - let Some(call_path) = (if let Some(call_path) = model.resolve_call_path(value) { + let Some(call_path) = (if let Some(call_path) = semantic.resolve_call_path(value) { if call_path.first().map_or(false, |module| *module == "logging") || call_path.as_slice() == ["flask", "current_app", "logger"] { Some(call_path) } else { @@ -41,7 +41,7 @@ pub fn is_logger_candidate(func: &Expr, model: &SemanticModel) -> bool { /// If the keywords to a logging call contain `exc_info=True` or `exc_info=sys.exc_info()`, /// return the `Keyword` for `exc_info`. -pub fn exc_info<'a>(keywords: &'a [Keyword], model: &SemanticModel) -> Option<&'a Keyword> { +pub fn exc_info<'a>(keywords: &'a [Keyword], semantic: &SemanticModel) -> Option<&'a Keyword> { let exc_info = find_keyword(keywords, "exc_info")?; // Ex) `logging.error("...", exc_info=True)` @@ -57,7 +57,7 @@ pub fn exc_info<'a>(keywords: &'a [Keyword], model: &SemanticModel) -> Option<&' // Ex) `logging.error("...", exc_info=sys.exc_info())` if let Expr::Call(ast::ExprCall { func, .. }) = &exc_info.value { - if model.resolve_call_path(func).map_or(false, |call_path| { + if semantic.resolve_call_path(func).map_or(false, |call_path| { call_path.as_slice() == ["sys", "exc_info"] }) { return Some(exc_info); diff --git a/crates/ruff_python_semantic/src/analyze/typing.rs b/crates/ruff_python_semantic/src/analyze/typing.rs index 694e97e650..58585e425b 100644 --- a/crates/ruff_python_semantic/src/analyze/typing.rs +++ b/crates/ruff_python_semantic/src/analyze/typing.rs @@ -29,7 +29,7 @@ pub enum SubscriptKind { pub fn match_annotated_subscript<'a>( expr: &Expr, - semantic_model: &SemanticModel, + semantic: &SemanticModel, typing_modules: impl Iterator, extend_generics: &[String], ) -> Option { @@ -37,39 +37,37 @@ pub fn match_annotated_subscript<'a>( return None; } - semantic_model - .resolve_call_path(expr) - .and_then(|call_path| { - if SUBSCRIPTS.contains(&call_path.as_slice()) - || extend_generics - .iter() - .map(|target| from_qualified_name(target)) - .any(|target| call_path == target) - { - return Some(SubscriptKind::AnnotatedSubscript); - } - if PEP_593_SUBSCRIPTS.contains(&call_path.as_slice()) { - return Some(SubscriptKind::PEP593AnnotatedSubscript); - } + semantic.resolve_call_path(expr).and_then(|call_path| { + if SUBSCRIPTS.contains(&call_path.as_slice()) + || extend_generics + .iter() + .map(|target| from_qualified_name(target)) + .any(|target| call_path == target) + { + return Some(SubscriptKind::AnnotatedSubscript); + } + if PEP_593_SUBSCRIPTS.contains(&call_path.as_slice()) { + return Some(SubscriptKind::PEP593AnnotatedSubscript); + } - for module in typing_modules { - let module_call_path: CallPath = from_unqualified_name(module); - if call_path.starts_with(&module_call_path) { - for subscript in SUBSCRIPTS.iter() { - if call_path.last() == subscript.last() { - return Some(SubscriptKind::AnnotatedSubscript); - } + for module in typing_modules { + let module_call_path: CallPath = from_unqualified_name(module); + if call_path.starts_with(&module_call_path) { + for subscript in SUBSCRIPTS.iter() { + if call_path.last() == subscript.last() { + return Some(SubscriptKind::AnnotatedSubscript); } - for subscript in PEP_593_SUBSCRIPTS.iter() { - if call_path.last() == subscript.last() { - return Some(SubscriptKind::PEP593AnnotatedSubscript); - } + } + for subscript in PEP_593_SUBSCRIPTS.iter() { + if call_path.last() == subscript.last() { + return Some(SubscriptKind::PEP593AnnotatedSubscript); } } } + } - None - }) + None + }) } #[derive(Debug, Clone, Eq, PartialEq)] @@ -91,32 +89,30 @@ impl std::fmt::Display for ModuleMember { /// Returns the PEP 585 standard library generic variant for a `typing` module reference, if such /// a variant exists. -pub fn to_pep585_generic(expr: &Expr, semantic_model: &SemanticModel) -> Option { - semantic_model - .resolve_call_path(expr) - .and_then(|call_path| { - let [module, name] = call_path.as_slice() else { +pub fn to_pep585_generic(expr: &Expr, semantic: &SemanticModel) -> Option { + semantic.resolve_call_path(expr).and_then(|call_path| { + let [module, name] = call_path.as_slice() else { return None; }; - PEP_585_GENERICS.iter().find_map( - |((from_module, from_member), (to_module, to_member))| { - if module == from_module && name == from_member { - if to_module.is_empty() { - Some(ModuleMember::BuiltIn(to_member)) - } else { - Some(ModuleMember::Member(to_module, to_member)) - } + PEP_585_GENERICS + .iter() + .find_map(|((from_module, from_member), (to_module, to_member))| { + if module == from_module && name == from_member { + if to_module.is_empty() { + Some(ModuleMember::BuiltIn(to_member)) } else { - None + Some(ModuleMember::Member(to_module, to_member)) } - }, - ) - }) + } else { + None + } + }) + }) } /// Return whether a given expression uses a PEP 585 standard library generic. -pub fn is_pep585_generic(expr: &Expr, model: &SemanticModel) -> bool { - if let Some(call_path) = model.resolve_call_path(expr) { +pub fn is_pep585_generic(expr: &Expr, semantic: &SemanticModel) -> bool { + if let Some(call_path) = semantic.resolve_call_path(expr) { let [module, name] = call_path.as_slice() else { return false; }; @@ -141,7 +137,7 @@ pub enum Pep604Operator { pub fn to_pep604_operator( value: &Expr, slice: &Expr, - semantic_model: &SemanticModel, + semantic: &SemanticModel, ) -> Option { /// Returns `true` if any argument in the slice is a string. fn any_arg_is_str(slice: &Expr) -> bool { @@ -161,13 +157,13 @@ pub fn to_pep604_operator( return None; } - semantic_model + semantic .resolve_call_path(value) .as_ref() .and_then(|call_path| { - if semantic_model.match_typing_call_path(call_path, "Optional") { + if semantic.match_typing_call_path(call_path, "Optional") { Some(Pep604Operator::Optional) - } else if semantic_model.match_typing_call_path(call_path, "Union") { + } else if semantic.match_typing_call_path(call_path, "Union") { Some(Pep604Operator::Union) } else { None @@ -177,19 +173,17 @@ pub fn to_pep604_operator( /// Return `true` if `Expr` represents a reference to a type annotation that resolves to an /// immutable type. -pub fn is_immutable_annotation(semantic_model: &SemanticModel, expr: &Expr) -> bool { +pub fn is_immutable_annotation(expr: &Expr, semantic: &SemanticModel) -> bool { match expr { Expr::Name(_) | Expr::Attribute(_) => { - semantic_model - .resolve_call_path(expr) - .map_or(false, |call_path| { - IMMUTABLE_TYPES - .iter() - .chain(IMMUTABLE_GENERIC_TYPES) - .any(|target| call_path.as_slice() == *target) - }) + semantic.resolve_call_path(expr).map_or(false, |call_path| { + IMMUTABLE_TYPES + .iter() + .chain(IMMUTABLE_GENERIC_TYPES) + .any(|target| call_path.as_slice() == *target) + }) } - Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => semantic_model + Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => semantic .resolve_call_path(value) .map_or(false, |call_path| { if IMMUTABLE_GENERIC_TYPES @@ -200,16 +194,16 @@ pub fn is_immutable_annotation(semantic_model: &SemanticModel, expr: &Expr) -> b } else if call_path.as_slice() == ["typing", "Union"] { if let Expr::Tuple(ast::ExprTuple { elts, .. }) = slice.as_ref() { elts.iter() - .all(|elt| is_immutable_annotation(semantic_model, elt)) + .all(|elt| is_immutable_annotation(elt, semantic)) } else { false } } else if call_path.as_slice() == ["typing", "Optional"] { - is_immutable_annotation(semantic_model, slice) + is_immutable_annotation(slice, semantic) } else if call_path.as_slice() == ["typing", "Annotated"] { if let Expr::Tuple(ast::ExprTuple { elts, .. }) = slice.as_ref() { elts.first() - .map_or(false, |elt| is_immutable_annotation(semantic_model, elt)) + .map_or(false, |elt| is_immutable_annotation(elt, semantic)) } else { false } @@ -222,10 +216,7 @@ pub fn is_immutable_annotation(semantic_model: &SemanticModel, expr: &Expr) -> b op: Operator::BitOr, right, range: _range, - }) => { - is_immutable_annotation(semantic_model, left) - && is_immutable_annotation(semantic_model, right) - } + }) => is_immutable_annotation(left, semantic) && is_immutable_annotation(right, semantic), Expr::Constant(ast::ExprConstant { value: Constant::None, .. @@ -257,24 +248,22 @@ const IMMUTABLE_FUNCS: &[&[&str]] = &[ /// Return `true` if `func` is a function that returns an immutable object. pub fn is_immutable_func( - semantic_model: &SemanticModel, func: &Expr, + semantic: &SemanticModel, extend_immutable_calls: &[CallPath], ) -> bool { - semantic_model - .resolve_call_path(func) - .map_or(false, |call_path| { - IMMUTABLE_FUNCS + semantic.resolve_call_path(func).map_or(false, |call_path| { + IMMUTABLE_FUNCS + .iter() + .any(|target| call_path.as_slice() == *target) + || extend_immutable_calls .iter() - .any(|target| call_path.as_slice() == *target) - || extend_immutable_calls - .iter() - .any(|target| call_path == *target) - }) + .any(|target| call_path == *target) + }) } /// Return `true` if [`Expr`] is a guard for a type-checking block. -pub fn is_type_checking_block(stmt: &ast::StmtIf, semantic_model: &SemanticModel) -> bool { +pub fn is_type_checking_block(stmt: &ast::StmtIf, semantic: &SemanticModel) -> bool { let ast::StmtIf { test, .. } = stmt; // Ex) `if False:` @@ -300,12 +289,9 @@ pub fn is_type_checking_block(stmt: &ast::StmtIf, semantic_model: &SemanticModel } // Ex) `if typing.TYPE_CHECKING:` - if semantic_model - .resolve_call_path(test) - .map_or(false, |call_path| { - call_path.as_slice() == ["typing", "TYPE_CHECKING"] - }) - { + if semantic.resolve_call_path(test).map_or(false, |call_path| { + call_path.as_slice() == ["typing", "TYPE_CHECKING"] + }) { return true; } diff --git a/crates/ruff_python_semantic/src/analyze/visibility.rs b/crates/ruff_python_semantic/src/analyze/visibility.rs index a94ac4ca5c..331e912feb 100644 --- a/crates/ruff_python_semantic/src/analyze/visibility.rs +++ b/crates/ruff_python_semantic/src/analyze/visibility.rs @@ -14,9 +14,9 @@ pub enum Visibility { } /// Returns `true` if a function is a "static method". -pub fn is_staticmethod(model: &SemanticModel, decorator_list: &[Decorator]) -> bool { +pub fn is_staticmethod(decorator_list: &[Decorator], semantic: &SemanticModel) -> bool { decorator_list.iter().any(|decorator| { - model + semantic .resolve_call_path(map_callable(&decorator.expression)) .map_or(false, |call_path| { call_path.as_slice() == ["", "staticmethod"] @@ -25,9 +25,9 @@ pub fn is_staticmethod(model: &SemanticModel, decorator_list: &[Decorator]) -> b } /// Returns `true` if a function is a "class method". -pub fn is_classmethod(model: &SemanticModel, decorator_list: &[Decorator]) -> bool { +pub fn is_classmethod(decorator_list: &[Decorator], semantic: &SemanticModel) -> bool { decorator_list.iter().any(|decorator| { - model + semantic .resolve_call_path(map_callable(&decorator.expression)) .map_or(false, |call_path| { call_path.as_slice() == ["", "classmethod"] @@ -36,23 +36,23 @@ pub fn is_classmethod(model: &SemanticModel, decorator_list: &[Decorator]) -> bo } /// Returns `true` if a function definition is an `@overload`. -pub fn is_overload(model: &SemanticModel, decorator_list: &[Decorator]) -> bool { - decorator_list - .iter() - .any(|decorator| model.match_typing_expr(map_callable(&decorator.expression), "overload")) +pub fn is_overload(decorator_list: &[Decorator], semantic: &SemanticModel) -> bool { + decorator_list.iter().any(|decorator| { + semantic.match_typing_expr(map_callable(&decorator.expression), "overload") + }) } /// Returns `true` if a function definition is an `@override` (PEP 698). -pub fn is_override(model: &SemanticModel, decorator_list: &[Decorator]) -> bool { - decorator_list - .iter() - .any(|decorator| model.match_typing_expr(map_callable(&decorator.expression), "override")) +pub fn is_override(decorator_list: &[Decorator], semantic: &SemanticModel) -> bool { + decorator_list.iter().any(|decorator| { + semantic.match_typing_expr(map_callable(&decorator.expression), "override") + }) } /// Returns `true` if a function definition is an abstract method based on its decorators. -pub fn is_abstract(model: &SemanticModel, decorator_list: &[Decorator]) -> bool { +pub fn is_abstract(decorator_list: &[Decorator], semantic: &SemanticModel) -> bool { decorator_list.iter().any(|decorator| { - model + semantic .resolve_call_path(map_callable(&decorator.expression)) .map_or(false, |call_path| { matches!( @@ -73,12 +73,12 @@ pub fn is_abstract(model: &SemanticModel, decorator_list: &[Decorator]) -> bool /// `extra_properties` can be used to check additional non-standard /// `@property`-like decorators. pub fn is_property( - model: &SemanticModel, decorator_list: &[Decorator], extra_properties: &[CallPath], + semantic: &SemanticModel, ) -> bool { decorator_list.iter().any(|decorator| { - model + semantic .resolve_call_path(map_callable(&decorator.expression)) .map_or(false, |call_path| { call_path.as_slice() == ["", "property"] @@ -91,10 +91,10 @@ pub fn is_property( } /// Returns `true` if a class is an `final`. -pub fn is_final(model: &SemanticModel, decorator_list: &[Decorator]) -> bool { +pub fn is_final(decorator_list: &[Decorator], semantic: &SemanticModel) -> bool { decorator_list .iter() - .any(|decorator| model.match_typing_expr(map_callable(&decorator.expression), "final")) + .any(|decorator| semantic.match_typing_expr(map_callable(&decorator.expression), "final")) } /// Returns `true` if a function is a "magic method". diff --git a/crates/ruff_python_semantic/src/binding.rs b/crates/ruff_python_semantic/src/binding.rs index d9fd471b41..b390362ae8 100644 --- a/crates/ruff_python_semantic/src/binding.rs +++ b/crates/ruff_python_semantic/src/binding.rs @@ -142,11 +142,11 @@ impl<'a> Binding<'a> { } /// Returns the appropriate visual range for highlighting this binding. - pub fn trimmed_range(&self, semantic_model: &SemanticModel, locator: &Locator) -> TextRange { + pub fn trimmed_range(&self, semantic: &SemanticModel, locator: &Locator) -> TextRange { match self.kind { BindingKind::ClassDefinition | BindingKind::FunctionDefinition => { self.source.map_or(self.range, |source| { - helpers::identifier_range(semantic_model.stmts[source], locator) + helpers::identifier_range(semantic.stmts[source], locator) }) } _ => self.range, @@ -154,9 +154,9 @@ impl<'a> Binding<'a> { } /// Returns the range of the binding's parent. - pub fn parent_range(&self, semantic_model: &SemanticModel) -> Option { + pub fn parent_range(&self, semantic: &SemanticModel) -> Option { self.source - .map(|node_id| semantic_model.stmts[node_id]) + .map(|node_id| semantic.stmts[node_id]) .and_then(|parent| { if parent.is_import_from_stmt() { Some(parent.range())