File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -5083,6 +5083,14 @@ impl<'warnings> Compiler<'warnings> {
50835083 func_range: TextRange,
50845084 ) -> CompileResult<bool> {
50855085 if !self.next_function_annotation_symbol_table_uses_annotations() {
5086+ // CPython creates a hidden AnnotationBlock for every function
5087+ // signature under `from __future__ import annotations`, including
5088+ // an unannotated one. It still belongs to this function: consume
5089+ // it so the next function sees its own block rather than remaining
5090+ // pinned to this unused entry.
5091+ if self.push_annotation_symbol_table() {
5092+ self.pop_annotation_symbol_table();
5093+ }
50865094 return Ok(false);
50875095 }
50885096
@@ -31247,6 +31255,25 @@ def f(x: T): pass
3124731255 );
3124831256 }
3124931257
31258+ #[test]
31259+ fn future_unannotated_function_does_not_hide_next_annotation_block() {
31260+ let code = compile_exec(
31261+ "\
31262+ from __future__ import annotations
31263+ def plain(x): pass
31264+ def annotated(x: int): pass
31265+ ",
31266+ );
31267+ let annotate = find_direct_child_code(&code, "__annotate__")
31268+ .expect("second function must retain its annotation closure");
31269+ assert!(
31270+ annotate.constants.iter().any(
31271+ |constant| matches!(constant, ConstantData::Str { value } if value.as_str() == Ok("int"))
31272+ ),
31273+ "annotation closure must belong to the annotated function"
31274+ );
31275+ }
31276+
3125031277 #[test]
3125131278 fn deferred_annotation_format_name_does_not_capture_helper_parameter() {
3125231279 let code = compile_exec(
You can’t perform that action at this time.
0 commit comments