From f53c68695d18a5fbd0a70623130acc5000246bd4 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Fri, 24 Feb 2023 13:24:44 +0900 Subject: [PATCH 1/2] Add __origname__ to frozenlibs to fix importlib --- vm/build.rs | 9 +++++++-- vm/src/import.rs | 17 +++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/vm/build.rs b/vm/build.rs index b04482f8de..063153f6e7 100644 --- a/vm/build.rs +++ b/vm/build.rs @@ -2,11 +2,16 @@ use itertools::Itertools; use std::{env, io::prelude::*, path::PathBuf, process::Command}; fn main() { - #[cfg(feature = "freeze-stdlib")] - for entry in glob::glob("Lib/*/*.py").expect("Lib/ exists?").flatten() { + let frozen_libs = if cfg!(feature = "freeze-stdlib") { + "Lib/*/*.py" + } else { + "Lib/python_builtins/*.py" + }; + for entry in glob::glob(frozen_libs).expect("Lib/ exists?").flatten() { let display = entry.display(); println!("cargo:rerun-if-changed={display}"); } + println!("cargo:rerun-if-changed=../Lib/importlib/_bootstrap.py"); println!("cargo:rustc-env=RUSTPYTHON_GIT_HASH={}", git_hash()); println!( diff --git a/vm/src/import.rs b/vm/src/import.rs index 2487908e54..855f829e52 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -21,11 +21,11 @@ pub(crate) fn init_importlib_base(vm: &mut VirtualMachine) -> PyResult PyResult> { } pub fn import_frozen(vm: &VirtualMachine, module_name: &str) -> PyResult { - make_frozen(vm, module_name).and_then(|frozen| import_codeobj(vm, module_name, frozen, false)) + make_frozen(vm, module_name).and_then(|frozen| { + let module = import_codeobj(vm, module_name, frozen, false)?; + // TODO: give a correct origname here + module.set_attr("__origname__", vm.ctx.new_str(module_name.to_owned()), vm)?; + Ok(module) + }) } pub fn import_builtin(vm: &VirtualMachine, module_name: &str) -> PyResult { From 10de265b4f4c07a1faca60144cfa2e8cfc6f8208 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Fri, 24 Feb 2023 14:06:23 +0900 Subject: [PATCH 2/2] Add basic _imp.find_frozen --- .cspell.json | 1 + vm/src/import.rs | 2 +- vm/src/stdlib/imp.rs | 58 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/.cspell.json b/.cspell.json index f1b9b7f6d7..ef9daa60d4 100644 --- a/.cspell.json +++ b/.cspell.json @@ -65,6 +65,7 @@ "PYTHONWARNINGS", "basicsize", "itemsize", + "origname", "getattro", "setattro", "iternext", diff --git a/vm/src/import.rs b/vm/src/import.rs index 855f829e52..9fc8e56ea4 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -24,7 +24,7 @@ pub(crate) fn init_importlib_base(vm: &mut VirtualMachine) -> PyResult PyObjectRef { let module = _imp::make_module(vm); @@ -48,10 +48,40 @@ mod lock { } } +#[allow(dead_code)] +enum FrozenError { + BadName, // The given module name wasn't valid. + NotFound, // It wasn't in PyImport_FrozenModules. + Disabled, // -X frozen_modules=off (and not essential) + Excluded, // The PyImport_FrozenModules entry has NULL "code" + // (module is present but marked as unimportable, stops search). + Invalid, // The PyImport_FrozenModules entry is bogus + // (eg. does not contain executable code). +} + +impl FrozenError { + fn to_pyexception(&self, mod_name: &str, vm: &VirtualMachine) -> PyBaseExceptionRef { + use FrozenError::*; + let msg = match self { + BadName | NotFound => format!("No such frozen object named {mod_name}"), + Disabled => format!("Frozen modules are disabled and the frozen object named {mod_name} is not essential"), + Excluded => format!("Excluded frozen object named {mod_name}"), + Invalid => format!("Frozen object named {mod_name} is invalid"), + }; + vm.new_import_error(msg, mod_name) + } +} + +// find_frozen in frozen.c +fn find_frozen<'a>(name: &str, vm: &'a VirtualMachine) -> Result<&'a FrozenModule, FrozenError> { + vm.state.frozen.get(name).ok_or(FrozenError::NotFound) +} + #[pymodule] mod _imp { use crate::{ - builtins::{PyBytesRef, PyCode, PyModule, PyStrRef}, + builtins::{PyBytesRef, PyCode, PyMemoryView, PyModule, PyStrRef}, + function::OptionalArg, import, PyObjectRef, PyRef, PyResult, TryFromObject, VirtualMachine, }; @@ -126,6 +156,30 @@ mod _imp { // TODO: } + #[allow(clippy::type_complexity)] + #[pyfunction] + fn find_frozen( + name: PyStrRef, + withdata: OptionalArg, + vm: &VirtualMachine, + ) -> PyResult>, bool, PyStrRef)>> { + use super::FrozenError::*; + + if withdata.into_option().is_some() { + // this is keyword-only argument in CPython + unimplemented!(); + } + + let info = match super::find_frozen(name.as_str(), vm) { + Ok(info) => info, + Err(NotFound | Disabled | BadName) => return Ok(None), + Err(e) => return Err(e.to_pyexception(name.as_str(), vm)), + }; + + let origname = name; // FIXME: origname != name + Ok(Some((None, info.package, origname))) + } + #[pyfunction] fn source_hash(key: u64, source: PyBytesRef) -> Vec { let hash: u64 = crate::common::hash::keyed_hash(key, source.as_bytes());