(zelf: &Py<Self>, vm: &VirtualMachine)
| 346 | |
| 347 | #[pygetset] |
| 348 | fn __annotations__(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> { |
| 349 | let dict = zelf.dict(); |
| 350 | |
| 351 | // Check if __annotations__ is already in dict (explicitly set) |
| 352 | if let Some(annotations) = dict.get_item_opt(identifier!(vm, __annotations__), vm)? { |
| 353 | return Ok(annotations); |
| 354 | } |
| 355 | |
| 356 | // Check if module is initializing |
| 357 | let is_initializing = Self::is_initializing(&dict, vm); |
| 358 | |
| 359 | // PEP 649: Get __annotate__ and call it if callable |
| 360 | let annotations = if let Some(annotate) = |
| 361 | dict.get_item_opt(identifier!(vm, __annotate__), vm)? |
| 362 | && annotate.is_callable() |
| 363 | { |
| 364 | // Call __annotate__(1) where 1 is FORMAT_VALUE |
| 365 | let result = annotate.call((1i32,), vm)?; |
| 366 | if !result.class().is(vm.ctx.types.dict_type) { |
| 367 | return Err(vm.new_type_error(format!( |
| 368 | "__annotate__ returned non-dict of type '{}'", |
| 369 | result.class().name() |
| 370 | ))); |
| 371 | } |
| 372 | result |
| 373 | } else { |
| 374 | vm.ctx.new_dict().into() |
| 375 | }; |
| 376 | |
| 377 | // Cache result unless module is initializing |
| 378 | if !is_initializing { |
| 379 | dict.set_item(identifier!(vm, __annotations__), annotations.clone(), vm)?; |
| 380 | } |
| 381 | |
| 382 | Ok(annotations) |
| 383 | } |
| 384 | |
| 385 | /// Check if module is initializing via __spec__._initializing |
| 386 | fn is_initializing(dict: &PyDictRef, vm: &VirtualMachine) -> bool { |
nothing calls this directly
no test coverage detected