Compile function annotations as a closure (PEP 649) Returns true if an __annotate__ closure was created Uses symbol table's annotation_block for proper scoping.
(
&mut self,
func_name: &str,
parameters: &ast::Parameters,
returns: Option<&ast::Expr>,
)
| 4163 | /// Returns true if an __annotate__ closure was created |
| 4164 | /// Uses symbol table's annotation_block for proper scoping. |
| 4165 | fn compile_annotations_closure( |
| 4166 | &mut self, |
| 4167 | func_name: &str, |
| 4168 | parameters: &ast::Parameters, |
| 4169 | returns: Option<&ast::Expr>, |
| 4170 | ) -> CompileResult<bool> { |
| 4171 | // Try to enter annotation scope - returns None if no annotation_block exists |
| 4172 | let Some(saved_ctx) = self.enter_annotation_scope(func_name)? else { |
| 4173 | return Ok(false); |
| 4174 | }; |
| 4175 | |
| 4176 | // Count annotations |
| 4177 | let parameters_iter = core::iter::empty() |
| 4178 | .chain(¶meters.posonlyargs) |
| 4179 | .chain(¶meters.args) |
| 4180 | .chain(¶meters.kwonlyargs) |
| 4181 | .map(|x| &x.parameter) |
| 4182 | .chain(parameters.vararg.as_deref()) |
| 4183 | .chain(parameters.kwarg.as_deref()); |
| 4184 | |
| 4185 | let num_annotations: u32 = |
| 4186 | u32::try_from(parameters_iter.filter(|p| p.annotation.is_some()).count()) |
| 4187 | .expect("too many annotations") |
| 4188 | + if returns.is_some() { 1 } else { 0 }; |
| 4189 | |
| 4190 | // Compile annotations inside the annotation scope |
| 4191 | let parameters_iter = core::iter::empty() |
| 4192 | .chain(¶meters.posonlyargs) |
| 4193 | .chain(¶meters.args) |
| 4194 | .chain(¶meters.kwonlyargs) |
| 4195 | .map(|x| &x.parameter) |
| 4196 | .chain(parameters.vararg.as_deref()) |
| 4197 | .chain(parameters.kwarg.as_deref()); |
| 4198 | |
| 4199 | for param in parameters_iter { |
| 4200 | if let Some(annotation) = ¶m.annotation { |
| 4201 | self.emit_load_const(ConstantData::Str { |
| 4202 | value: self.mangle(param.name.as_str()).into_owned().into(), |
| 4203 | }); |
| 4204 | self.compile_annotation(annotation)?; |
| 4205 | } |
| 4206 | } |
| 4207 | |
| 4208 | // Handle return annotation |
| 4209 | if let Some(annotation) = returns { |
| 4210 | self.emit_load_const(ConstantData::Str { |
| 4211 | value: "return".into(), |
| 4212 | }); |
| 4213 | self.compile_annotation(annotation)?; |
| 4214 | } |
| 4215 | |
| 4216 | // Build the map and return it |
| 4217 | emit!( |
| 4218 | self, |
| 4219 | Instruction::BuildMap { |
| 4220 | count: num_annotations, |
| 4221 | } |
| 4222 | ); |
no test coverage detected