Skip to content

Commit 73edde6

Browse files
Merge pull request RustPython#1037 from RustPython/coolreader18/option-source_path
Make CodeObject.source_path an Option<String>
2 parents 9b35219 + b74b65d commit 73edde6

13 files changed

Lines changed: 59 additions & 51 deletions

File tree

compiler/src/bytecode.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub struct CodeObject {
2121
pub varargs: Varargs, // *args or *
2222
pub kwonlyarg_names: Vec<String>,
2323
pub varkeywords: Varargs, // **kwargs or **
24-
pub source_path: String,
24+
pub source_path: Option<String>,
2525
pub first_line_number: usize,
2626
pub obj_name: String, // Name of the object that created this code object
2727
pub is_generator: bool,
@@ -269,7 +269,7 @@ impl CodeObject {
269269
varargs: Varargs,
270270
kwonlyarg_names: Vec<String>,
271271
varkeywords: Varargs,
272-
source_path: String,
272+
source_path: Option<String>,
273273
first_line_number: usize,
274274
obj_name: String,
275275
) -> CodeObject {

compiler/src/compile.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ struct Compiler {
2323
}
2424

2525
/// Compile a given sourcecode into a bytecode object.
26-
pub fn compile(source: &str, mode: &Mode, source_path: String) -> Result<CodeObject, CompileError> {
26+
pub fn compile(
27+
source: &str,
28+
mode: &Mode,
29+
source_path: Option<String>,
30+
) -> Result<CodeObject, CompileError> {
2731
match mode {
2832
Mode::Exec => {
2933
let ast = parser::parse_program(source)?;
@@ -42,11 +46,11 @@ pub fn compile(source: &str, mode: &Mode, source_path: String) -> Result<CodeObj
4246

4347
/// A helper function for the shared code of the different compile functions
4448
fn with_compiler(
45-
source_path: String,
49+
source_path: Option<String>,
4650
f: impl FnOnce(&mut Compiler) -> Result<(), CompileError>,
4751
) -> Result<CodeObject, CompileError> {
4852
let mut compiler = Compiler::new();
49-
compiler.source_path = Some(source_path);
53+
compiler.source_path = source_path;
5054
compiler.push_new_code_object("<module>".to_string());
5155
f(&mut compiler)?;
5256
let code = compiler.pop_code_object();
@@ -55,7 +59,10 @@ fn with_compiler(
5559
}
5660

5761
/// Compile a standard Python program to bytecode
58-
pub fn compile_program(ast: ast::Program, source_path: String) -> Result<CodeObject, CompileError> {
62+
pub fn compile_program(
63+
ast: ast::Program,
64+
source_path: Option<String>,
65+
) -> Result<CodeObject, CompileError> {
5966
with_compiler(source_path, |compiler| {
6067
let symbol_table = make_symbol_table(&ast)?;
6168
compiler.compile_program(&ast, symbol_table)
@@ -65,7 +72,7 @@ pub fn compile_program(ast: ast::Program, source_path: String) -> Result<CodeObj
6572
/// Compile a single Python expression to bytecode
6673
pub fn compile_statement_eval(
6774
statement: Vec<ast::LocatedStatement>,
68-
source_path: String,
75+
source_path: Option<String>,
6976
) -> Result<CodeObject, CompileError> {
7077
with_compiler(source_path, |compiler| {
7178
let symbol_table = statements_to_symbol_table(&statement)?;
@@ -76,7 +83,7 @@ pub fn compile_statement_eval(
7683
/// Compile a Python program to bytecode for the context of a REPL
7784
pub fn compile_program_single(
7885
ast: ast::Program,
79-
source_path: String,
86+
source_path: Option<String>,
8087
) -> Result<CodeObject, CompileError> {
8188
with_compiler(source_path, |compiler| {
8289
let symbol_table = make_symbol_table(&ast)?;
@@ -119,7 +126,7 @@ impl Compiler {
119126
Varargs::None,
120127
Vec::new(),
121128
Varargs::None,
122-
self.source_path.clone().unwrap(),
129+
self.source_path.clone(),
123130
line_number,
124131
obj_name,
125132
));
@@ -596,7 +603,7 @@ impl Compiler {
596603
Varargs::from(&args.vararg),
597604
args.kwonlyargs.iter().map(|a| a.arg.clone()).collect(),
598605
Varargs::from(&args.kwarg),
599-
self.source_path.clone().unwrap(),
606+
self.source_path.clone(),
600607
line_number,
601608
name.to_string(),
602609
));
@@ -849,7 +856,7 @@ impl Compiler {
849856
Varargs::None,
850857
vec![],
851858
Varargs::None,
852-
self.source_path.clone().unwrap(),
859+
self.source_path.clone(),
853860
line_number,
854861
name.to_string(),
855862
));
@@ -1571,7 +1578,7 @@ impl Compiler {
15711578
Varargs::None,
15721579
vec![],
15731580
Varargs::None,
1574-
self.source_path.clone().unwrap(),
1581+
self.source_path.clone(),
15751582
line_number,
15761583
name.clone(),
15771584
));

derive/src/compile_bytecode.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ struct CompilationSource {
3535
}
3636

3737
impl CompilationSource {
38-
fn compile(self, mode: &compile::Mode, source_path: String) -> Result<CodeObject, Diagnostic> {
38+
fn compile(
39+
self,
40+
mode: &compile::Mode,
41+
source_path: Option<String>,
42+
) -> Result<CodeObject, Diagnostic> {
3943
let compile = |source| {
4044
compile::compile(source, mode, source_path).map_err(|err| {
4145
Diagnostic::spans_error(self.span, format!("Compile error: {}", err))
@@ -135,10 +139,7 @@ impl PyCompileInput {
135139
"Must have either file or source in py_compile_bytecode!()",
136140
)
137141
})?
138-
.compile(
139-
&mode.unwrap_or(compile::Mode::Exec),
140-
source_path.unwrap_or_else(|| "frozen".to_string()),
141-
)
142+
.compile(&mode.unwrap_or(compile::Mode::Exec), source_path)
142143
}
143144
}
144145

src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ fn main() {
7676

7777
fn _run_string(vm: &VirtualMachine, source: &str, source_path: String) -> PyResult {
7878
let code_obj = vm
79-
.compile(source, &compile::Mode::Exec, source_path.clone())
79+
.compile(source, &compile::Mode::Exec, Some(source_path.clone()))
8080
.map_err(|err| vm.new_syntax_error(&err))?;
8181
// trace!("Code object: {:?}", code_obj.borrow());
8282
let attrs = vm.ctx.new_dict();
@@ -161,7 +161,7 @@ fn test_run_script() {
161161
}
162162

163163
fn shell_exec(vm: &VirtualMachine, source: &str, scope: Scope) -> Result<(), CompileError> {
164-
match vm.compile(source, &compile::Mode::Single, "<stdin>".to_string()) {
164+
match vm.compile(source, &compile::Mode::Single, Some("<stdin>".to_string())) {
165165
Ok(code) => {
166166
match vm.run_code_obj(code, scope.clone()) {
167167
Ok(value) => {

vm/src/builtins.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ fn builtin_compile(args: CompileArgs, vm: &VirtualMachine) -> PyResult<PyCodeRef
122122
}
123123
};
124124

125-
vm.compile(&source, &mode, args.filename.value.to_string())
125+
vm.compile(&source, &mode, Some(args.filename.value.to_string()))
126126
.map_err(|err| vm.new_syntax_error(&err))
127127
}
128128

@@ -171,7 +171,7 @@ fn builtin_eval(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
171171
let source = objstr::get_value(source);
172172
// TODO: fix this newline bug:
173173
let source = format!("{}\n", source);
174-
vm.compile(&source, &mode, "<string>".to_string())
174+
vm.compile(&source, &mode, Some("<string>".to_string()))
175175
.map_err(|err| vm.new_syntax_error(&err))?
176176
} else {
177177
return Err(vm.new_type_error("code argument must be str or code object".to_string()));
@@ -199,7 +199,7 @@ fn builtin_exec(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
199199
let source = objstr::get_value(source);
200200
// TODO: fix this newline bug:
201201
let source = format!("{}\n", source);
202-
vm.compile(&source, &mode, "<string>".to_string())
202+
vm.compile(&source, &mode, Some("<string>".to_string()))
203203
.map_err(|err| vm.new_syntax_error(&err))?
204204
} else if let Ok(code_obj) = PyCodeRef::try_from_object(vm, source.clone()) {
205205
code_obj

vm/src/eval.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
extern crate rustpython_parser;
2-
31
use crate::compile;
42
use crate::frame::Scope;
53
use crate::pyobject::PyResult;
64
use crate::vm::VirtualMachine;
75

8-
pub fn eval(vm: &VirtualMachine, source: &str, scope: Scope, source_path: &str) -> PyResult {
9-
match vm.compile(source, &compile::Mode::Eval, source_path.to_string()) {
6+
pub fn eval(
7+
vm: &VirtualMachine,
8+
source: &str,
9+
scope: Scope,
10+
source_path: Option<String>,
11+
) -> PyResult {
12+
match vm.compile(source, &compile::Mode::Eval, source_path) {
1013
Ok(bytecode) => {
1114
debug!("Code object: {:?}", bytecode);
1215
vm.run_code_obj(bytecode, scope)
@@ -25,7 +28,7 @@ mod tests {
2528
let source = String::from("print('Hello world')\n");
2629
let mut vm = VirtualMachine::new();
2730
let vars = vm.new_scope_with_builtins();
28-
let _result = eval(&mut vm, &source, vars, "<unittest>");
31+
let _result = eval(&mut vm, &source, vars, Some("<unittest>".to_string()));
2932

3033
// TODO: check result?
3134
//assert_eq!(

vm/src/frame.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,10 @@ impl Frame {
271271
}
272272

273273
pub fn run(&self, vm: &VirtualMachine) -> Result<ExecutionResult, PyObjectRef> {
274-
let filename = &self.code.source_path.to_string();
274+
let filename = match self.code.source_path.clone() {
275+
Some(s) => vm.ctx.new_str(s),
276+
None => vm.get_none(),
277+
};
275278

276279
// This is the name of the object being run:
277280
let run_obj_name = &self.code.obj_name.to_string();
@@ -299,7 +302,7 @@ impl Frame {
299302
.unwrap();
300303
trace!("Adding to traceback: {:?} {:?}", traceback, lineno);
301304
let raise_location = vm.ctx.new_tuple(vec![
302-
vm.ctx.new_str(filename.clone()),
305+
filename.clone(),
303306
vm.ctx.new_int(lineno.get_row()),
304307
vm.ctx.new_str(run_obj_name.clone()),
305308
]);

vm/src/import.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ pub fn init_importlib(vm: &VirtualMachine) -> PyResult {
2525
}
2626

2727
pub fn import_frozen(vm: &VirtualMachine, module_name: &str) -> PyResult {
28-
if let Some(frozen) = vm.frozen.borrow().get(module_name) {
29-
let mut frozen = frozen.clone();
30-
frozen.source_path = format!("frozen {}", module_name);
31-
import_codeobj(vm, module_name, frozen)
32-
} else {
33-
Err(vm.new_import_error(format!("Cannot import frozen module {}", module_name)))
34-
}
28+
vm.frozen
29+
.borrow()
30+
.get(module_name)
31+
.cloned()
32+
.ok_or_else(|| vm.new_import_error(format!("Cannot import frozen module {}", module_name)))
33+
.and_then(|frozen| import_codeobj(vm, module_name, frozen))
3534
}
3635

3736
pub fn import_builtin(vm: &VirtualMachine, module_name: &str) -> PyResult {
@@ -69,7 +68,7 @@ pub fn import_module(vm: &VirtualMachine, current_path: PathBuf, module_name: &s
6968
import_file(
7069
vm,
7170
module_name,
72-
file_path.to_str().unwrap().to_string(),
71+
Some(file_path.to_str().unwrap().to_string()),
7372
source,
7473
)
7574
}
@@ -78,7 +77,7 @@ pub fn import_module(vm: &VirtualMachine, current_path: PathBuf, module_name: &s
7877
pub fn import_file(
7978
vm: &VirtualMachine,
8079
module_name: &str,
81-
file_path: String,
80+
file_path: Option<String>,
8281
content: String,
8382
) -> PyResult {
8483
let code_obj = compile::compile(&content, &compile::Mode::Exec, file_path)
@@ -89,10 +88,8 @@ pub fn import_file(
8988
pub fn import_codeobj(vm: &VirtualMachine, module_name: &str, code_obj: CodeObject) -> PyResult {
9089
let attrs = vm.ctx.new_dict();
9190
attrs.set_item("__name__", vm.new_str(module_name.to_string()), vm)?;
92-
let file_path = &code_obj.source_path;
93-
if !file_path.starts_with("frozen") {
94-
// TODO: Should be less hacky, not depend on source_path
95-
attrs.set_item("__file__", vm.new_str(file_path.to_owned()), vm)?;
91+
if let Some(source_path) = &code_obj.source_path {
92+
attrs.set_item("__file__", vm.new_str(source_path.to_owned()), vm)?;
9693
}
9794
let module = vm.ctx.new_module(module_name, attrs.clone());
9895

vm/src/obj/objcode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl PyCodeRef {
5454
self.code.arg_names.len()
5555
}
5656

57-
fn co_filename(self, _vm: &VirtualMachine) -> String {
57+
fn co_filename(self, _vm: &VirtualMachine) -> Option<String> {
5858
self.code.source_path.clone()
5959
}
6060

vm/src/stdlib/imp.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,8 @@ fn imp_get_frozen_object(name: PyStringRef, vm: &VirtualMachine) -> PyResult<PyC
5858
vm.frozen
5959
.borrow()
6060
.get(name.as_str())
61-
.map(|frozen| {
62-
let mut frozen = frozen.clone();
63-
frozen.source_path = format!("frozen {}", name.as_str());
64-
PyCode::new(frozen)
65-
})
61+
.cloned()
62+
.map(PyCode::new)
6663
.ok_or_else(|| {
6764
vm.new_import_error(format!("No such frozen object named {}", name.as_str()))
6865
})

0 commit comments

Comments
 (0)