From 2fa508793f74488bea34811b2f5a574a5766c22b Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Thu, 3 Aug 2023 12:21:55 -0400 Subject: [PATCH] Return a slice in `StmtClassDef#bases` (#6311) Slices are strictly more flexible, since you can always convert to an iterator, etc., but not the other way around. Suggested in https://github.com/astral-sh/ruff/pull/6259#discussion_r1282730994. --- .../rules/builtin_attribute_shadowing.rs | 1 + .../flake8_pie/rules/non_unique_enums.rs | 2 +- .../rules/unused_private_type_definition.rs | 2 ++ .../src/rules/flake8_type_checking/helpers.rs | 2 +- crates/ruff_python_ast/src/nodes.rs | 22 +++++++++---------- .../src/analyze/function_type.rs | 2 +- 6 files changed, 16 insertions(+), 15 deletions(-) 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 a2e7347a1bdd4..271bc997ce8d5 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 @@ -79,6 +79,7 @@ pub(crate) fn builtin_attribute_shadowing( // subscripting and not through attribute access. if class_def .bases() + .iter() .any(|base| checker.semantic().match_typing_expr(base, "TypedDict")) { return; 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 1ce7512c453d0..7603fa3d44bd1 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 @@ -58,7 +58,7 @@ pub(crate) fn non_unique_enums(checker: &mut Checker, parent: &Stmt, body: &[Stm return; }; - if !parent.bases().any(|expr| { + if !parent.bases().iter().any(|expr| { checker .semantic() .resolve_call_path(expr) diff --git a/crates/ruff/src/rules/flake8_pyi/rules/unused_private_type_definition.rs b/crates/ruff/src/rules/flake8_pyi/rules/unused_private_type_definition.rs index ddd57f9ccb7f7..01d93b90e72ed 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/unused_private_type_definition.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/unused_private_type_definition.rs @@ -223,6 +223,7 @@ pub(crate) fn unused_private_protocol( if !class_def .bases() + .iter() .any(|base| checker.semantic().match_typing_expr(base, "Protocol")) { continue; @@ -309,6 +310,7 @@ pub(crate) fn unused_private_typed_dict( if !class_def .bases() + .iter() .any(|base| checker.semantic().match_typing_expr(base, "TypedDict")) { continue; diff --git a/crates/ruff/src/rules/flake8_type_checking/helpers.rs b/crates/ruff/src/rules/flake8_type_checking/helpers.rs index fa25bd0f13861..001b7f258207f 100644 --- a/crates/ruff/src/rules/flake8_type_checking/helpers.rs +++ b/crates/ruff/src/rules/flake8_type_checking/helpers.rs @@ -39,7 +39,7 @@ fn runtime_evaluated_base_class(base_classes: &[String], semantic: &SemanticMode return false; }; - class_def.bases().any(|base| { + class_def.bases().iter().any(|base| { semantic.resolve_call_path(base).is_some_and(|call_path| { base_classes .iter() diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 1928c0a372f15..7ed613913f5a2 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -167,21 +167,19 @@ pub struct StmtClassDef { impl StmtClassDef { /// Return an iterator over the bases of the class. - pub fn bases(&self) -> impl Iterator { - self.arguments - .as_ref() - .map(|arguments| &arguments.args) - .into_iter() - .flatten() + pub fn bases(&self) -> &[Expr] { + match &self.arguments { + Some(arguments) => &arguments.args, + None => &[], + } } /// Return an iterator over the metaclass keywords of the class. - pub fn keywords(&self) -> impl Iterator { - self.arguments - .as_ref() - .map(|arguments| &arguments.keywords) - .into_iter() - .flatten() + pub fn keywords(&self) -> &[Keyword] { + match &self.arguments { + Some(arguments) => &arguments.keywords, + None => &[], + } } } diff --git a/crates/ruff_python_semantic/src/analyze/function_type.rs b/crates/ruff_python_semantic/src/analyze/function_type.rs index 22e6e22425964..8289eb26fd68c 100644 --- a/crates/ruff_python_semantic/src/analyze/function_type.rs +++ b/crates/ruff_python_semantic/src/analyze/function_type.rs @@ -42,7 +42,7 @@ pub fn classify( FunctionType::StaticMethod } else if matches!(name, "__new__" | "__init_subclass__" | "__class_getitem__") // Special-case class method, like `__new__`. - || class_def.bases().any(|expr| { + || class_def.bases().iter().any(|expr| { // The class itself extends a known metaclass, so all methods are class methods. semantic .resolve_call_path(map_callable(expr))