From ee51c2a38980da2edc0558274d2d0da452ab35ea Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama <45118249+mtshiba@users.noreply.github.com> Date: Sun, 23 Mar 2025 22:23:12 +0900 Subject: [PATCH] [red-knot] fix ordering of `ClassDef` semantic index building (#16915) ## Summary From #16861 This PR fixes the incorrect `ClassDef` handling of `SemanticIndexBuilder::visit_stmt`, which fixes some of the incorrect behavior of referencing the class itself in the class scope (a complete fix requires a different fix, which will be done in the another PR). --------- Co-authored-by: Carl Meyer --- .../resources/mdtest/generics/classes.md | 3 ++- .../red_knot_python_semantic/src/semantic_index/builder.rs | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md b/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md index d7944b1369..d6f78f1fed 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md +++ b/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md @@ -183,8 +183,9 @@ In a non-stub file, without stringified forward references, this raises a `NameE ```py class Base[T]: ... -# TODO: error: [unresolved-reference] +# TODO: the unresolved-reference error is correct, the non-subscriptable is not # error: [non-subscriptable] +# error: [unresolved-reference] class Sub(Base[Sub]): ... ``` diff --git a/crates/red_knot_python_semantic/src/semantic_index/builder.rs b/crates/red_knot_python_semantic/src/semantic_index/builder.rs index d6cb15670f..0d6ecb8b00 100644 --- a/crates/red_knot_python_semantic/src/semantic_index/builder.rs +++ b/crates/red_knot_python_semantic/src/semantic_index/builder.rs @@ -926,9 +926,6 @@ where self.visit_decorator(decorator); } - let symbol = self.add_symbol(class.name.id.clone()); - self.add_definition(symbol, class); - self.with_type_params( NodeWithScopeRef::ClassTypeParameters(class), class.type_params.as_deref(), @@ -943,6 +940,10 @@ where builder.pop_scope() }, ); + + // In Python runtime semantics, a class is registered after its scope is evaluated. + let symbol = self.add_symbol(class.name.id.clone()); + self.add_definition(symbol, class); } ast::Stmt::TypeAlias(type_alias) => { let symbol = self.add_symbol(