Skip to content

Commit 9c2a469

Browse files
authored
Fix excepthook (RustPython#5830)
1 parent 638d218 commit 9c2a469

5 files changed

Lines changed: 50 additions & 32 deletions

File tree

‎Lib/test/test_exceptions.py‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -701,8 +701,6 @@ def test_str(self):
701701
self.assertTrue(str(Exception('a')))
702702
self.assertTrue(str(Exception('a', 'b')))
703703

704-
# TODO: RUSTPYTHON
705-
@unittest.expectedFailure
706704
def test_exception_cleanup_names(self):
707705
# Make sure the local variable bound to the exception instance by
708706
# an "except" statement is only visible inside the except block.
@@ -725,8 +723,6 @@ def test_exception_cleanup_names2(self):
725723
with self.assertRaises(UnboundLocalError):
726724
e
727725

728-
# TODO: RUSTPYTHON
729-
@unittest.expectedFailure
730726
def testExceptionCleanupState(self):
731727
# Make sure exception state is cleaned up as soon as the except
732728
# block is left. See #2507
@@ -1573,8 +1569,6 @@ def inner():
15731569
gc_collect() # For PyPy or other GCs.
15741570
self.assertEqual(wr(), None)
15751571

1576-
# TODO: RUSTPYTHON
1577-
@unittest.expectedFailure
15781572
@no_tracing
15791573
@unittest.skipIf(sys.platform == 'win32', 'TODO: RUSTPYTHON Windows')
15801574
def test_recursion_error_cleanup(self):

‎Lib/test/test_sys.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,6 @@ def test_excepthook_bytes_filename(self):
167167
self.assertIn(""" text\n""", err)
168168
self.assertTrue(err.endswith("SyntaxError: msg\n"))
169169

170-
# TODO: RUSTPYTHON, print argument error to stderr in sys.excepthook instead of throwing
171-
@unittest.expectedFailure
172170
def test_excepthook(self):
173171
with test.support.captured_output("stderr") as stderr:
174172
sys.excepthook(1, '1', 1)

‎compiler/codegen/src/compile.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,14 @@ impl Compiler<'_> {
13171317
self.compile_statements(body)?;
13181318
emit!(self, Instruction::PopException);
13191319

1320+
// Delete the exception variable if it was bound
1321+
if let Some(alias) = name {
1322+
// Set the variable to None before deleting (as CPython does)
1323+
self.emit_load_const(ConstantData::None);
1324+
self.store_name(alias.as_str())?;
1325+
self.compile_name(alias.as_str(), NameUsage::Delete)?;
1326+
}
1327+
13201328
if !finalbody.is_empty() {
13211329
emit!(self, Instruction::PopBlock); // pop excepthandler block
13221330
// We enter the finally block, without exception.

‎compiler/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap‎

Lines changed: 25 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎vm/src/stdlib/sys.rs‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,24 @@ mod sys {
363363
exc_tb: PyObjectRef,
364364
vm: &VirtualMachine,
365365
) -> PyResult<()> {
366-
let exc = vm.normalize_exception(exc_type, exc_val, exc_tb)?;
367366
let stderr = super::get_stderr(vm)?;
368-
vm.write_exception(&mut crate::py_io::PyWriter(stderr, vm), &exc)
367+
368+
// Try to normalize the exception. If it fails, print error to stderr like CPython
369+
match vm.normalize_exception(exc_type.clone(), exc_val.clone(), exc_tb) {
370+
Ok(exc) => vm.write_exception(&mut crate::py_io::PyWriter(stderr, vm), &exc),
371+
Err(_) => {
372+
// CPython prints error message to stderr instead of raising exception
373+
let type_name = exc_val.class().name();
374+
// TODO: fix error message
375+
let msg = format!(
376+
"TypeError: print_exception(): Exception expected for value, {} found\n",
377+
type_name
378+
);
379+
use crate::py_io::Write;
380+
write!(&mut crate::py_io::PyWriter(stderr, vm), "{}", msg)?;
381+
Ok(())
382+
}
383+
}
369384
}
370385

371386
#[pyfunction(name = "__breakpointhook__")]

0 commit comments

Comments
 (0)