Skip to content

Commit d46f5ba

Browse files
committed
Implement __str__ for OSError
In CPython, __str__ and __repr__ for OSError show different results. This PR try to match this behavior but without the part after the message (in following example is "'123' -> '456'"). ``` In : exc.__repr__() Out: "FileNotFoundError(2, 'No such file or directory')" In : exc.__str__() Out: "[Errno 2] No such file or directory: '123' -> '456'" In : exc.args Out: (2, 'No such file or directory') ```
1 parent a19e876 commit d46f5ba

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

vm/src/exceptions.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,7 @@ impl ExceptionZoo {
745745
"filename" => ctx.none(),
746746
// second exception filename
747747
"filename2" => ctx.none(),
748+
"__str__" => ctx.new_method("__str__", excs.os_error.clone(), os_error_str),
748749
});
749750
// TODO: this isn't really accurate
750751
#[cfg(windows)]
@@ -859,6 +860,21 @@ fn key_error_str(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyStrRef {
859860
}
860861
}
861862

863+
fn os_error_str(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyResult<PyStrRef> {
864+
let args = exc.args();
865+
if args.as_slice().len() == 2 {
866+
// SAFETY: len() == 2 is checked so get_arg 1 or 2 won't panic
867+
let s = format!(
868+
"[Errno {}] {}",
869+
exc.get_arg(0).unwrap().str(vm)?,
870+
exc.get_arg(1).unwrap().str(vm)?
871+
);
872+
Ok(vm.ctx.new_str(s))
873+
} else {
874+
Ok(exc.str(vm))
875+
}
876+
}
877+
862878
fn system_exit_code(exc: PyBaseExceptionRef) -> Option<PyObjectRef> {
863879
exc.args.read().as_slice().first().map(|code| {
864880
match_class!(match code {

0 commit comments

Comments
 (0)