Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Use _print_exception_bltin in excepthook, register source in linecache
- excepthook: call traceback._print_exception_bltin instead of
  traceback.print_exception to match PyErr_Display behavior
- run_string: register compiled code in linecache._interactive_cache
  so traceback can display source lines and caret indicators
- Remove test_sys_tracebacklimit expectedFailure
  • Loading branch information
youknowone committed Feb 17, 2026
commit 27390dc54ab59c6f14467f508a18f2fa17d7ceef
1 change: 1 addition & 0 deletions .cspell.dict/cpython.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ badsyntax
baseinfo
basetype
binop
bltin
boolop
BUFMAX
BUILDSTDLIB
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,6 @@ def test_getandroidapilevel(self):
self.assertIsInstance(level, int)
self.assertGreater(level, 0)

@unittest.expectedFailure # TODO: RUSTPYTHON
@force_not_colorized
@support.requires_subprocess()
def test_sys_tracebacklimit(self):
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_warnings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,6 @@ def test_envvar_and_command_line(self):
self.assertEqual(stdout,
b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: b"['error::DeprecationWarning']" != b"['default::DeprecationWarning', 'error::DeprecationWarning']"
@force_not_colorized
def test_conflicting_envvar_and_command_line(self):
rc, stdout, stderr = assert_python_failure("-Werror::DeprecationWarning", "-c",
Expand Down
10 changes: 6 additions & 4 deletions crates/vm/src/stdlib/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -825,11 +825,13 @@ mod sys {
let stderr = super::get_stderr(vm)?;
match vm.normalize_exception(exc_type.clone(), exc_val.clone(), exc_tb) {
Ok(exc) => {
// Try Python traceback module first for richer output
// (enables features like keyword typo suggestions in SyntaxError)
// PyErr_Display: try traceback._print_exception_bltin first
if let Ok(tb_mod) = vm.import("traceback", 0)
&& let Ok(print_exc) = tb_mod.get_attr("print_exception", vm)
&& print_exc.call((exc.as_object().to_owned(),), vm).is_ok()
&& let Ok(print_exc_builtin) =
tb_mod.get_attr("_print_exception_bltin", vm)
&& print_exc_builtin
.call((exc.as_object().to_owned(),), vm)
.is_ok()
{
return Ok(());
}
Expand Down
16 changes: 15 additions & 1 deletion crates/vm/src/vm/python_run.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Python code execution functions.

use crate::{
PyResult, VirtualMachine,
AsObject, PyRef, PyResult, VirtualMachine,
builtins::PyCode,
compiler::{self},
scope::Scope,
};
Expand All @@ -22,9 +23,22 @@ impl VirtualMachine {
let code_obj = self
.compile(source, compiler::Mode::Exec, source_path)
.map_err(|err| self.new_syntax_error(&err, Some(source)))?;
// linecache._register_code(code, source, filename)
let _ = self.register_code_in_linecache(&code_obj, source);
self.run_code_obj(code_obj, scope)
}

/// Register a code object's source in linecache._interactive_cache
/// so that traceback can display source lines and caret indicators.
fn register_code_in_linecache(&self, code: &PyRef<PyCode>, source: &str) -> PyResult<()> {
let linecache = self.import("linecache", 0)?;
let register = linecache.get_attr("_register_code", self)?;
let source_str = self.ctx.new_str(source);
let filename = self.ctx.new_str(code.source_path().as_str());
register.call((code.as_object().to_owned(), source_str, filename), self)?;
Ok(())
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

#[deprecated(note = "use run_string instead")]
pub fn run_code_string(&self, scope: Scope, source: &str, source_path: String) -> PyResult {
self.run_string(scope, source, source_path)
Expand Down
Loading