handle type annotations in nested functions correctly (#7072)

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': <class 'int'>, 'y': <class 'float'>}

Previously annotations where 'lost', and we would get:

    >>>>> foo.__annotations__
    {}
This commit is contained in:
Elmir
2026-02-10 16:08:57 +01:00
committed by GitHub
parent 23cf16a283
commit fde808e663
2 changed files with 4 additions and 2 deletions

View File

@@ -6707,7 +6707,6 @@ class GetTypeHintsTests(BaseTestCase):
'default_b': Optional[mod_generics_cache.B]}
self.assertEqual(gth(mod_generics_cache), mgc_hints)
@unittest.expectedFailure # TODO: RUSTPYTHON; + {'x': <class 'int'>}
def test_get_type_hints_classes(self):
self.assertEqual(gth(ann_module.C), # gth will find the right globalns
{'y': Optional[ann_module.C]})

View File

@@ -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()