From da3df8a0aee31d33e798c1be1e7de35cee4527a3 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Fri, 10 May 2019 13:58:10 +0300 Subject: [PATCH 1/2] Add __file__ for imported modules --- tests/snippets/builtin_file.py | 3 +++ tests/snippets/import_file.py | 4 ++++ vm/src/import.rs | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/snippets/builtin_file.py create mode 100644 tests/snippets/import_file.py diff --git a/tests/snippets/builtin_file.py b/tests/snippets/builtin_file.py new file mode 100644 index 000000000..50dfeb931 --- /dev/null +++ b/tests/snippets/builtin_file.py @@ -0,0 +1,3 @@ +from import_file import import_file + +import_file() diff --git a/tests/snippets/import_file.py b/tests/snippets/import_file.py new file mode 100644 index 000000000..3f9eeed70 --- /dev/null +++ b/tests/snippets/import_file.py @@ -0,0 +1,4 @@ +import os + +def import_file(): + assert os.path.basename(__file__) == "import_file.py" diff --git a/vm/src/import.rs b/vm/src/import.rs index f4c52a11e..a03f14623 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -48,12 +48,13 @@ pub fn import_file( content: String, ) -> PyResult { let sys_modules = vm.get_attribute(vm.sys_module.clone(), "modules").unwrap(); - let code_obj = compile::compile(vm, &content, &compile::Mode::Exec, file_path) + let code_obj = compile::compile(vm, &content, &compile::Mode::Exec, file_path.clone()) .map_err(|err| vm.new_syntax_error(&err))?; // trace!("Code object: {:?}", code_obj); let attrs = vm.ctx.new_dict(); attrs.set_item("__name__", vm.new_str(module_name.to_string()), vm)?; + attrs.set_item("__file__", vm.new_str(file_path), vm)?; let module = vm.ctx.new_module(module_name, attrs.clone()); // Store module in cache to prevent infinite loop with mutual importing libs: From fc1a063a2cfd2b2b5082116566cdb7bb0f8c4ec4 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Fri, 10 May 2019 14:06:23 +0300 Subject: [PATCH 2/2] Add __file__ for file executed from main --- src/main.rs | 18 +++++++++++++----- tests/snippets/builtin_file.py | 4 ++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3e77ddbc2..72bb16139 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,8 +10,15 @@ extern crate rustyline; use clap::{App, Arg}; use rustpython_parser::error::ParseError; use rustpython_vm::{ - compile, error::CompileError, error::CompileErrorType, frame::Scope, import, obj::objstr, - print_exception, pyobject::PyResult, util, VirtualMachine, + compile, + error::CompileError, + error::CompileErrorType, + frame::Scope, + import, + obj::objstr, + print_exception, + pyobject::{ItemProtocol, PyResult}, + util, VirtualMachine, }; use rustyline::{error::ReadlineError, Editor}; use std::path::PathBuf; @@ -65,11 +72,12 @@ fn main() { } fn _run_string(vm: &VirtualMachine, source: &str, source_path: String) -> PyResult { - let code_obj = compile::compile(vm, source, &compile::Mode::Exec, source_path) + let code_obj = compile::compile(vm, source, &compile::Mode::Exec, source_path.clone()) .map_err(|err| vm.new_syntax_error(&err))?; // trace!("Code object: {:?}", code_obj.borrow()); - let vars = vm.ctx.new_scope(); // Keep track of local variables - vm.run_code_obj(code_obj, vars) + let attrs = vm.ctx.new_dict(); + attrs.set_item("__file__", vm.new_str(source_path), vm)?; + vm.run_code_obj(code_obj, Scope::new(None, attrs)) } fn handle_exception(vm: &VirtualMachine, result: PyResult) { diff --git a/tests/snippets/builtin_file.py b/tests/snippets/builtin_file.py index 50dfeb931..2c80d1590 100644 --- a/tests/snippets/builtin_file.py +++ b/tests/snippets/builtin_file.py @@ -1,3 +1,7 @@ +import os + from import_file import import_file import_file() + +assert os.path.basename(__file__) == "builtin_file.py"