From 2c83511bd68579e41f42c197b2105898aa7ab334 Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Tue, 10 Feb 2026 14:50:32 +0100 Subject: [PATCH] handle type annotations in nested functions correctly For example in the following code: def foo(x: int, y: float): def bar(q: int): return q pass Make sure that `foo` type annotations are correctly propogated to it's `__annotate__` and `__annotations__` attributes. With this chage, we'll get: >>>>> foo.__annotations__ {'x': , 'y': } Previously annotations where 'lost', and we would get: >>>>> foo.__annotations__ {} --- Lib/test/test_typing.py | 1 - crates/codegen/src/symboltable.rs | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 0a3e57d34c6..3372312c6d8 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -6707,7 +6707,6 @@ def test_get_type_hints_modules_forwardref(self): 'default_b': Optional[mod_generics_cache.B]} self.assertEqual(gth(mod_generics_cache), mgc_hints) - @unittest.expectedFailure # TODO: RUSTPYTHON; + {'x': } def test_get_type_hints_classes(self): self.assertEqual(gth(ann_module.C), # gth will find the right globalns {'y': Optional[ann_module.C]}) diff --git a/crates/codegen/src/symboltable.rs b/crates/codegen/src/symboltable.rs index b175e40d487..4862c25b8b6 100644 --- a/crates/codegen/src/symboltable.rs +++ b/crates/codegen/src/symboltable.rs @@ -1136,7 +1136,10 @@ impl SymbolTableBuilder { let parent_scope_typ = self.tables.last().map(|t| t.typ); let should_save_annotation_block = matches!( parent_scope_typ, - Some(CompilerScope::Class) | Some(CompilerScope::Module) + Some(CompilerScope::Class) + | Some(CompilerScope::Module) + | Some(CompilerScope::Function) + | Some(CompilerScope::AsyncFunction) ); let saved_annotation_block = if should_save_annotation_block { self.tables.last_mut().unwrap().annotation_block.take()