Skip to content

Commit 00e461e

Browse files
authored
Merge pull request RustPython#3668 from youknowone/interpreter-default
Remove Interpreter::default to alert better there is no stdlib
2 parents 4c39668 + 6fd5094 commit 00e461e

File tree

18 files changed

+195
-187
lines changed

18 files changed

+195
-187
lines changed

benches/execution.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn bench_cpython_code(b: &mut Bencher, source: &str) {
2323

2424
fn bench_rustpy_code(b: &mut Bencher, name: &str, source: &str) {
2525
// NOTE: Take long time.
26-
Interpreter::default().enter(|vm| {
26+
Interpreter::without_stdlib(Default::default()).enter(|vm| {
2727
// Note: bench_cpython is both compiling and executing the code.
2828
// As such we compile the code in the benchmark loop as well.
2929
b.iter(|| {

benches/microbenchmarks.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use criterion::{
33
Criterion, Throughput,
44
};
55
use rustpython_compiler::Mode;
6-
use rustpython_vm::{common::ascii, InitParameter, Interpreter, PyResult, Settings};
6+
use rustpython_vm::{common::ascii, Interpreter, PyResult, Settings};
77
use std::{
88
ffi, fs, io,
99
path::{Path, PathBuf},
@@ -114,11 +114,10 @@ fn bench_rustpy_code(group: &mut BenchmarkGroup<WallTime>, bench: &MicroBenchmar
114114
settings.dont_write_bytecode = true;
115115
settings.no_user_site = true;
116116

117-
Interpreter::new_with_init(settings, |vm| {
117+
Interpreter::with_init(settings, |vm| {
118118
for (name, init) in rustpython_stdlib::get_module_inits().into_iter() {
119119
vm.add_native_module(name, init);
120120
}
121-
InitParameter::External
122121
})
123122
.enter(|vm| {
124123
let setup_code = vm

examples/freeze/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustpython_vm as vm;
22

33
fn main() -> vm::PyResult<()> {
4-
vm::Interpreter::default().enter(run)
4+
vm::Interpreter::without_stdlib(Default::default()).enter(run)
55
}
66

77
fn run(vm: &vm::VirtualMachine) -> vm::PyResult<()> {

examples/hello_embed.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustpython_vm as vm;
22

33
fn main() -> vm::PyResult<()> {
4-
vm::Interpreter::default().enter(|vm| {
4+
vm::Interpreter::without_stdlib(Default::default()).enter(|vm| {
55
let scope = vm.new_scope_with_builtins();
66

77
let code_obj = vm

examples/mini_repl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ fn on(b: bool) {
2929
}
3030

3131
fn main() -> vm::PyResult<()> {
32-
vm::Interpreter::default().enter(run)
32+
vm::Interpreter::without_stdlib(Default::default()).enter(run)
3333
}
3434

3535
fn run(vm: &vm::VirtualMachine) -> vm::PyResult<()> {

src/lib.rs

Lines changed: 15 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,13 @@ mod shell;
4747

4848
use clap::{App, AppSettings, Arg, ArgMatches};
4949
use rustpython_vm::{
50-
builtins::{PyDictRef, PyInt},
51-
compile, match_class,
50+
builtins::PyInt,
51+
match_class,
5252
scope::Scope,
5353
stdlib::{atexit, sys},
54-
AsObject, InitParameter, Interpreter, PyObjectRef, PyResult, Settings, TryFromObject,
55-
VirtualMachine,
54+
AsObject, Interpreter, PyResult, Settings, VirtualMachine,
5655
};
57-
use std::{env, path::Path, process, str::FromStr};
56+
use std::{env, process, str::FromStr};
5857

5958
pub use rustpython_vm as vm;
6059

@@ -84,10 +83,9 @@ where
8483
}
8584
}
8685

87-
let interp = Interpreter::new_with_init(settings, |vm| {
86+
let interp = Interpreter::with_init(settings, |vm| {
8887
add_stdlib(vm);
8988
init(vm);
90-
InitParameter::External
9189
});
9290

9391
let exitcode = interp.enter(move |vm| {
@@ -574,7 +572,7 @@ __import__("io").TextIOWrapper(
574572
.downcast()
575573
.expect("TextIOWrapper.read() should return str");
576574
eprintln!("running get-pip.py...");
577-
_run_string(vm, scope, getpip_code.as_str(), "get-pip.py".to_owned())
575+
vm.run_code_string(scope, getpip_code.as_str(), "get-pip.py".to_owned())
578576
}
579577

580578
#[cfg(not(feature = "ssl"))]
@@ -599,13 +597,16 @@ fn run_rustpython(vm: &VirtualMachine, matches: &ArgMatches) -> PyResult<()> {
599597

600598
// Figure out if a -c option was given:
601599
if let Some(command) = matches.value_of("c") {
602-
run_command(vm, scope, command.to_owned())?;
600+
debug!("Running command {}", command);
601+
vm.run_code_string(scope, command, "<stdin>".to_owned())?;
603602
} else if let Some(module) = matches.value_of("m") {
604-
run_module(vm, module)?;
603+
debug!("Running module {}", module);
604+
vm.run_module(module)?;
605605
} else if matches.is_present("install_pip") {
606606
install_pip(scope, vm)?;
607607
} else if let Some(filename) = matches.value_of("script") {
608-
run_script(vm, scope.clone(), filename)?;
608+
debug!("Running file {}", filename);
609+
vm.run_script(scope.clone(), filename)?;
609610
if matches.is_present("inspect") {
610611
shell::run_shell(vm, scope)?;
611612
}
@@ -620,97 +621,13 @@ fn run_rustpython(vm: &VirtualMachine, matches: &ArgMatches) -> PyResult<()> {
620621
Ok(())
621622
}
622623

623-
fn _run_string(vm: &VirtualMachine, scope: Scope, source: &str, source_path: String) -> PyResult {
624-
let code_obj = vm
625-
.compile(source, compile::Mode::Exec, source_path.clone())
626-
.map_err(|err| vm.new_syntax_error(&err))?;
627-
// trace!("Code object: {:?}", code_obj.borrow());
628-
scope
629-
.globals
630-
.set_item("__file__", vm.new_pyobj(source_path), vm)?;
631-
vm.run_code_obj(code_obj, scope)
632-
}
633-
634-
fn run_command(vm: &VirtualMachine, scope: Scope, source: String) -> PyResult<()> {
635-
debug!("Running command {}", source);
636-
_run_string(vm, scope, &source, "<stdin>".to_owned())?;
637-
Ok(())
638-
}
639-
640-
fn run_module(vm: &VirtualMachine, module: &str) -> PyResult<()> {
641-
debug!("Running module {}", module);
642-
let runpy = vm.import("runpy", None, 0)?;
643-
let run_module_as_main = runpy.get_attr("_run_module_as_main", vm)?;
644-
vm.invoke(&run_module_as_main, (module,))?;
645-
Ok(())
646-
}
647-
648-
fn get_importer(path: &str, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>> {
649-
let path_importer_cache = vm.sys_module.get_attr("path_importer_cache", vm)?;
650-
let path_importer_cache = PyDictRef::try_from_object(vm, path_importer_cache)?;
651-
if let Some(importer) = path_importer_cache.get_item_opt(path, vm)? {
652-
return Ok(Some(importer));
653-
}
654-
let path = vm.ctx.new_str(path);
655-
let path_hooks = vm.sys_module.get_attr("path_hooks", vm)?;
656-
let mut importer = None;
657-
let path_hooks: Vec<PyObjectRef> = path_hooks.try_into_value(vm)?;
658-
for path_hook in path_hooks {
659-
match vm.invoke(&path_hook, (path.clone(),)) {
660-
Ok(imp) => {
661-
importer = Some(imp);
662-
break;
663-
}
664-
Err(e) if e.fast_isinstance(&vm.ctx.exceptions.import_error) => continue,
665-
Err(e) => return Err(e),
666-
}
667-
}
668-
Ok(if let Some(imp) = importer {
669-
let imp = path_importer_cache.get_or_insert(vm, path.into(), || imp.clone())?;
670-
Some(imp)
671-
} else {
672-
None
673-
})
674-
}
675-
676-
fn insert_sys_path(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<()> {
677-
let sys_path = vm.sys_module.get_attr("path", vm).unwrap();
678-
vm.call_method(&sys_path, "insert", (0, obj))?;
679-
Ok(())
680-
}
681-
682-
fn run_script(vm: &VirtualMachine, scope: Scope, script_file: &str) -> PyResult<()> {
683-
debug!("Running file {}", script_file);
684-
if get_importer(script_file, vm)?.is_some() {
685-
insert_sys_path(vm, vm.ctx.new_str(script_file).into())?;
686-
let runpy = vm.import("runpy", None, 0)?;
687-
let run_module_as_main = runpy.get_attr("_run_module_as_main", vm)?;
688-
vm.invoke(&run_module_as_main, (vm.ctx.new_str("__main__"), false))?;
689-
return Ok(());
690-
}
691-
let dir = Path::new(script_file).parent().unwrap().to_str().unwrap();
692-
insert_sys_path(vm, vm.ctx.new_str(dir).into())?;
693-
694-
match std::fs::read_to_string(script_file) {
695-
Ok(source) => {
696-
_run_string(vm, scope, &source, script_file.to_owned())?;
697-
}
698-
Err(err) => {
699-
error!("Failed reading file '{}': {}", script_file, err);
700-
process::exit(1);
701-
}
702-
}
703-
Ok(())
704-
}
705-
706624
#[cfg(test)]
707625
mod tests {
708626
use super::*;
709627

710628
fn interpreter() -> Interpreter {
711-
Interpreter::new_with_init(Settings::default(), |vm| {
629+
Interpreter::with_init(Settings::default(), |vm| {
712630
add_stdlib(vm);
713-
InitParameter::External
714631
})
715632
}
716633

@@ -720,11 +637,11 @@ mod tests {
720637
vm.unwrap_pyresult((|| {
721638
let scope = setup_main_module(vm)?;
722639
// test file run
723-
run_script(vm, scope, "extra_tests/snippets/dir_main/__main__.py")?;
640+
vm.run_script(scope, "extra_tests/snippets/dir_main/__main__.py")?;
724641

725642
let scope = setup_main_module(vm)?;
726643
// test module run
727-
run_script(vm, scope, "extra_tests/snippets/dir_main")?;
644+
vm.run_script(scope, "extra_tests/snippets/dir_main")?;
728645

729646
Ok(())
730647
})());

vm/src/builtins/str.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1559,7 +1559,7 @@ mod tests {
15591559

15601560
#[test]
15611561
fn str_maketrans_and_translate() {
1562-
Interpreter::default().enter(|vm| {
1562+
Interpreter::without_stdlib(Default::default()).enter(|vm| {
15631563
let table = vm.ctx.new_dict();
15641564
table
15651565
.set_item("a", vm.ctx.new_str("🎅").into(), &vm)

vm/src/dictdatatype.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ mod tests {
872872

873873
#[test]
874874
fn test_insert() {
875-
Interpreter::default().enter(|vm| {
875+
Interpreter::without_stdlib(Default::default()).enter(|vm| {
876876
let dict = Dict::default();
877877
assert_eq!(0, dict.len());
878878

@@ -921,7 +921,7 @@ mod tests {
921921
}
922922

923923
fn check_hash_equivalence(text: &str) {
924-
Interpreter::default().enter(|vm| {
924+
Interpreter::without_stdlib(Default::default()).enter(|vm| {
925925
let value1 = text;
926926
let value2 = vm.new_pyobj(value1.to_owned());
927927

vm/src/eval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ mod tests {
2020

2121
#[test]
2222
fn test_print_42() {
23-
Interpreter::default().enter(|vm| {
23+
Interpreter::without_stdlib(Default::default()).enter(|vm| {
2424
let source = String::from("print('Hello world')");
2525
let vars = vm.new_scope_with_builtins();
2626
let result = eval(&vm, &source, vars, "<unittest>").expect("this should pass");

vm/src/import.rs

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,23 @@ use crate::{
77
builtins::{code, code::CodeObject, list, traceback::PyTraceback, PyBaseExceptionRef},
88
scope::Scope,
99
version::get_git_revision,
10-
vm::{InitParameter, VirtualMachine},
10+
vm::{thread, VirtualMachine},
1111
AsObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject,
1212
};
1313
use rand::Rng;
1414

1515
pub(crate) fn init_importlib(
1616
vm: &mut VirtualMachine,
17-
initialize_parameter: InitParameter,
17+
allow_external_library: bool,
1818
) -> PyResult<()> {
19-
use crate::vm::thread::enter_vm;
19+
let importlib = init_importlib_base(vm)?;
20+
if allow_external_library && cfg!(feature = "rustpython-compiler") {
21+
init_importlib_package(vm, importlib)?;
22+
}
23+
Ok(())
24+
}
25+
26+
pub(crate) fn init_importlib_base(vm: &mut VirtualMachine) -> PyResult<PyObjectRef> {
2027
flame_guard!("init importlib");
2128

2229
// importlib_bootstrap needs these and it inlines checks to sys.modules before calling into
@@ -26,53 +33,56 @@ pub(crate) fn init_importlib(
2633
import_builtin(vm, "_warnings")?;
2734
import_builtin(vm, "_weakref")?;
2835

29-
let importlib = enter_vm(vm, || {
36+
let importlib = thread::enter_vm(vm, || {
3037
let importlib = import_frozen(vm, "_frozen_importlib")?;
3138
let impmod = import_builtin(vm, "_imp")?;
3239
let install = importlib.get_attr("_install", vm)?;
3340
vm.invoke(&install, (vm.sys_module.clone(), impmod))?;
3441
Ok(importlib)
3542
})?;
3643
vm.import_func = importlib.get_attr("__import__", vm)?;
44+
Ok(importlib)
45+
}
3746

38-
if initialize_parameter == InitParameter::External && cfg!(feature = "rustpython-compiler") {
39-
enter_vm(vm, || {
40-
flame_guard!("install_external");
41-
42-
// same deal as imports above
43-
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
44-
import_builtin(vm, crate::stdlib::os::MODULE_NAME)?;
45-
#[cfg(windows)]
46-
import_builtin(vm, "winreg")?;
47-
import_builtin(vm, "_io")?;
48-
import_builtin(vm, "marshal")?;
49-
50-
let install_external = importlib.get_attr("_install_external_importers", vm)?;
51-
vm.invoke(&install_external, ())?;
52-
// Set pyc magic number to commit hash. Should be changed when bytecode will be more stable.
53-
let importlib_external = vm.import("_frozen_importlib_external", None, 0)?;
54-
let mut magic = get_git_revision().into_bytes();
55-
magic.truncate(4);
56-
if magic.len() != 4 {
57-
magic = rand::thread_rng().gen::<[u8; 4]>().to_vec();
58-
}
59-
let magic: PyObjectRef = vm.ctx.new_bytes(magic).into();
60-
importlib_external.set_attr("MAGIC_NUMBER", magic, vm)?;
61-
let zipimport_res = (|| -> PyResult<()> {
62-
let zipimport = vm.import("zipimport", None, 0)?;
63-
let zipimporter = zipimport.get_attr("zipimporter", vm)?;
64-
let path_hooks = vm.sys_module.get_attr("path_hooks", vm)?;
65-
let path_hooks = list::PyListRef::try_from_object(vm, path_hooks)?;
66-
path_hooks.insert(0, zipimporter);
67-
Ok(())
68-
})();
69-
if zipimport_res.is_err() {
70-
warn!("couldn't init zipimport")
71-
}
47+
pub(crate) fn init_importlib_package(
48+
vm: &mut VirtualMachine,
49+
importlib: PyObjectRef,
50+
) -> PyResult<()> {
51+
thread::enter_vm(vm, || {
52+
flame_guard!("install_external");
53+
54+
// same deal as imports above
55+
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
56+
import_builtin(vm, crate::stdlib::os::MODULE_NAME)?;
57+
#[cfg(windows)]
58+
import_builtin(vm, "winreg")?;
59+
import_builtin(vm, "_io")?;
60+
import_builtin(vm, "marshal")?;
61+
62+
let install_external = importlib.get_attr("_install_external_importers", vm)?;
63+
vm.invoke(&install_external, ())?;
64+
// Set pyc magic number to commit hash. Should be changed when bytecode will be more stable.
65+
let importlib_external = vm.import("_frozen_importlib_external", None, 0)?;
66+
let mut magic = get_git_revision().into_bytes();
67+
magic.truncate(4);
68+
if magic.len() != 4 {
69+
magic = rand::thread_rng().gen::<[u8; 4]>().to_vec();
70+
}
71+
let magic: PyObjectRef = vm.ctx.new_bytes(magic).into();
72+
importlib_external.set_attr("MAGIC_NUMBER", magic, vm)?;
73+
let zipimport_res = (|| -> PyResult<()> {
74+
let zipimport = vm.import("zipimport", None, 0)?;
75+
let zipimporter = zipimport.get_attr("zipimporter", vm)?;
76+
let path_hooks = vm.sys_module.get_attr("path_hooks", vm)?;
77+
let path_hooks = list::PyListRef::try_from_object(vm, path_hooks)?;
78+
path_hooks.insert(0, zipimporter);
7279
Ok(())
73-
})?
74-
}
75-
Ok(())
80+
})();
81+
if zipimport_res.is_err() {
82+
warn!("couldn't init zipimport")
83+
}
84+
Ok(())
85+
})
7686
}
7787

7888
pub fn import_frozen(vm: &VirtualMachine, module_name: &str) -> PyResult {

0 commit comments

Comments
 (0)