(&mut self, vm: &VirtualMachine)
| 6268 | |
| 6269 | #[cfg_attr(feature = "flame-it", flame("Frame"))] |
| 6270 | fn import_star(&mut self, vm: &VirtualMachine) -> PyResult<()> { |
| 6271 | let module = self.pop_value(); |
| 6272 | |
| 6273 | let Some(dict) = module.dict() else { |
| 6274 | return Ok(()); |
| 6275 | }; |
| 6276 | |
| 6277 | let mod_name = module |
| 6278 | .get_attr(identifier!(vm, __name__), vm) |
| 6279 | .ok() |
| 6280 | .and_then(|n| n.downcast::<PyStr>().ok()); |
| 6281 | |
| 6282 | let require_str = |obj: PyObjectRef, attr: &str| -> PyResult<PyRef<PyStr>> { |
| 6283 | obj.downcast().map_err(|obj: PyObjectRef| { |
| 6284 | let source = if let Some(ref mod_name) = mod_name { |
| 6285 | format!("{}.{attr}", mod_name.as_wtf8()) |
| 6286 | } else { |
| 6287 | attr.to_owned() |
| 6288 | }; |
| 6289 | let repr = obj.repr(vm).unwrap_or_else(|_| vm.ctx.new_str("?")); |
| 6290 | vm.new_type_error(format!( |
| 6291 | "{} in {} must be str, not {}", |
| 6292 | repr.as_wtf8(), |
| 6293 | source, |
| 6294 | obj.class().name() |
| 6295 | )) |
| 6296 | }) |
| 6297 | }; |
| 6298 | |
| 6299 | let locals_map = self.locals.mapping(vm); |
| 6300 | if let Ok(all) = dict.get_item(identifier!(vm, __all__), vm) { |
| 6301 | let items: Vec<PyObjectRef> = all.try_to_value(vm)?; |
| 6302 | for item in items { |
| 6303 | let name = require_str(item, "__all__")?; |
| 6304 | let value = module.get_attr(&*name, vm)?; |
| 6305 | locals_map.ass_subscript(&name, Some(value), vm)?; |
| 6306 | } |
| 6307 | } else { |
| 6308 | for (k, v) in dict { |
| 6309 | let k = require_str(k, "__dict__")?; |
| 6310 | if !k.as_bytes().starts_with(b"_") { |
| 6311 | locals_map.ass_subscript(&k, Some(v), vm)?; |
| 6312 | } |
| 6313 | } |
| 6314 | } |
| 6315 | Ok(()) |
| 6316 | } |
| 6317 | |
| 6318 | /// Unwind blocks. |
| 6319 | /// The reason for unwinding gives a hint on what to do when |
no test coverage detected