mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Allow running packages passed to command line
This commit is contained in:
2 files changed
+59
-24
No files matched your search
+50
-24
@@ -45,13 +45,14 @@ extern crate log;
|
||||
|
||||
use clap::{App, AppSettings, Arg, ArgMatches};
|
||||
use rustpython_vm::{
|
||||
builtins::PyInt, compile, exceptions::print_exception, match_class, scope::Scope, stdlib::sys,
|
||||
InitParameter, Interpreter, ItemProtocol, PyResult, PySettings, TypeProtocol, VirtualMachine,
|
||||
builtins::PyDictRef, builtins::PyInt, compile, exceptions::print_exception, match_class,
|
||||
scope::Scope, stdlib::sys, InitParameter, Interpreter, ItemProtocol, PyObjectRef, PyResult,
|
||||
PySettings, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
};
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -613,35 +614,60 @@ fn run_module(vm: &VirtualMachine, module: &str) -> PyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_script(vm: &VirtualMachine, scope: Scope, script_file: &str) -> PyResult<()> {
|
||||
debug!("Running file {}", script_file);
|
||||
let mut file_path = PathBuf::from(script_file);
|
||||
let file_meta = file_path.metadata().unwrap_or_else(|e| {
|
||||
error!("can't open file '{}': {}", file_path.display(), e);
|
||||
process::exit(1);
|
||||
});
|
||||
if file_meta.is_dir() {
|
||||
file_path.push("__main__.py");
|
||||
if !file_path.is_file() {
|
||||
error!("can't find '__main__' module in '{}'", file_path.display());
|
||||
process::exit(1);
|
||||
fn get_importer(path: &str, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>> {
|
||||
let path_importer_cache = vm.get_attribute(vm.sys_module.clone(), "path_importer_cache")?;
|
||||
let path_importer_cache = PyDictRef::try_from_object(vm, path_importer_cache)?;
|
||||
if let Some(importer) = path_importer_cache.get_item_option(path, vm)? {
|
||||
return Ok(Some(importer));
|
||||
}
|
||||
let path = vm.ctx.new_utf8_str(path);
|
||||
let path_hooks = vm.get_attribute(vm.sys_module.clone(), "path_hooks")?;
|
||||
let mut importer = None;
|
||||
for path_hook in vm.extract_elements(&path_hooks)? {
|
||||
match vm.invoke(&path_hook, (path.clone(),)) {
|
||||
Ok(imp) => {
|
||||
importer = Some(imp);
|
||||
break;
|
||||
}
|
||||
Err(e) if e.isinstance(&vm.ctx.exceptions.import_error) => continue,
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
Ok(if let Some(imp) = importer {
|
||||
let imp = path_importer_cache.get_or_insert(vm, path, || imp.clone())?;
|
||||
Some(imp)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
let dir = file_path.parent().unwrap().to_str().unwrap().to_owned();
|
||||
fn insert_sys_path(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<()> {
|
||||
let sys_path = vm.get_attribute(vm.sys_module.clone(), "path").unwrap();
|
||||
vm.call_method(&sys_path, "insert", (0, dir))?;
|
||||
vm.call_method(&sys_path, "insert", (0, obj))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
match std::fs::read_to_string(&file_path) {
|
||||
fn run_script(vm: &VirtualMachine, scope: Scope, script_file: &str) -> PyResult<()> {
|
||||
debug!("Running file {}", script_file);
|
||||
if get_importer(script_file, vm)?.is_some() {
|
||||
insert_sys_path(vm, vm.ctx.new_utf8_str(script_file))?;
|
||||
let runpy = vm.import("runpy", None, 0)?;
|
||||
let run_module_as_main = vm.get_attribute(runpy, "_run_module_as_main")?;
|
||||
vm.invoke(
|
||||
&run_module_as_main,
|
||||
(vm.ctx.new_utf8_str("__main__"), false),
|
||||
)?;
|
||||
return Ok(());
|
||||
}
|
||||
let dir = Path::new(script_file).parent().unwrap().to_str().unwrap();
|
||||
insert_sys_path(vm, vm.ctx.new_utf8_str(dir))?;
|
||||
|
||||
match std::fs::read_to_string(script_file) {
|
||||
Ok(source) => {
|
||||
_run_string(vm, scope, &source, file_path.to_str().unwrap().to_owned())?;
|
||||
_run_string(vm, scope, &source, script_file.to_owned())?;
|
||||
}
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Failed reading file '{}': {:?}",
|
||||
file_path.to_str().unwrap(),
|
||||
err.kind()
|
||||
);
|
||||
error!("Failed reading file '{}': {:?}", script_file, err.kind());
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,6 +297,15 @@ impl PyDict {
|
||||
.setdefault(vm, key, || default.unwrap_or_none(vm))
|
||||
}
|
||||
|
||||
pub fn get_or_insert(
|
||||
&self,
|
||||
vm: &VirtualMachine,
|
||||
key: PyObjectRef,
|
||||
default: impl FnOnce() -> PyObjectRef,
|
||||
) -> PyResult {
|
||||
self.entries.setdefault(vm, key, default)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
pub fn copy(&self) -> PyDict {
|
||||
PyDict {
|
||||
|
||||
Reference in new issue
Block a user