Compile module-level __annotate__ function (PEP 649) Returns true if __annotate__ was created and stored
(&mut self, body: &[ast::Stmt])
| 4299 | /// Compile module-level __annotate__ function (PEP 649) |
| 4300 | /// Returns true if __annotate__ was created and stored |
| 4301 | fn compile_module_annotate(&mut self, body: &[ast::Stmt]) -> CompileResult<bool> { |
| 4302 | // Collect simple annotations from module body first |
| 4303 | let annotations = Self::collect_simple_annotations(body); |
| 4304 | |
| 4305 | if annotations.is_empty() { |
| 4306 | return Ok(false); |
| 4307 | } |
| 4308 | |
| 4309 | // Check if we have conditional annotations |
| 4310 | let has_conditional = self.current_symbol_table().has_conditional_annotations; |
| 4311 | |
| 4312 | // Get parent scope type BEFORE pushing annotation symbol table |
| 4313 | let parent_scope_type = self.current_symbol_table().typ; |
| 4314 | // Try to push annotation symbol table from current scope |
| 4315 | if !self.push_current_annotation_symbol_table() { |
| 4316 | return Ok(false); |
| 4317 | } |
| 4318 | |
| 4319 | // Annotation scopes are never async (even inside async functions) |
| 4320 | let saved_ctx = self.ctx; |
| 4321 | self.ctx = CompileContext { |
| 4322 | loop_data: None, |
| 4323 | in_class: saved_ctx.in_class, |
| 4324 | func: FunctionContext::Function, |
| 4325 | in_async_scope: false, |
| 4326 | }; |
| 4327 | |
| 4328 | // Enter annotation scope for code generation |
| 4329 | let key = self.symbol_table_stack.len() - 1; |
| 4330 | let lineno = self.get_source_line_number().get(); |
| 4331 | self.enter_scope( |
| 4332 | "__annotate__", |
| 4333 | CompilerScope::Annotation, |
| 4334 | key, |
| 4335 | lineno.to_u32(), |
| 4336 | )?; |
| 4337 | |
| 4338 | // Add 'format' parameter to varnames |
| 4339 | self.current_code_info() |
| 4340 | .metadata |
| 4341 | .varnames |
| 4342 | .insert("format".to_owned()); |
| 4343 | |
| 4344 | // Emit format validation: if format > VALUE_WITH_FAKE_GLOBALS: raise NotImplementedError |
| 4345 | self.emit_format_validation()?; |
| 4346 | |
| 4347 | if has_conditional { |
| 4348 | // PEP 649: Build dict incrementally, checking conditional annotations |
| 4349 | // Start with empty dict |
| 4350 | emit!(self, Instruction::BuildMap { count: 0 }); |
| 4351 | |
| 4352 | // Process each annotation |
| 4353 | for (idx, (name, annotation)) in annotations.iter().enumerate() { |
| 4354 | // Check if index is in __conditional_annotations__ |
| 4355 | let not_set_block = self.new_block(); |
| 4356 | |
| 4357 | // LOAD_CONST index |
| 4358 | self.emit_load_const(ConstantData::Integer { value: idx.into() }); |
no test coverage detected