From e7923f6c75a57d5d6172b7efc10fe1172785478d Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Sun, 22 Jun 2025 20:33:31 +0300 Subject: [PATCH 1/9] Make `new_X_error` recv `impl Into` --- stdlib/src/array.rs | 27 +++++++++++++-------------- stdlib/src/hashlib.rs | 6 +++--- vm/src/builtins/classmethod.rs | 2 +- vm/src/builtins/module.rs | 2 +- vm/src/builtins/object.rs | 2 +- vm/src/builtins/staticmethod.rs | 2 +- vm/src/vm/vm_new.rs | 5 +++-- wasm/lib/src/convert.rs | 2 +- wasm/lib/src/js_module.rs | 20 ++++++-------------- 9 files changed, 30 insertions(+), 38 deletions(-) diff --git a/stdlib/src/array.rs b/stdlib/src/array.rs index db4394e44f5..865ef24c1bc 100644 --- a/stdlib/src/array.rs +++ b/stdlib/src/array.rs @@ -581,7 +581,7 @@ mod array { .chars() .exactly_one() .map(|ch| Self(ch as _)) - .map_err(|_| vm.new_type_error("array item must be unicode character".into())) + .map_err(|_| vm.new_type_error("array item must be unicode character")) } fn byteswap(self) -> Self { Self(self.0.swap_bytes()) @@ -832,9 +832,9 @@ mod array { )) })?; if zelf.read().typecode() != 'u' { - return Err(vm.new_value_error( - "fromunicode() may only be called on unicode type arrays".into(), - )); + return Err( + vm.new_value_error("fromunicode() may only be called on unicode type arrays") + ); } let mut w = zelf.try_resizable(vm)?; let bytes = Self::_unicode_to_wchar_bytes(wtf8, w.itemsize()); @@ -846,9 +846,9 @@ mod array { fn tounicode(&self, vm: &VirtualMachine) -> PyResult { let array = self.array.read(); if array.typecode() != 'u' { - return Err(vm.new_value_error( - "tounicode() may only be called on unicode type arrays".into(), - )); + return Err( + vm.new_value_error("tounicode() may only be called on unicode type arrays") + ); } let bytes = array.get_bytes(); Self::_wchar_bytes_to_string(bytes, self.itemsize(), vm) @@ -1500,7 +1500,7 @@ mod array { .unwrap_or(u8::MAX) .try_into() .map_err(|_| { - vm.new_value_error("third argument must be a valid machine format code.".into()) + vm.new_value_error("third argument must be a valid machine format code.") }) } } @@ -1572,11 +1572,11 @@ mod array { fn check_type_code(spec: PyStrRef, vm: &VirtualMachine) -> PyResult { let spec = spec.as_str().chars().exactly_one().map_err(|_| { vm.new_type_error( - "_array_reconstructor() argument 2 must be a unicode character, not str".into(), + "_array_reconstructor() argument 2 must be a unicode character, not str", ) })?; ArrayContentType::from_char(spec) - .map_err(|_| vm.new_value_error("second argument must be a valid type code".into())) + .map_err(|_| vm.new_value_error("second argument must be a valid type code")) } macro_rules! chunk_to_obj { @@ -1609,7 +1609,7 @@ mod array { let format = args.mformat_code; let bytes = args.items.as_bytes(); if bytes.len() % format.item_size() != 0 { - return Err(vm.new_value_error("bytes length not a multiple of item size".into())); + return Err(vm.new_value_error("bytes length not a multiple of item size")); } if MachineFormatCode::from_typecode(array.typecode()) == Some(format) { array.frombytes(bytes); @@ -1642,9 +1642,8 @@ mod array { })?, MachineFormatCode::Utf16 { big_endian } => { let utf16: Vec<_> = chunks.map(|b| chunk_to_obj!(b, u16, big_endian)).collect(); - let s = String::from_utf16(&utf16).map_err(|_| { - vm.new_unicode_encode_error("items cannot decode as utf16".into()) - })?; + let s = String::from_utf16(&utf16) + .map_err(|_| vm.new_unicode_encode_error("items cannot decode as utf16"))?; let bytes = PyArray::_unicode_to_wchar_bytes((*s).as_ref(), array.itemsize()); array.frombytes_move(bytes); } diff --git a/stdlib/src/hashlib.rs b/stdlib/src/hashlib.rs index 586d825b2c3..f996177eb9f 100644 --- a/stdlib/src/hashlib.rs +++ b/stdlib/src/hashlib.rs @@ -107,7 +107,7 @@ pub mod _hashlib { #[pyslot] fn slot_new(_cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult { - Err(vm.new_type_error("cannot create '_hashlib.HASH' instances".into())) + Err(vm.new_type_error("cannot create '_hashlib.HASH' instances")) } #[pygetset] @@ -171,7 +171,7 @@ pub mod _hashlib { #[pyslot] fn slot_new(_cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult { - Err(vm.new_type_error("cannot create '_hashlib.HASHXOF' instances".into())) + Err(vm.new_type_error("cannot create '_hashlib.HASHXOF' instances")) } #[pygetset] @@ -337,7 +337,7 @@ pub mod _hashlib { #[pyfunction] fn hmac_new(_args: NewHMACHashArgs, vm: &VirtualMachine) -> PyResult { - Err(vm.new_type_error("cannot create 'hmac' instances".into())) // TODO: RUSTPYTHON support hmac + Err(vm.new_type_error("cannot create 'hmac' instances")) // TODO: RUSTPYTHON support hmac } pub trait ThreadSafeDynDigest: DynClone + DynDigest + Sync + Send {} diff --git a/vm/src/builtins/classmethod.rs b/vm/src/builtins/classmethod.rs index 94b6e0ca9f1..84a93c88c94 100644 --- a/vm/src/builtins/classmethod.rs +++ b/vm/src/builtins/classmethod.rs @@ -169,7 +169,7 @@ impl Representable for PyClassMethod { .map(|n| n.as_str()), class.module(vm).downcast_ref::().map(|m| m.as_str()), ) { - (None, _) => return Err(vm.new_type_error("Unknown qualified name".into())), + (None, _) => return Err(vm.new_type_error("Unknown qualified name")), (Some(qualname), Some(module)) if module != "builtins" => { format!("<{module}.{qualname}({callable})>") } diff --git a/vm/src/builtins/module.rs b/vm/src/builtins/module.rs index 2cdc13a59cc..b142617d1f8 100644 --- a/vm/src/builtins/module.rs +++ b/vm/src/builtins/module.rs @@ -207,7 +207,7 @@ impl Representable for PyModule { let module_repr = importlib.get_attr("_module_repr", vm)?; let repr = module_repr.call((zelf.to_owned(),), vm)?; repr.downcast() - .map_err(|_| vm.new_type_error("_module_repr did not return a string".into())) + .map_err(|_| vm.new_type_error("_module_repr did not return a string")) } #[cold] diff --git a/vm/src/builtins/object.rs b/vm/src/builtins/object.rs index 5bf47f9fd3a..6b1b0bb1304 100644 --- a/vm/src/builtins/object.rs +++ b/vm/src/builtins/object.rs @@ -350,7 +350,7 @@ impl PyBaseObject { .map(|n| n.as_str()), class.module(vm).downcast_ref::().map(|m| m.as_str()), ) { - (None, _) => Err(vm.new_type_error("Unknown qualified name".into())), + (None, _) => Err(vm.new_type_error("Unknown qualified name")), (Some(qualname), Some(module)) if module != "builtins" => Ok(PyStr::from(format!( "<{}.{} object at {:#x}>", module, diff --git a/vm/src/builtins/staticmethod.rs b/vm/src/builtins/staticmethod.rs index 6c19a42a337..1e16cfd8ab5 100644 --- a/vm/src/builtins/staticmethod.rs +++ b/vm/src/builtins/staticmethod.rs @@ -153,7 +153,7 @@ impl Representable for PyStaticMethod { .map(|n| n.as_str()), class.module(vm).downcast_ref::().map(|m| m.as_str()), ) { - (None, _) => Err(vm.new_type_error("Unknown qualified name".into())), + (None, _) => Err(vm.new_type_error("Unknown qualified name")), (Some(qualname), Some(module)) if module != "builtins" => { Ok(format!("<{module}.{qualname}({callable})>")) } diff --git a/vm/src/vm/vm_new.rs b/vm/src/vm/vm_new.rs index 414c6cb526b..4285e225b06 100644 --- a/vm/src/vm/vm_new.rs +++ b/vm/src/vm/vm_new.rs @@ -22,9 +22,10 @@ macro_rules! define_exception_fn { stringify!($python_repr), " object.\nUseful for raising errors from python functions implemented in rust." )] - pub fn $fn_name(&self, msg: String) -> PyBaseExceptionRef { + pub fn $fn_name(&self, msg: impl Into) -> PyBaseExceptionRef + { let err = self.ctx.exceptions.$attr.to_owned(); - self.new_exception_msg(err, msg) + self.new_exception_msg(err, msg.into()) } }; } diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs index bccf5564fa7..9d83f70cebc 100644 --- a/wasm/lib/src/convert.rs +++ b/wasm/lib/src/convert.rs @@ -57,7 +57,7 @@ pub fn py_err_to_js_err(vm: &VirtualMachine, py_err: &PyBaseExceptionRef) -> JsV pub fn js_py_typeerror(vm: &VirtualMachine, js_err: JsValue) -> PyBaseExceptionRef { let msg = js_err.unchecked_into::().to_string(); - vm.new_type_error(msg.into()) + vm.new_type_error(msg) } pub fn js_err_to_py_err(vm: &VirtualMachine, js_err: &JsValue) -> PyBaseExceptionRef { diff --git a/wasm/lib/src/js_module.rs b/wasm/lib/src/js_module.rs index 5a3ac4025be..1d8ca0961ca 100644 --- a/wasm/lib/src/js_module.rs +++ b/wasm/lib/src/js_module.rs @@ -136,9 +136,7 @@ mod _js { } else if proto.value.is_null() { Object::create(proto.value.unchecked_ref()) } else { - return Err( - vm.new_value_error("prototype must be an Object or null".to_owned()) - ); + return Err(vm.new_value_error("prototype must be an Object or null")); } } else { Object::new() @@ -184,7 +182,7 @@ mod _js { let func = self .value .dyn_ref::() - .ok_or_else(|| vm.new_type_error("JS value is not callable".to_owned()))?; + .ok_or_else(|| vm.new_type_error("JS value is not callable"))?; let js_args = args.iter().map(|x| -> &PyJsValue { x }).collect::(); let res = match opts.this { Some(this) => Reflect::apply(func, &this.value, &js_args), @@ -216,7 +214,7 @@ mod _js { let ctor = self .value .dyn_ref::() - .ok_or_else(|| vm.new_type_error("JS value is not callable".to_owned()))?; + .ok_or_else(|| vm.new_type_error("JS value is not callable"))?; let proto = opts .prototype .as_ref() @@ -361,9 +359,7 @@ mod _js { #[pymethod] fn destroy(&self, vm: &VirtualMachine) -> PyResult<()> { let (closure, _) = self.closure.replace(None).ok_or_else(|| { - vm.new_value_error( - "can't destroy closure has already been destroyed or detached".to_owned(), - ) + vm.new_value_error("can't destroy closure has already been destroyed or detached") })?; drop(closure); self.destroyed.set(true); @@ -372,9 +368,7 @@ mod _js { #[pymethod] fn detach(&self, vm: &VirtualMachine) -> PyResult { let (closure, js_val) = self.closure.replace(None).ok_or_else(|| { - vm.new_value_error( - "can't detach closure has already been detached or destroyed".to_owned(), - ) + vm.new_value_error("can't detach closure has already been detached or destroyed") })?; closure.forget(); self.detached.set(true); @@ -574,9 +568,7 @@ mod _js { match self.obj.take() { Some(prom) => { if val.is_some() { - Err(vm.new_type_error( - "can't send non-None value to an AwaitPromise".to_owned(), - )) + Err(vm.new_type_error("can't send non-None value to an AwaitPromise")) } else { Ok(PyIterReturn::Return(prom)) } From 485dea281031eacea7cdc8b514c8011a495930a4 Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Sun, 22 Jun 2025 20:40:37 +0300 Subject: [PATCH 2/9] Maks the rest of the methods to be generic --- vm/src/vm/vm_new.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/vm/src/vm/vm_new.rs b/vm/src/vm/vm_new.rs index 4285e225b06..b70e5b79865 100644 --- a/vm/src/vm/vm_new.rs +++ b/vm/src/vm/vm_new.rs @@ -25,7 +25,7 @@ macro_rules! define_exception_fn { pub fn $fn_name(&self, msg: impl Into) -> PyBaseExceptionRef { let err = self.ctx.exceptions.$attr.to_owned(); - self.new_exception_msg(err, msg.into()) + self.new_exception_msg(err, msg) } }; } @@ -117,8 +117,12 @@ impl VirtualMachine { /// type is passed in, it may not be fully initialized; try using /// [`vm.invoke_exception()`][Self::invoke_exception] or /// [`exceptions::ExceptionCtor`][crate::exceptions::ExceptionCtor] instead. - pub fn new_exception_msg(&self, exc_type: PyTypeRef, msg: String) -> PyBaseExceptionRef { - self.new_exception(exc_type, vec![self.ctx.new_str(msg).into()]) + pub fn new_exception_msg( + &self, + exc_type: PyTypeRef, + msg: impl Into, + ) -> PyBaseExceptionRef { + self.new_exception(exc_type, vec![self.ctx.new_str(msg.into()).into()]) } /// Instantiate an exception with `msg` as the only argument and `dict` for object @@ -129,14 +133,14 @@ impl VirtualMachine { pub fn new_exception_msg_dict( &self, exc_type: PyTypeRef, - msg: String, + msg: impl Into, dict: PyDictRef, ) -> PyBaseExceptionRef { PyRef::new_ref( // TODO: this constructor might be invalid, because multiple // exception (even builtin ones) are using custom constructors, // see `OSError` as an example: - PyBaseException::new(vec![self.ctx.new_str(msg).into()], self), + PyBaseException::new(vec![self.ctx.new_str(msg.into()).into()], self), exc_type, Some(dict), ) @@ -156,7 +160,7 @@ impl VirtualMachine { attribute_error } - pub fn new_name_error(&self, msg: String, name: PyStrRef) -> PyBaseExceptionRef { + pub fn new_name_error(&self, msg: impl Into, name: PyStrRef) -> PyBaseExceptionRef { let name_error_type = self.ctx.exceptions.name_error.to_owned(); let name_error = self.new_exception_msg(name_error_type, msg); name_error.as_object().set_attr("name", name, self).unwrap(); @@ -201,13 +205,16 @@ impl VirtualMachine { )) } - pub fn new_errno_error(&self, errno: i32, msg: String) -> PyBaseExceptionRef { + pub fn new_errno_error(&self, errno: i32, msg: impl Into) -> PyBaseExceptionRef { let vm = self; let exc_type = crate::exceptions::errno_to_exc_type(errno, vm).unwrap_or(vm.ctx.exceptions.os_error); let errno_obj = vm.new_pyobj(errno); - vm.new_exception(exc_type.to_owned(), vec![errno_obj, vm.new_pyobj(msg)]) + vm.new_exception( + exc_type.to_owned(), + vec![errno_obj, vm.new_pyobj(msg.into())], + ) } pub fn new_unicode_decode_error_real( @@ -467,7 +474,7 @@ impl VirtualMachine { self.new_syntax_error_maybe_incomplete(error, source, false) } - pub fn new_import_error(&self, msg: String, name: PyStrRef) -> PyBaseExceptionRef { + pub fn new_import_error(&self, msg: impl Into, name: PyStrRef) -> PyBaseExceptionRef { let import_error = self.ctx.exceptions.import_error.to_owned(); let exc = self.new_exception_msg(import_error, msg); exc.as_object().set_attr("name", name, self).unwrap(); From 93de8d8169190123ddfee198e1cc5f77ed5a199b Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Sun, 22 Jun 2025 20:52:52 +0300 Subject: [PATCH 3/9] remove to_owned --- vm/src/stdlib/io.rs | 87 +++++++++++++++++++-------------------------- vm/src/vm/vm_ops.rs | 40 +++++++++++---------- 2 files changed, 58 insertions(+), 69 deletions(-) diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 91efb4481b1..ee6a846bddb 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -79,14 +79,12 @@ impl TryFromObject for Fildes { Ok(i) => i, Err(obj) => { let fileno_meth = vm.get_attribute_opt(obj, "fileno")?.ok_or_else(|| { - vm.new_type_error( - "argument must be an int, or have a fileno() method.".to_owned(), - ) + vm.new_type_error("argument must be an int, or have a fileno() method.") })?; fileno_meth .call((), vm)? .downcast() - .map_err(|_| vm.new_type_error("fileno() returned a non-integer".to_owned()))? + .map_err(|_| vm.new_type_error("fileno() returned a non-integer"))? } }; let fd = int.try_to_primitive(vm)?; @@ -168,7 +166,7 @@ mod _io { fn ensure_unclosed(file: &PyObject, msg: &str, vm: &VirtualMachine) -> PyResult<()> { if file.get_attr("closed", vm)?.try_to_bool(vm)? { - Err(vm.new_value_error(msg.to_owned())) + Err(vm.new_value_error(msg)) } else { Ok(()) } @@ -226,7 +224,7 @@ mod _io { } pub(super) fn io_closed_error(vm: &VirtualMachine) -> PyBaseExceptionRef { - vm.new_value_error("I/O operation on closed file".to_owned()) + vm.new_value_error("I/O operation on closed file") } #[pyattr] @@ -243,7 +241,7 @@ mod _io { } OptionalArg::Present(1) => SeekFrom::Current(offset.try_into_value(vm)?), OptionalArg::Present(2) => SeekFrom::End(offset.try_into_value(vm)?), - _ => return Err(vm.new_value_error("invalid value for how".to_owned())), + _ => return Err(vm.new_value_error("invalid value for how")), }; Ok(seek) } @@ -694,9 +692,9 @@ mod _io { slice.copy_from_slice(&data); Ok(data.len()) } - None => Err(vm.new_value_error( - "readinto: buffer and read data have different lengths".to_owned(), - )), + None => { + Err(vm.new_value_error("readinto: buffer and read data have different lengths")) + } } } #[pymethod] @@ -769,7 +767,7 @@ mod _io { } else { "I/O operation on uninitialized object" }; - Err(vm.new_value_error(msg.to_owned())) + Err(vm.new_value_error(msg)) } } @@ -1399,7 +1397,7 @@ mod _io { fn lock(&self, vm: &VirtualMachine) -> PyResult> { self.data() .lock() - .ok_or_else(|| vm.new_runtime_error("reentrant call inside buffered io".to_owned())) + .ok_or_else(|| vm.new_runtime_error("reentrant call inside buffered io")) } #[pyslot] @@ -1430,9 +1428,7 @@ mod _io { let buffer_size = match buffer_size { OptionalArg::Present(i) if i <= 0 => { - return Err( - vm.new_value_error("buffer size must be strictly positive".to_owned()) - ); + return Err(vm.new_value_error("buffer size must be strictly positive")); } OptionalArg::Present(i) => i as usize, OptionalArg::Missing => DEFAULT_BUFFER_SIZE, @@ -1519,7 +1515,7 @@ mod _io { data.flags.insert(BufferedFlags::DETACHED); data.raw .take() - .ok_or_else(|| vm.new_value_error("raw stream has been detached".to_owned())) + .ok_or_else(|| vm.new_value_error("raw stream has been detached")) } #[pymethod] fn seekable(&self, vm: &VirtualMachine) -> PyResult { @@ -1621,7 +1617,7 @@ mod _io { let raw = data.check_init(vm)?; let n = size.size.map(|s| *s).unwrap_or(-1); if n < -1 { - return Err(vm.new_value_error("read length must be non-negative or -1".to_owned())); + return Err(vm.new_value_error("read length must be non-negative or -1")); } ensure_unclosed(raw, "read of closed file", vm)?; match n.to_usize() { @@ -2282,13 +2278,13 @@ mod _io { ) -> PyResult>> { self.data .lock() - .ok_or_else(|| vm.new_runtime_error("reentrant call inside textio".to_owned())) + .ok_or_else(|| vm.new_runtime_error("reentrant call inside textio")) } fn lock(&self, vm: &VirtualMachine) -> PyResult> { let lock = self.lock_opt(vm)?; PyThreadMutexGuard::try_map(lock, |x| x.as_mut()) - .map_err(|_| vm.new_value_error("I/O operation on uninitialized object".to_owned())) + .map_err(|_| vm.new_value_error("I/O operation on uninitialized object")) } #[allow(clippy::type_complexity)] @@ -2421,9 +2417,7 @@ mod _io { let mut textio = self.lock(vm)?; match chunk_size { PySetterValue::Assign(chunk_size) => textio.chunk_size = chunk_size, - PySetterValue::Delete => { - Err(vm.new_attribute_error("cannot delete attribute".to_owned()))? - } + PySetterValue::Delete => Err(vm.new_attribute_error("cannot delete attribute"))?, }; // TODO: RUSTPYTHON // Change chunk_size type, validate it manually and throws ValueError if invalid. @@ -2511,7 +2505,7 @@ mod _io { vm.call_method(zelf.as_object(), "flush", ())?; let cookie_obj = crate::builtins::PyIntRef::try_from_object(vm, cookie)?; let cookie = TextIOCookie::parse(cookie_obj.as_bigint()) - .ok_or_else(|| vm.new_value_error("invalid cookie".to_owned()))?; + .ok_or_else(|| vm.new_value_error("invalid cookie"))?; let mut textio = zelf.lock(vm)?; vm.call_method(&textio.buffer, "seek", (cookie.start_pos,))?; textio.set_decoded_chars(None); @@ -2528,7 +2522,7 @@ mod _io { } = *textio; let decoder = decoder .as_ref() - .ok_or_else(|| vm.new_value_error("invalid cookie".to_owned()))?; + .ok_or_else(|| vm.new_value_error("invalid cookie"))?; let input_chunk = vm.call_method(buffer, "read", (cookie.bytes_to_feed,))?; let input_chunk: PyBytesRef = input_chunk.downcast().map_err(|obj| { vm.new_type_error(format!( @@ -2544,7 +2538,7 @@ mod _io { .is_code_point_boundary(cookie.bytes_to_skip as usize); textio.set_decoded_chars(Some(decoded)); if !pos_is_valid { - return Err(vm.new_os_error("can't restore logical file position".to_owned())); + return Err(vm.new_os_error("can't restore logical file position")); } textio.decoded_chars_used = cookie.num_to_skip(); } else { @@ -2567,7 +2561,7 @@ mod _io { )); } if !textio.telling { - return Err(vm.new_os_error("telling position disabled by next() call".to_owned())); + return Err(vm.new_os_error("telling position disabled by next() call")); } textio.write_pending(vm)?; drop(textio); @@ -2656,9 +2650,7 @@ mod _io { let final_decoded_chars = n_decoded.chars + decoded.char_len(); cookie.need_eof = true; if final_decoded_chars < num_to_skip.chars { - return Err( - vm.new_os_error("can't reconstruct logical file position".to_owned()) - ); + return Err(vm.new_os_error("can't reconstruct logical file position")); } } } @@ -3010,7 +3002,7 @@ mod _io { fn parse_decoder_state(state: PyObjectRef, vm: &VirtualMachine) -> PyResult<(PyBytesRef, i32)> { use crate::builtins::{PyTuple, int}; - let state_err = || vm.new_type_error("illegal decoder state".to_owned()); + let state_err = || vm.new_type_error("illegal decoder state"); let state = state.downcast::().map_err(|_| state_err())?; match state.as_slice() { [buf, flags] => { @@ -3220,7 +3212,7 @@ mod _io { ) -> PyResult>> { self.data .lock() - .ok_or_else(|| vm.new_runtime_error("reentrant call inside nldecoder".to_owned())) + .ok_or_else(|| vm.new_runtime_error("reentrant call inside nldecoder")) } fn lock( @@ -3228,9 +3220,8 @@ mod _io { vm: &VirtualMachine, ) -> PyResult> { let lock = self.lock_opt(vm)?; - PyThreadMutexGuard::try_map(lock, |x| x.as_mut()).map_err(|_| { - vm.new_value_error("I/O operation on uninitialized nldecoder".to_owned()) - }) + PyThreadMutexGuard::try_map(lock, |x| x.as_mut()) + .map_err(|_| vm.new_value_error("I/O operation on uninitialized nldecoder")) } #[pymethod] @@ -3466,15 +3457,14 @@ mod _io { let bytes = data.as_bytes(); self.buffer(vm)? .write(bytes) - .ok_or_else(|| vm.new_type_error("Error Writing String".to_owned())) + .ok_or_else(|| vm.new_type_error("Error Writing String")) } // return the entire contents of the underlying #[pymethod] fn getvalue(&self, vm: &VirtualMachine) -> PyResult { let bytes = self.buffer(vm)?.getvalue(); - Wtf8Buf::from_bytes(bytes) - .map_err(|_| vm.new_value_error("Error Retrieving Value".to_owned())) + Wtf8Buf::from_bytes(bytes).map_err(|_| vm.new_value_error("Error Retrieving Value")) } // skip to the jth position @@ -3498,7 +3488,7 @@ mod _io { let data = self.buffer(vm)?.read(size.to_usize()).unwrap_or_default(); let value = Wtf8Buf::from_bytes(data) - .map_err(|_| vm.new_value_error("Error Retrieving Value".to_owned()))?; + .map_err(|_| vm.new_value_error("Error Retrieving Value"))?; Ok(value) } @@ -3512,8 +3502,7 @@ mod _io { // TODO size should correspond to the number of characters, at the moments its the number of // bytes. let input = self.buffer(vm)?.readline(size.to_usize(), vm)?; - Wtf8Buf::from_bytes(input) - .map_err(|_| vm.new_value_error("Error Retrieving Value".to_owned())) + Wtf8Buf::from_bytes(input).map_err(|_| vm.new_value_error("Error Retrieving Value")) } #[pymethod] @@ -3580,7 +3569,7 @@ mod _io { fn write(&self, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult { let mut buffer = self.try_resizable(vm)?; data.with_ref(|b| buffer.write(b)) - .ok_or_else(|| vm.new_type_error("Error Writing Bytes".to_owned())) + .ok_or_else(|| vm.new_type_error("Error Writing Bytes")) } // Retrieves the entire bytes object value from the underlying buffer @@ -3606,7 +3595,7 @@ mod _io { let ret = buf .cursor .read(&mut obj.borrow_buf_mut()) - .map_err(|_| vm.new_value_error("Error readinto from Take".to_owned()))?; + .map_err(|_| vm.new_value_error("Error readinto from Take"))?; Ok(ret) } @@ -3874,7 +3863,7 @@ mod _io { None }; if let Some(msg) = msg { - return Err(vm.new_value_error(msg.to_owned())); + return Err(vm.new_value_error(msg)); } } @@ -3923,9 +3912,7 @@ mod _io { if buffering == 0 { let ret = match mode.encode { - EncodeMode::Text => { - Err(vm.new_value_error("can't have unbuffered text I/O".to_owned())) - } + EncodeMode::Text => Err(vm.new_value_error("can't have unbuffered text I/O")), EncodeMode::Bytes => Ok(raw), }; return ret; @@ -4196,7 +4183,7 @@ mod fileio { let arg_fd = if let Some(i) = name.payload::() { let fd = i.try_to_primitive(vm)?; if fd < 0 { - return Err(vm.new_value_error("negative file descriptor".to_owned())); + return Err(vm.new_value_error("negative file descriptor")); } Some(fd) } else { @@ -4217,15 +4204,13 @@ mod fileio { } else { zelf.closefd.store(true); if !args.closefd { - return Err( - vm.new_value_error("Cannot use closefd=False with file name".to_owned()) - ); + return Err(vm.new_value_error("Cannot use closefd=False with file name")); } if let Some(opener) = args.opener { let fd = opener.call((name.clone(), flags), vm)?; if !fd.fast_isinstance(vm.ctx.types.int_type) { - return Err(vm.new_type_error("expected integer from opener".to_owned())); + return Err(vm.new_type_error("expected integer from opener")); } let fd = i32::try_from_object(vm, fd)?; if fd < 0 { diff --git a/vm/src/vm/vm_ops.rs b/vm/src/vm/vm_ops.rs index df33e822aa1..00ba2d0f664 100644 --- a/vm/src/vm/vm_ops.rs +++ b/vm/src/vm/vm_ops.rs @@ -128,7 +128,7 @@ impl VirtualMachine { })? .try_to_primitive::(self)?; if hint.is_negative() { - Err(self.new_value_error("__length_hint__() should return >= 0".to_owned())) + Err(self.new_value_error("__length_hint__() should return >= 0")) } else { Ok(Some(hint as usize)) } @@ -142,7 +142,7 @@ impl VirtualMachine { } else { let n = n as usize; if length > crate::stdlib::sys::MAXSIZE as usize / n { - Err(self.new_overflow_error("repeated value are too long".to_owned())) + Err(self.new_overflow_error("repeated value are too long")) } else { Ok(n) } @@ -407,16 +407,18 @@ impl VirtualMachine { return Ok(result); } if let Ok(seq_a) = PySequence::try_protocol(a, self) { - let n = - b.try_index(self)?.as_bigint().to_isize().ok_or_else(|| { - self.new_overflow_error("repeated bytes are too long".to_owned()) - })?; + let n = b + .try_index(self)? + .as_bigint() + .to_isize() + .ok_or_else(|| self.new_overflow_error("repeated bytes are too long"))?; return seq_a.repeat(n, self); } else if let Ok(seq_b) = PySequence::try_protocol(b, self) { - let n = - a.try_index(self)?.as_bigint().to_isize().ok_or_else(|| { - self.new_overflow_error("repeated bytes are too long".to_owned()) - })?; + let n = a + .try_index(self)? + .as_bigint() + .to_isize() + .ok_or_else(|| self.new_overflow_error("repeated bytes are too long"))?; return seq_b.repeat(n, self); } Err(self.new_unsupported_bin_op_error(a, b, "*")) @@ -433,16 +435,18 @@ impl VirtualMachine { return Ok(result); } if let Ok(seq_a) = PySequence::try_protocol(a, self) { - let n = - b.try_index(self)?.as_bigint().to_isize().ok_or_else(|| { - self.new_overflow_error("repeated bytes are too long".to_owned()) - })?; + let n = b + .try_index(self)? + .as_bigint() + .to_isize() + .ok_or_else(|| self.new_overflow_error("repeated bytes are too long"))?; return seq_a.inplace_repeat(n, self); } else if let Ok(seq_b) = PySequence::try_protocol(b, self) { - let n = - a.try_index(self)?.as_bigint().to_isize().ok_or_else(|| { - self.new_overflow_error("repeated bytes are too long".to_owned()) - })?; + let n = a + .try_index(self)? + .as_bigint() + .to_isize() + .ok_or_else(|| self.new_overflow_error("repeated bytes are too long"))?; /* Note that the right hand operand should not be * mutated in this case so inplace_repeat is not * used. */ From 8d7deb2479f98f26a5379f3f2b315b4e3e1696f4 Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Mon, 23 Jun 2025 11:36:01 +0300 Subject: [PATCH 4/9] Remove `.to_owned()` from more files --- vm/src/buffer.rs | 2 +- vm/src/exceptions.rs | 12 +++++------- vm/src/format.rs | 22 ++++++++++------------ 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/vm/src/buffer.rs b/vm/src/buffer.rs index 5c78975cb86..2d4ea7c0973 100644 --- a/vm/src/buffer.rs +++ b/vm/src/buffer.rs @@ -549,7 +549,7 @@ impl Packable for f16 { // "from_f64 should be preferred in any non-`const` context" except it gives the wrong result :/ let f_16 = f16::from_f64_const(f_64); if f_16.is_infinite() != f_64.is_infinite() { - return Err(vm.new_overflow_error("float too large to pack with e format".to_owned())); + return Err(vm.new_overflow_error("float too large to pack with e format")); } f_16.to_bits().pack_int::(data); Ok(()) diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 885f82b71ad..2c3d2261441 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -427,8 +427,7 @@ impl ExceptionCtor { match (self, exc_inst) { // both are instances; which would we choose? (Self::Instance(_exc_a), Some(_exc_b)) => { - Err(vm - .new_type_error("instance exception may not have a separate value".to_owned())) + Err(vm.new_type_error("instance exception may not have a separate value")) } // if the "type" is an instance and the value isn't, use the "type" (Self::Instance(exc), None) => Ok(exc), @@ -653,7 +652,7 @@ impl PyRef { if !vm.is_none(&state) { let dict = state .downcast::() - .map_err(|_| vm.new_type_error("state is not a dictionary".to_owned()))?; + .map_err(|_| vm.new_type_error("state is not a dictionary"))?; for (key, value) in &dict { let key_str = key.str(vm)?; @@ -672,7 +671,7 @@ impl Constructor for PyBaseException { fn py_new(cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult { if cls.is(PyBaseException::class(&vm.ctx)) && !args.kwargs.is_empty() { - return Err(vm.new_type_error("BaseException() takes no keyword arguments".to_owned())); + return Err(vm.new_type_error("BaseException() takes no keyword arguments")); } PyBaseException::new(args.args, vm) .into_ref_with_type(vm, cls) @@ -1130,7 +1129,7 @@ impl serde::Serialize for SerializeException<'_, '_> { } pub fn cstring_error(vm: &VirtualMachine) -> PyBaseExceptionRef { - vm.new_value_error("embedded null character".to_owned()) + vm.new_value_error("embedded null character") } impl ToPyException for std::ffi::NulError { @@ -1334,8 +1333,7 @@ pub(super) mod types { // Check for any remaining invalid keyword arguments if let Some(invalid_key) = kwargs.keys().next() { return Err(vm.new_type_error(format!( - "'{}' is an invalid keyword argument for ImportError", - invalid_key + "'{invalid_key}' is an invalid keyword argument for ImportError" ))); } diff --git a/vm/src/format.rs b/vm/src/format.rs index 3349ee854e2..77e2f3c5f01 100644 --- a/vm/src/format.rs +++ b/vm/src/format.rs @@ -28,17 +28,17 @@ impl IntoPyException for FormatSpecError { vm.new_value_error(msg) } FormatSpecError::PrecisionNotAllowed => { - vm.new_value_error("Precision not allowed in integer format specifier".to_owned()) + vm.new_value_error("Precision not allowed in integer format specifier") } FormatSpecError::NotAllowed(s) => { let msg = format!("{s} not allowed with integer format specifier 'c'"); vm.new_value_error(msg) } FormatSpecError::UnableToConvert => { - vm.new_value_error("Unable to convert int to float".to_owned()) + vm.new_value_error("Unable to convert int to float") } FormatSpecError::CodeNotInRange => { - vm.new_overflow_error("%c arg not in range(0x110000)".to_owned()) + vm.new_overflow_error("%c arg not in range(0x110000)") } FormatSpecError::NotImplemented(c, s) => { let msg = format!("Format code '{c}' for object of type '{s}' not implemented yet"); @@ -52,9 +52,9 @@ impl ToPyException for FormatParseError { fn to_pyexception(&self, vm: &VirtualMachine) -> PyBaseExceptionRef { match self { FormatParseError::UnmatchedBracket => { - vm.new_value_error("expected '}' before end of string".to_owned()) + vm.new_value_error("expected '}' before end of string") } - _ => vm.new_value_error("Unexpected error parsing format string".to_owned()), + _ => vm.new_value_error("Unexpected error parsing format string"), } } } @@ -130,8 +130,7 @@ pub(crate) fn format( FieldType::Auto => { if seen_index { return Err(vm.new_value_error( - "cannot switch from manual field specification to automatic field numbering" - .to_owned(), + "cannot switch from manual field specification to automatic field numbering", )); } auto_argument_index += 1; @@ -139,13 +138,12 @@ pub(crate) fn format( .args .get(auto_argument_index - 1) .cloned() - .ok_or_else(|| vm.new_index_error("tuple index out of range".to_owned())) + .ok_or_else(|| vm.new_index_error("tuple index out of range")) } FieldType::Index(index) => { if auto_argument_index != 0 { return Err(vm.new_value_error( - "cannot switch from automatic field numbering to manual field specification" - .to_owned(), + "cannot switch from automatic field numbering to manual field specification", )); } seen_index = true; @@ -153,7 +151,7 @@ pub(crate) fn format( .args .get(index) .cloned() - .ok_or_else(|| vm.new_index_error("tuple index out of range".to_owned())) + .ok_or_else(|| vm.new_index_error("tuple index out of range")) } FieldType::Keyword(keyword) => keyword .as_str() @@ -170,7 +168,7 @@ pub(crate) fn format_map( ) -> PyResult { format_internal(vm, format, &mut |field_type| match field_type { FieldType::Auto | FieldType::Index(_) => { - Err(vm.new_value_error("Format string contains positional fields".to_owned())) + Err(vm.new_value_error("Format string contains positional fields")) } FieldType::Keyword(keyword) => dict.get_item(&keyword, vm), }) From 9e83d439f0abe93639d630f70dce5efbe536aac6 Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Mon, 23 Jun 2025 11:39:14 +0300 Subject: [PATCH 5/9] Make `new_struct_error` to be generic as well --- vm/src/buffer.rs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/vm/src/buffer.rs b/vm/src/buffer.rs index 2d4ea7c0973..b585bfbcde5 100644 --- a/vm/src/buffer.rs +++ b/vm/src/buffer.rs @@ -497,15 +497,12 @@ fn get_int_or_index(vm: &VirtualMachine, arg: PyObjectRef) -> PyResult where T: PrimInt + for<'a> TryFrom<&'a BigInt>, { - let index = arg.try_index_opt(vm).unwrap_or_else(|| { - Err(new_struct_error( - vm, - "required argument is not an integer".to_owned(), - )) - })?; + let index = arg + .try_index_opt(vm) + .unwrap_or_else(|| Err(new_struct_error(vm, "required argument is not an integer")))?; index .try_to_primitive(vm) - .map_err(|_| new_struct_error(vm, "argument out of range".to_owned())) + .map_err(|_| new_struct_error(vm, "argument out of range")) } make_pack_prim_int!(i8); @@ -586,12 +583,11 @@ impl Packable for bool { fn pack_char(vm: &VirtualMachine, arg: PyObjectRef, data: &mut [u8]) -> PyResult<()> { let v = PyBytesRef::try_from_object(vm, arg)?; - let ch = *v.as_bytes().iter().exactly_one().map_err(|_| { - new_struct_error( - vm, - "char format requires a bytes object of length 1".to_owned(), - ) - })?; + let ch = *v + .as_bytes() + .iter() + .exactly_one() + .map_err(|_| new_struct_error(vm, "char format requires a bytes object of length 1"))?; data[0] = ch; Ok(()) } @@ -647,7 +643,7 @@ pub fn struct_error_type(vm: &VirtualMachine) -> &'static PyTypeRef { INSTANCE.get_or_init(|| vm.ctx.new_exception_type("struct", "error", None)) } -pub fn new_struct_error(vm: &VirtualMachine, msg: String) -> PyBaseExceptionRef { +pub fn new_struct_error(vm: &VirtualMachine, msg: impl Into) -> PyBaseExceptionRef { // can't just STRUCT_ERROR.get().unwrap() cause this could be called before from buffer // machinery, independent of whether _struct was ever imported vm.new_exception_msg(struct_error_type(vm).clone(), msg) From 704cc8f639b1567e1ed1d13b571e4160d7e8c4f4 Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Mon, 23 Jun 2025 11:42:57 +0300 Subject: [PATCH 6/9] Remove `.to_owned()` from more places --- vm/src/sequence.rs | 2 +- vm/src/signal.rs | 2 +- vm/src/warn.rs | 12 +++++------- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/vm/src/sequence.rs b/vm/src/sequence.rs index fc6e2168090..5d668224605 100644 --- a/vm/src/sequence.rs +++ b/vm/src/sequence.rs @@ -101,7 +101,7 @@ where let n = vm.check_repeat_or_overflow_error(self.as_ref().len(), n)?; if n > 1 && std::mem::size_of_val(self.as_ref()) >= MAX_MEMORY_SIZE / n { - return Err(vm.new_memory_error("".to_owned())); + return Err(vm.new_memory_error("")); } let mut v = Vec::with_capacity(n * self.as_ref().len()); diff --git a/vm/src/signal.rs b/vm/src/signal.rs index 846114794b4..4157a2c67e5 100644 --- a/vm/src/signal.rs +++ b/vm/src/signal.rs @@ -59,7 +59,7 @@ pub fn assert_in_range(signum: i32, vm: &VirtualMachine) -> PyResult<()> { if (1..NSIG as i32).contains(&signum) { Ok(()) } else { - Err(vm.new_value_error("signal number out of range".to_owned())) + Err(vm.new_value_error("signal number out of range")) } } diff --git a/vm/src/warn.rs b/vm/src/warn.rs index b2055225a0f..6c195d5f2e5 100644 --- a/vm/src/warn.rs +++ b/vm/src/warn.rs @@ -109,7 +109,7 @@ fn get_filter( let filters: PyListRef = filters .try_into_value(vm) - .map_err(|_| vm.new_value_error("_warnings.filters must be a list".to_string()))?; + .map_err(|_| vm.new_value_error("_warnings.filters must be a list"))?; /* WarningsState.filters could change while we are iterating over it. */ for i in 0..filters.borrow_vec().len() { @@ -125,7 +125,7 @@ fn get_filter( let action = if let Some(action) = tmp_item.first() { action.str(vm).map(|action| action.into_object()) } else { - Err(vm.new_type_error("action must be a string".to_string())) + Err(vm.new_type_error("action must be a string")) }; let good_msg = if let Some(msg) = tmp_item.get(1) { @@ -224,7 +224,7 @@ fn warn_explicit( ) -> PyResult<()> { let registry: PyObjectRef = registry .try_into_value(vm) - .map_err(|_| vm.new_type_error("'registry' must be a dict or None".to_owned()))?; + .map_err(|_| vm.new_type_error("'registry' must be a dict or None"))?; // Normalize module. let module = match module.or_else(|| normalize_module(&filename, vm)) { @@ -314,13 +314,11 @@ fn call_show_warning( return show_warning(filename, lineno, message, category, source_line, vm); }; if !show_fn.is_callable() { - return Err( - vm.new_type_error("warnings._showwarnmsg() must be set to a callable".to_owned()) - ); + return Err(vm.new_type_error("warnings._showwarnmsg() must be set to a callable")); } let Some(warnmsg_cls) = get_warnings_attr(vm, identifier!(&vm.ctx, WarningMessage), false)? else { - return Err(vm.new_type_error("unable to get warnings.WarningMessage".to_owned())); + return Err(vm.new_type_error("unable to get warnings.WarningMessage")); }; let msg = warnmsg_cls.call( From 2eefb81434b01bf41fe4676a0e93868dc5ffbd1f Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Mon, 23 Jun 2025 11:53:21 +0300 Subject: [PATCH 7/9] Resolve wasm errors --- wasm/lib/src/browser_module.rs | 2 +- wasm/lib/src/convert.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wasm/lib/src/browser_module.rs b/wasm/lib/src/browser_module.rs index f8d1b2ebc3e..0b978a4b563 100644 --- a/wasm/lib/src/browser_module.rs +++ b/wasm/lib/src/browser_module.rs @@ -29,7 +29,7 @@ mod _browser { "json" => Ok(FetchResponseFormat::Json), "text" => Ok(FetchResponseFormat::Text), "array_buffer" => Ok(FetchResponseFormat::ArrayBuffer), - _ => Err(vm.new_type_error("Unknown fetch response_format".into())), + _ => Err(vm.new_type_error("Unknown fetch response_format")), } } fn get_response(&self, response: &web_sys::Response) -> Result { diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs index 9d83f70cebc..a44e7a2c483 100644 --- a/wasm/lib/src/convert.rs +++ b/wasm/lib/src/convert.rs @@ -70,7 +70,7 @@ pub fn js_err_to_py_err(vm: &VirtualMachine, js_err: &JsValue) -> PyBaseExceptio _ => vm.ctx.exceptions.exception_type, } .to_owned(); - vm.new_exception_msg(exc_type, err.message().into()) + vm.new_exception_msg(exc_type, err.message()) } None => vm.new_exception_msg( vm.ctx.exceptions.exception_type.to_owned(), From ebc88bc95e2c9c8ecc52e1d2ad316115e1e72e35 Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Tue, 24 Jun 2025 17:53:04 +0300 Subject: [PATCH 8/9] Revert changes to `new_exception_msg` and `new_exception_msg_dict` --- vm/src/buffer.rs | 2 +- vm/src/vm/vm_new.rs | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/vm/src/buffer.rs b/vm/src/buffer.rs index b585bfbcde5..d6bff513720 100644 --- a/vm/src/buffer.rs +++ b/vm/src/buffer.rs @@ -646,5 +646,5 @@ pub fn struct_error_type(vm: &VirtualMachine) -> &'static PyTypeRef { pub fn new_struct_error(vm: &VirtualMachine, msg: impl Into) -> PyBaseExceptionRef { // can't just STRUCT_ERROR.get().unwrap() cause this could be called before from buffer // machinery, independent of whether _struct was ever imported - vm.new_exception_msg(struct_error_type(vm).clone(), msg) + vm.new_exception_msg(struct_error_type(vm).clone(), msg.into()) } diff --git a/vm/src/vm/vm_new.rs b/vm/src/vm/vm_new.rs index b70e5b79865..7673620c00a 100644 --- a/vm/src/vm/vm_new.rs +++ b/vm/src/vm/vm_new.rs @@ -25,7 +25,7 @@ macro_rules! define_exception_fn { pub fn $fn_name(&self, msg: impl Into) -> PyBaseExceptionRef { let err = self.ctx.exceptions.$attr.to_owned(); - self.new_exception_msg(err, msg) + self.new_exception_msg(err, msg.into()) } }; } @@ -117,12 +117,8 @@ impl VirtualMachine { /// type is passed in, it may not be fully initialized; try using /// [`vm.invoke_exception()`][Self::invoke_exception] or /// [`exceptions::ExceptionCtor`][crate::exceptions::ExceptionCtor] instead. - pub fn new_exception_msg( - &self, - exc_type: PyTypeRef, - msg: impl Into, - ) -> PyBaseExceptionRef { - self.new_exception(exc_type, vec![self.ctx.new_str(msg.into()).into()]) + pub fn new_exception_msg(&self, exc_type: PyTypeRef, msg: String) -> PyBaseExceptionRef { + self.new_exception(exc_type, vec![self.ctx.new_str(msg).into()]) } /// Instantiate an exception with `msg` as the only argument and `dict` for object @@ -133,14 +129,14 @@ impl VirtualMachine { pub fn new_exception_msg_dict( &self, exc_type: PyTypeRef, - msg: impl Into, + msg: String, dict: PyDictRef, ) -> PyBaseExceptionRef { PyRef::new_ref( // TODO: this constructor might be invalid, because multiple // exception (even builtin ones) are using custom constructors, // see `OSError` as an example: - PyBaseException::new(vec![self.ctx.new_str(msg.into()).into()], self), + PyBaseException::new(vec![self.ctx.new_str(msg).into()], self), exc_type, Some(dict), ) @@ -162,7 +158,7 @@ impl VirtualMachine { pub fn new_name_error(&self, msg: impl Into, name: PyStrRef) -> PyBaseExceptionRef { let name_error_type = self.ctx.exceptions.name_error.to_owned(); - let name_error = self.new_exception_msg(name_error_type, msg); + let name_error = self.new_exception_msg(name_error_type, msg.into()); name_error.as_object().set_attr("name", name, self).unwrap(); name_error } @@ -476,7 +472,7 @@ impl VirtualMachine { pub fn new_import_error(&self, msg: impl Into, name: PyStrRef) -> PyBaseExceptionRef { let import_error = self.ctx.exceptions.import_error.to_owned(); - let exc = self.new_exception_msg(import_error, msg); + let exc = self.new_exception_msg(import_error, msg.into()); exc.as_object().set_attr("name", name, self).unwrap(); exc } From 324b8be834e8bf544b6c87d7cd67876250929dd0 Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Tue, 24 Jun 2025 18:55:35 +0300 Subject: [PATCH 9/9] fix wasm --- wasm/lib/src/convert.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs index a44e7a2c483..9d83f70cebc 100644 --- a/wasm/lib/src/convert.rs +++ b/wasm/lib/src/convert.rs @@ -70,7 +70,7 @@ pub fn js_err_to_py_err(vm: &VirtualMachine, js_err: &JsValue) -> PyBaseExceptio _ => vm.ctx.exceptions.exception_type, } .to_owned(); - vm.new_exception_msg(exc_type, err.message()) + vm.new_exception_msg(exc_type, err.message().into()) } None => vm.new_exception_msg( vm.ctx.exceptions.exception_type.to_owned(),