rustpython_vm/stdlib/
imp.rs1use crate::frozen::FrozenModule;
2use crate::{builtins::PyBaseExceptionRef, VirtualMachine};
3pub(crate) use _imp::make_module;
4
5#[cfg(feature = "threading")]
6#[pymodule(sub)]
7mod lock {
8 use crate::{stdlib::thread::RawRMutex, PyResult, VirtualMachine};
9
10 static IMP_LOCK: RawRMutex = RawRMutex::INIT;
11
12 #[pyfunction]
13 fn acquire_lock(_vm: &VirtualMachine) {
14 IMP_LOCK.lock()
15 }
16
17 #[pyfunction]
18 fn release_lock(vm: &VirtualMachine) -> PyResult<()> {
19 if !IMP_LOCK.is_locked() {
20 Err(vm.new_runtime_error("Global import lock not held".to_owned()))
21 } else {
22 unsafe { IMP_LOCK.unlock() };
23 Ok(())
24 }
25 }
26
27 #[pyfunction]
28 fn lock_held(_vm: &VirtualMachine) -> bool {
29 IMP_LOCK.is_locked()
30 }
31}
32
33#[cfg(not(feature = "threading"))]
34#[pymodule(sub)]
35mod lock {
36 use crate::vm::VirtualMachine;
37 #[pyfunction]
38 pub(super) fn acquire_lock(_vm: &VirtualMachine) {}
39 #[pyfunction]
40 pub(super) fn release_lock(_vm: &VirtualMachine) {}
41 #[pyfunction]
42 pub(super) fn lock_held(_vm: &VirtualMachine) -> bool {
43 false
44 }
45}
46
47#[allow(dead_code)]
48enum FrozenError {
49 BadName, NotFound, Disabled, Excluded, Invalid, }
57
58impl FrozenError {
59 fn to_pyexception(&self, mod_name: &str, vm: &VirtualMachine) -> PyBaseExceptionRef {
60 use FrozenError::*;
61 let msg = match self {
62 BadName | NotFound => format!("No such frozen object named {mod_name}"),
63 Disabled => format!("Frozen modules are disabled and the frozen object named {mod_name} is not essential"),
64 Excluded => format!("Excluded frozen object named {mod_name}"),
65 Invalid => format!("Frozen object named {mod_name} is invalid"),
66 };
67 vm.new_import_error(msg, vm.ctx.new_str(mod_name))
68 }
69}
70
71fn find_frozen(name: &str, vm: &VirtualMachine) -> Result<FrozenModule, FrozenError> {
73 vm.state
74 .frozen
75 .get(name)
76 .copied()
77 .ok_or(FrozenError::NotFound)
78}
79
80#[pymodule(with(lock))]
81mod _imp {
82 use crate::{
83 builtins::{PyBytesRef, PyCode, PyMemoryView, PyModule, PyStrRef},
84 function::OptionalArg,
85 import, PyObjectRef, PyRef, PyResult, VirtualMachine,
86 };
87
88 #[pyattr]
89 fn check_hash_based_pycs(vm: &VirtualMachine) -> PyStrRef {
90 vm.ctx
91 .new_str(vm.state.settings.check_hash_pycs_mode.clone())
92 }
93
94 #[pyfunction]
95 fn extension_suffixes() -> PyResult<Vec<PyObjectRef>> {
96 Ok(Vec::new())
97 }
98
99 #[pyfunction]
100 fn is_builtin(name: PyStrRef, vm: &VirtualMachine) -> bool {
101 vm.state.module_inits.contains_key(name.as_str())
102 }
103
104 #[pyfunction]
105 fn is_frozen(name: PyStrRef, vm: &VirtualMachine) -> bool {
106 vm.state.frozen.contains_key(name.as_str())
107 }
108
109 #[pyfunction]
110 fn create_builtin(spec: PyObjectRef, vm: &VirtualMachine) -> PyResult {
111 let sys_modules = vm.sys_module.get_attr("modules", vm).unwrap();
112 let name: PyStrRef = spec.get_attr("name", vm)?.try_into_value(vm)?;
113
114 let module = if let Ok(module) = sys_modules.get_item(&*name, vm) {
115 module
116 } else if let Some(make_module_func) = vm.state.module_inits.get(name.as_str()) {
117 make_module_func(vm).into()
118 } else {
119 vm.ctx.none()
120 };
121 Ok(module)
122 }
123
124 #[pyfunction]
125 fn exec_builtin(_mod: PyRef<PyModule>) -> i32 {
126 0
128 }
129
130 #[pyfunction]
131 fn get_frozen_object(name: PyStrRef, vm: &VirtualMachine) -> PyResult<PyRef<PyCode>> {
132 import::make_frozen(vm, name.as_str())
133 }
134
135 #[pyfunction]
136 fn init_frozen(name: PyStrRef, vm: &VirtualMachine) -> PyResult {
137 import::import_frozen(vm, name.as_str())
138 }
139
140 #[pyfunction]
141 fn is_frozen_package(name: PyStrRef, vm: &VirtualMachine) -> PyResult<bool> {
142 super::find_frozen(name.as_str(), vm)
143 .map(|frozen| frozen.package)
144 .map_err(|e| e.to_pyexception(name.as_str(), vm))
145 }
146
147 #[pyfunction]
148 fn _override_frozen_modules_for_tests(value: isize, vm: &VirtualMachine) {
149 vm.state.override_frozen_modules.store(value);
150 }
151
152 #[pyfunction]
153 fn _fix_co_filename(_code: PyObjectRef, _path: PyStrRef) {
154 }
156
157 #[pyfunction]
158 fn _frozen_module_names(vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
159 let names = vm
160 .state
161 .frozen
162 .keys()
163 .map(|&name| vm.ctx.new_str(name).into())
164 .collect();
165 Ok(names)
166 }
167
168 #[allow(clippy::type_complexity)]
169 #[pyfunction]
170 fn find_frozen(
171 name: PyStrRef,
172 withdata: OptionalArg<bool>,
173 vm: &VirtualMachine,
174 ) -> PyResult<Option<(Option<PyRef<PyMemoryView>>, bool, PyStrRef)>> {
175 use super::FrozenError::*;
176
177 if withdata.into_option().is_some() {
178 unimplemented!();
180 }
181
182 let info = match super::find_frozen(name.as_str(), vm) {
183 Ok(info) => info,
184 Err(NotFound | Disabled | BadName) => return Ok(None),
185 Err(e) => return Err(e.to_pyexception(name.as_str(), vm)),
186 };
187
188 let origname = name; Ok(Some((None, info.package, origname)))
190 }
191
192 #[pyfunction]
193 fn source_hash(key: u64, source: PyBytesRef) -> Vec<u8> {
194 let hash: u64 = crate::common::hash::keyed_hash(key, source.as_bytes());
195 hash.to_le_bytes().to_vec()
196 }
197}