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
|
// If we're in a class or module scope, then the annotation needs to be
|
||||||
// available at runtime.
|
// available at runtime.
|
||||||
// See: https://docs.python.org/3/reference/simple_stmts.html#annotated-assignment-statements
|
// See: https://docs.python.org/3/reference/simple_stmts.html#annotated-assignment-statements
|
||||||
let runtime_annotation = (!self.ctx.annotations_future_enabled
|
let runtime_annotation = if self.ctx.annotations_future_enabled {
|
||||||
&& matches!(
|
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,
|
self.ctx.current_scope().kind,
|
||||||
ScopeKind::Class(..) | ScopeKind::Module
|
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 {
|
if runtime_annotation {
|
||||||
visit_type_definition!(self, annotation);
|
visit_type_definition!(self, annotation);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
use num_traits::Zero;
|
use num_traits::Zero;
|
||||||
use rustpython_parser::ast::{Constant, Expr, ExprKind};
|
use rustpython_parser::ast::{Constant, Expr, ExprKind};
|
||||||
|
|
||||||
|
use crate::ast::context::Context;
|
||||||
use crate::ast::helpers::{map_callable, to_call_path};
|
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;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
/// Return `true` if [`Expr`] is a guard for a type-checking block.
|
/// 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 {
|
pub fn runtime_evaluated(
|
||||||
runtime_evaluated_due_to_baseclass(checker, scope)
|
context: &Context,
|
||||||
|| runtime_evaluated_due_to_decorator(checker, scope)
|
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 {
|
if !decorators.is_empty() {
|
||||||
for base_class in def.bases.iter() {
|
if runtime_evaluated_decorators(context, decorators) {
|
||||||
if let Some(call_path) = checker.resolve_call_path(map_callable(base_class)) {
|
return true;
|
||||||
if checker
|
}
|
||||||
.settings
|
}
|
||||||
.flake8_type_checking
|
false
|
||||||
.runtime_evaluated_baseclasses
|
}
|
||||||
|
|
||||||
|
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()
|
.iter()
|
||||||
.any(|base_class| to_call_path(base_class) == call_path)
|
.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
|
false
|
||||||
}
|
}
|
||||||
pub fn runtime_evaluated_due_to_decorator(checker: &Checker, scope: &Scope) -> bool {
|
|
||||||
if let ScopeKind::Class(def) = &scope.kind {
|
fn runtime_evaluated_decorators(context: &Context, decorators: &[String]) -> bool {
|
||||||
for decorator in def.decorator_list.iter() {
|
if let ScopeKind::Class(class_def) = &context.current_scope().kind {
|
||||||
if let Some(call_path) = checker.resolve_call_path(map_callable(decorator)) {
|
for decorator in class_def.decorator_list.iter() {
|
||||||
if checker
|
if let Some(call_path) = context.resolve_call_path(map_callable(decorator)) {
|
||||||
.settings
|
if decorators
|
||||||
.flake8_type_checking
|
|
||||||
.runtime_evaluated_decorators
|
|
||||||
.iter()
|
.iter()
|
||||||
.any(|decorator| to_call_path(decorator) == call_path)
|
.any(|decorator| to_call_path(decorator) == call_path)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue