diff --git a/crates/vm/src/vm/mod.rs b/crates/vm/src/vm/mod.rs index ddbf7660f7d..b156e30b738 100644 --- a/crates/vm/src/vm/mod.rs +++ b/crates/vm/src/vm/mod.rs @@ -327,11 +327,17 @@ impl VirtualMachine { let line_buffering = buffered_stdio && (isatty || fd == 2); let newline = if cfg!(windows) { None } else { Some("\n") }; + // stderr uses backslashreplace error handler + let errors: Option<&str> = if fd == 2 { + Some("backslashreplace") + } else { + None + }; let stdio = self.call_method( &io, "TextIOWrapper", - (buf, (), (), newline, line_buffering, write_through), + (buf, (), errors, newline, line_buffering, write_through), )?; let mode = if write { "w" } else { "r" }; stdio.set_attr("mode", self.ctx.new_str(mode), self)?; @@ -853,7 +859,13 @@ impl VirtualMachine { [arg] => match_class!(match arg { ref i @ PyInt => { use num_traits::cast::ToPrimitive; - return i.as_bigint().to_u32().unwrap_or(0); + // Try u32 first, then i32 (for negative values), else -1 for overflow + let code = i + .as_bigint() + .to_u32() + .or_else(|| i.as_bigint().to_i32().map(|v| v as u32)) + .unwrap_or(-1i32 as u32); + return code; } arg => { if self.is_none(arg) { @@ -866,8 +878,11 @@ impl VirtualMachine { _ => args.as_object().repr(self).ok(), }; if let Some(msg) = msg { - let stderr = stdlib::sys::PyStderr(self); - writeln!(stderr, "{msg}"); + // Write using Python's write() to use stderr's error handler (backslashreplace) + if let Ok(stderr) = stdlib::sys::get_stderr(self) { + let _ = self.call_method(&stderr, "write", (msg,)); + let _ = self.call_method(&stderr, "write", ("\n",)); + } } 1 } else if exc.fast_isinstance(self.ctx.exceptions.keyboard_interrupt) {