mirror of https://github.com/astral-sh/ruff
Tweak interfaces to take Context
This commit is contained in:
parent
b307200e42
commit
5afe4bf711
|
|
@ -2084,17 +2084,30 @@ 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 = (!self.ctx.annotations_future_enabled
|
||||
&& matches!(
|
||||
let runtime_annotation = if self.ctx.annotations_future_enabled {
|
||||
if matches!(self.ctx.current_scope().kind, ScopeKind::Class(..)) {
|
||||
let baseclasses = &self
|
||||
.settings
|
||||
.flake8_type_checking
|
||||
.runtime_evaluated_baseclasses;
|
||||
let decorators = &self
|
||||
.settings
|
||||
.flake8_type_checking
|
||||
.runtime_evaluated_decorators;
|
||||
flake8_type_checking::helpers::runtime_evaluated(
|
||||
&self.ctx,
|
||||
baseclasses,
|
||||
decorators,
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
matches!(
|
||||
self.ctx.current_scope().kind,
|
||||
ScopeKind::Class(..) | ScopeKind::Module
|
||||
))
|
||||
|| (self.ctx.annotations_future_enabled
|
||||
&& matches!(self.current_scope().kind, ScopeKind::Class(..))
|
||||
&& flake8_type_checking::helpers::runtime_evaluated(
|
||||
self,
|
||||
self.current_scope(),
|
||||
));
|
||||
)
|
||||
};
|
||||
|
||||
if runtime_annotation {
|
||||
visit_type_definition!(self, annotation);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use num_traits::Zero;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind};
|
||||
|
||||
use crate::ast::context::Context;
|
||||
use crate::ast::helpers::{map_callable, to_call_path};
|
||||
use crate::ast::types::{Binding, BindingKind, ExecutionContext, Scope, ScopeKind};
|
||||
use crate::ast::types::{Binding, BindingKind, ExecutionContext, ScopeKind};
|
||||
use crate::checkers::ast::Checker;
|
||||
|
||||
/// Return `true` if [`Expr`] is a guard for a type-checking block.
|
||||
|
|
@ -56,18 +57,29 @@ pub const fn is_valid_runtime_import(binding: &Binding) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn runtime_evaluated(checker: &Checker, scope: &Scope) -> bool {
|
||||
runtime_evaluated_due_to_baseclass(checker, scope)
|
||||
|| runtime_evaluated_due_to_decorator(checker, scope)
|
||||
pub fn runtime_evaluated(
|
||||
context: &Context,
|
||||
base_classes: &[String],
|
||||
decorators: &[String],
|
||||
) -> bool {
|
||||
if !base_classes.is_empty() {
|
||||
if runtime_evaluated_baseclass(context, base_classes) {
|
||||
return true;
|
||||
}
|
||||
pub fn runtime_evaluated_due_to_baseclass(checker: &Checker, scope: &Scope) -> bool {
|
||||
if let ScopeKind::Class(def) = &scope.kind {
|
||||
for base_class in def.bases.iter() {
|
||||
if let Some(call_path) = checker.resolve_call_path(map_callable(base_class)) {
|
||||
if checker
|
||||
.settings
|
||||
.flake8_type_checking
|
||||
.runtime_evaluated_baseclasses
|
||||
}
|
||||
if !decorators.is_empty() {
|
||||
if runtime_evaluated_decorators(context, decorators) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn runtime_evaluated_baseclass(context: &Context, base_classes: &[String]) -> bool {
|
||||
if let ScopeKind::Class(class_def) = &context.current_scope().kind {
|
||||
for base in class_def.bases.iter() {
|
||||
if let Some(call_path) = context.resolve_call_path(base) {
|
||||
if base_classes
|
||||
.iter()
|
||||
.any(|base_class| to_call_path(base_class) == call_path)
|
||||
{
|
||||
|
|
@ -78,14 +90,12 @@ pub fn runtime_evaluated_due_to_baseclass(checker: &Checker, scope: &Scope) -> b
|
|||
}
|
||||
false
|
||||
}
|
||||
pub fn runtime_evaluated_due_to_decorator(checker: &Checker, scope: &Scope) -> bool {
|
||||
if let ScopeKind::Class(def) = &scope.kind {
|
||||
for decorator in def.decorator_list.iter() {
|
||||
if let Some(call_path) = checker.resolve_call_path(map_callable(decorator)) {
|
||||
if checker
|
||||
.settings
|
||||
.flake8_type_checking
|
||||
.runtime_evaluated_decorators
|
||||
|
||||
fn runtime_evaluated_decorators(context: &Context, decorators: &[String]) -> bool {
|
||||
if let ScopeKind::Class(class_def) = &context.current_scope().kind {
|
||||
for decorator in class_def.decorator_list.iter() {
|
||||
if let Some(call_path) = context.resolve_call_path(map_callable(decorator)) {
|
||||
if decorators
|
||||
.iter()
|
||||
.any(|decorator| to_call_path(decorator) == call_path)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue