Skip to content

Commit f532742

Browse files
committed
Add basic _imp.find_frozen
1 parent f53c686 commit f532742

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

.cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"PYTHONWARNINGS",
6666
"basicsize",
6767
"itemsize",
68+
"origname",
6869
"getattro",
6970
"setattro",
7071
"iternext",

vm/src/stdlib/imp.rs

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{PyObjectRef, VirtualMachine};
1+
use crate::{builtins::PyBaseExceptionRef, bytecode::FrozenModule, PyObjectRef, VirtualMachine};
22

33
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
44
let module = _imp::make_module(vm);
@@ -48,10 +48,40 @@ mod lock {
4848
}
4949
}
5050

51+
#[allow(dead_code)]
52+
enum FrozenError {
53+
BadName, // The given module name wasn't valid.
54+
NotFound, // It wasn't in PyImport_FrozenModules.
55+
Disabled, // -X frozen_modules=off (and not essential)
56+
Excluded, // The PyImport_FrozenModules entry has NULL "code"
57+
// (module is present but marked as unimportable, stops search).
58+
Invalid, // The PyImport_FrozenModules entry is bogus
59+
// (eg. does not contain executable code).
60+
}
61+
62+
impl FrozenError {
63+
fn to_pyexception(&self, mod_name: &str, vm: &VirtualMachine) -> PyBaseExceptionRef {
64+
use FrozenError::*;
65+
let msg = match self {
66+
BadName | NotFound => format!("No such frozen object named {mod_name}"),
67+
Disabled => format!("Frozen modules are disabled and the frozen object named {mod_name} is not essential"),
68+
Excluded => format!("Excluded frozen object named {mod_name}"),
69+
Invalid => format!("Frozen object named {mod_name} is invalid"),
70+
};
71+
vm.new_import_error(msg, mod_name)
72+
}
73+
}
74+
75+
// find_frozen in frozen.c
76+
fn find_frozen<'a>(name: &str, vm: &'a VirtualMachine) -> Result<&'a FrozenModule, FrozenError> {
77+
vm.state.frozen.get(name).ok_or(FrozenError::NotFound)
78+
}
79+
5180
#[pymodule]
5281
mod _imp {
5382
use crate::{
54-
builtins::{PyBytesRef, PyCode, PyModule, PyStrRef},
83+
builtins::{PyBytesRef, PyCode, PyMemoryView, PyModule, PyStrRef},
84+
function::OptionalArg,
5585
import, PyObjectRef, PyRef, PyResult, TryFromObject, VirtualMachine,
5686
};
5787

@@ -126,6 +156,29 @@ mod _imp {
126156
// TODO:
127157
}
128158

159+
#[pyfunction]
160+
fn find_frozen(
161+
name: PyStrRef,
162+
withdata: OptionalArg<bool>,
163+
vm: &VirtualMachine,
164+
) -> PyResult<Option<(Option<PyRef<PyMemoryView>>, bool, PyStrRef)>> {
165+
use super::FrozenError::*;
166+
167+
if withdata.into_option().is_some() {
168+
// this is keyword-only argument in CPython
169+
unimplemented!();
170+
}
171+
172+
let info = match super::find_frozen(name.as_str(), vm) {
173+
Ok(info) => info,
174+
Err(NotFound | Disabled | BadName) => return Ok(None),
175+
Err(e) => return Err(e.to_pyexception(name.as_str(), vm)),
176+
};
177+
178+
let origname = name; // FIXME: origname != name
179+
Ok(Some((None, info.package, origname)))
180+
}
181+
129182
#[pyfunction]
130183
fn source_hash(key: u64, source: PyBytesRef) -> Vec<u8> {
131184
let hash: u64 = crate::common::hash::keyed_hash(key, source.as_bytes());

0 commit comments

Comments
 (0)