Skip to content

Commit 35f46c0

Browse files
authored
Update warning setup_context (RustPython#4130)
1 parent 31fdb20 commit 35f46c0

File tree

4 files changed

+57
-30
lines changed

4 files changed

+57
-30
lines changed

vm/src/builtins/code.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ impl PyRef<PyCode> {
190190
}
191191

192192
#[pyproperty]
193-
fn co_filename(self) -> PyStrRef {
193+
pub fn co_filename(self) -> PyStrRef {
194194
self.code.source_path.to_owned()
195195
}
196196

vm/src/builtins/frame.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ impl FrameRef {
4242
}
4343

4444
#[pyproperty]
45-
fn f_code(self) -> PyRef<PyCode> {
45+
pub fn f_code(self) -> PyRef<PyCode> {
4646
self.code.clone()
4747
}
4848

4949
#[pyproperty]
50-
fn f_back(self, vm: &VirtualMachine) -> Option<Self> {
50+
pub fn f_back(self, vm: &VirtualMachine) -> Option<Self> {
5151
// TODO: actually store f_back inside Frame struct
5252

5353
// get the frame in the frame stack that appears before this one.

vm/src/frame.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,27 @@ impl FrameRef {
264264
self.lasti.get()
265265
}
266266
}
267+
268+
pub fn is_internal_frame(&self) -> bool {
269+
let code = self.clone().f_code();
270+
let filename = code.co_filename();
271+
272+
filename.as_str().contains("importlib") && filename.as_str().contains("_bootstrap")
273+
}
274+
275+
pub fn next_external_frame(&self, vm: &VirtualMachine) -> Option<FrameRef> {
276+
self.clone().f_back(vm).map(|mut back| loop {
277+
back = if let Some(back) = back.to_owned().f_back(vm) {
278+
back
279+
} else {
280+
break back;
281+
};
282+
283+
if !back.is_internal_frame() {
284+
break back;
285+
}
286+
})
287+
}
267288
}
268289

269290
/// An executing frame; essentially just a struct to combine the immutable data outside the mutex

vm/src/warn.rs

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ fn warn_explicit(
6060
Ok(())
6161
}
6262

63-
// filename, module, and registry are new refs, globals is borrowed
64-
// Returns 0 on error (no new refs), 1 on success
63+
/// filename, module, and registry are new refs, globals is borrowed
64+
/// Returns `Ok` on success, or `Err` on error (no new refs)
6565
fn setup_context(
66-
_stack_level: isize,
66+
mut stack_level: isize,
6767
vm: &VirtualMachine,
6868
) -> PyResult<
6969
// filename, lineno, module, registry
@@ -72,32 +72,38 @@ fn setup_context(
7272
let __warningregistry__ = "__warningregistry__";
7373
let __name__ = "__name__";
7474

75-
// Setup globals, filename and lineno.
76-
let frame = vm.current_frame();
75+
let mut f = vm.current_frame().as_deref().cloned();
7776

78-
// PyThreadState *tstate = _PyThreadState_GET();
79-
// PyFrameObject *f = PyThreadState_GetFrame(tstate);
80-
// // Stack level comparisons to Python code is off by one as there is no
81-
// // warnings-related stack level to avoid.
82-
// if (stack_level <= 0 || is_internal_frame(f)) {
83-
// while (--stack_level > 0 && f != NULL) {
84-
// PyFrameObject *back = PyFrame_GetBack(f);
85-
// Py_DECREF(f);
86-
// f = back;
87-
// }
88-
// }
89-
// else {
90-
// while (--stack_level > 0 && f != NULL) {
91-
// f = next_external_frame(f);
92-
// }
93-
// }
77+
// Stack level comparisons to Python code is off by one as there is no
78+
// warnings-related stack level to avoid.
79+
if stack_level <= 0 || f.as_ref().map_or(false, |frame| frame.is_internal_frame()) {
80+
loop {
81+
stack_level -= 1;
82+
if stack_level <= 0 {
83+
break;
84+
}
85+
if let Some(tmp) = f {
86+
f = tmp.f_back(vm);
87+
} else {
88+
break;
89+
}
90+
}
91+
} else {
92+
loop {
93+
stack_level -= 1;
94+
if stack_level <= 0 {
95+
break;
96+
}
97+
if let Some(tmp) = f {
98+
f = tmp.next_external_frame(vm);
99+
} else {
100+
break;
101+
}
102+
}
103+
}
94104

95-
let (globals, filename, lineno) = if let Some(f) = frame {
96-
// TODO:
97-
let lineno = 1;
98-
// *lineno = PyFrame_GetLineNumber(f);
99-
// *filename = code->co_filename;
100-
(f.globals.clone(), f.code.source_path, lineno)
105+
let (globals, filename, lineno) = if let Some(f) = f {
106+
(f.globals.clone(), f.code.source_path, f.f_lineno())
101107
} else {
102108
(vm.current_globals().clone(), vm.ctx.intern_str("sys"), 1)
103109
};

0 commit comments

Comments
 (0)