Skip to content

Commit a099ba5

Browse files
Merge pull request RustPython#1104 from palaviv/remove-importlib-frames
Remove importlib frames from traceback
2 parents 22c0b08 + 251e33a commit a099ba5

File tree

2 files changed

+67
-25
lines changed

2 files changed

+67
-25
lines changed

vm/src/import.rs

+40-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
use crate::bytecode::CodeObject;
66
use crate::frame::Scope;
7-
use crate::obj::objcode;
8-
use crate::pyobject::{ItemProtocol, PyResult, PyValue};
7+
use crate::obj::{objcode, objsequence, objstr, objtype};
8+
use crate::pyobject::{ItemProtocol, PyObjectRef, PyResult, PyValue};
99
use crate::vm::VirtualMachine;
1010
#[cfg(feature = "rustpython-compiler")]
1111
use rustpython_compiler::compile;
@@ -82,3 +82,41 @@ pub fn import_codeobj(
8282
)?;
8383
Ok(module)
8484
}
85+
86+
// TODO: This function should do nothing on verbose mode.
87+
pub fn remove_importlib_frames(vm: &VirtualMachine, exc: &PyObjectRef) -> PyObjectRef {
88+
let always_trim = objtype::isinstance(exc, &vm.ctx.exceptions.import_error);
89+
90+
if let Ok(tb) = vm.get_attribute(exc.clone(), "__traceback__") {
91+
if objtype::isinstance(&tb, &vm.ctx.list_type()) {
92+
let tb_entries = objsequence::get_elements_list(&tb).to_vec();
93+
let mut in_importlib = false;
94+
let new_tb = tb_entries
95+
.iter()
96+
.filter(|tb_entry| {
97+
let location_attrs = objsequence::get_elements_tuple(&tb_entry);
98+
let file_name = objstr::get_value(&location_attrs[0]);
99+
if file_name == "_frozen_importlib" || file_name == "_frozen_importlib_external"
100+
{
101+
let run_obj_name = objstr::get_value(&location_attrs[2]);
102+
if run_obj_name == "_call_with_frames_removed" {
103+
in_importlib = true;
104+
}
105+
if always_trim || in_importlib {
106+
false
107+
} else {
108+
true
109+
}
110+
} else {
111+
in_importlib = false;
112+
true
113+
}
114+
})
115+
.map(|x| x.clone())
116+
.collect();
117+
vm.set_attr(exc, "__traceback__", vm.ctx.new_list(new_tb))
118+
.unwrap();
119+
}
120+
}
121+
exc.clone()
122+
}

vm/src/vm.rs

+27-23
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::bytecode;
1515
use crate::frame::{ExecutionResult, Frame, FrameRef, Scope};
1616
use crate::frozen;
1717
use crate::function::PyFuncArgs;
18+
use crate::import;
1819
use crate::obj::objbool;
1920
use crate::obj::objbuiltinfunc::PyBuiltinFunction;
2021
use crate::obj::objcode::{PyCode, PyCodeRef};
@@ -305,30 +306,33 @@ impl VirtualMachine {
305306

306307
pub fn import(&self, module: &str, from_list: &PyObjectRef, level: usize) -> PyResult {
307308
let sys_modules = self.get_attribute(self.sys_module.clone(), "modules")?;
308-
sys_modules.get_item(module.to_string(), self).or_else(|_| {
309-
let import_func = self
310-
.get_attribute(self.builtins.clone(), "__import__")
311-
.map_err(|_| self.new_import_error("__import__ not found".to_string()))?;
312-
313-
let (locals, globals) = if let Some(frame) = self.current_frame() {
314-
(
315-
frame.scope.get_locals().into_object(),
316-
frame.scope.globals.clone().into_object(),
309+
sys_modules
310+
.get_item(module.to_string(), self)
311+
.or_else(|_| {
312+
let import_func = self
313+
.get_attribute(self.builtins.clone(), "__import__")
314+
.map_err(|_| self.new_import_error("__import__ not found".to_string()))?;
315+
316+
let (locals, globals) = if let Some(frame) = self.current_frame() {
317+
(
318+
frame.scope.get_locals().into_object(),
319+
frame.scope.globals.clone().into_object(),
320+
)
321+
} else {
322+
(self.get_none(), self.get_none())
323+
};
324+
self.invoke(
325+
import_func,
326+
vec![
327+
self.ctx.new_str(module.to_string()),
328+
globals,
329+
locals,
330+
from_list.clone(),
331+
self.ctx.new_int(level),
332+
],
317333
)
318-
} else {
319-
(self.get_none(), self.get_none())
320-
};
321-
self.invoke(
322-
import_func,
323-
vec![
324-
self.ctx.new_str(module.to_string()),
325-
globals,
326-
locals,
327-
from_list.clone(),
328-
self.ctx.new_int(level),
329-
],
330-
)
331-
})
334+
})
335+
.map_err(|exc| import::remove_importlib_frames(self, &exc))
332336
}
333337

334338
/// Determines if `obj` is an instance of `cls`, either directly, indirectly or virtually via

0 commit comments

Comments
 (0)