From 777542f7ecbf4d99dec764a68c581c486cca50ea Mon Sep 17 00:00:00 2001 From: coolreader18 <33094578+coolreader18@users.noreply.github.com> Date: Sat, 28 Dec 2019 01:31:24 -0600 Subject: [PATCH] Directly instantiate exceptions in the vm.new_*_error functions --- src/shell.rs | 5 ++- vm/src/builtins.rs | 2 +- vm/src/exceptions.rs | 29 +++++++++------ vm/src/frame.rs | 4 +-- vm/src/lib.rs | 1 - vm/src/obj/objcoroutine.rs | 2 +- vm/src/obj/objdict.rs | 2 +- vm/src/obj/objgenerator.rs | 2 +- vm/src/obj/objiter.rs | 2 +- vm/src/obj/objweakproxy.rs | 4 +-- vm/src/pyobject.rs | 8 +++-- vm/src/stdlib/functools.rs | 2 +- vm/src/stdlib/io.rs | 8 ++--- vm/src/stdlib/json.rs | 2 +- vm/src/stdlib/os.rs | 10 +++--- vm/src/stdlib/random.rs | 2 +- vm/src/stdlib/signal.rs | 2 +- vm/src/stdlib/socket.rs | 8 ++--- vm/src/stdlib/subprocess.rs | 2 +- vm/src/stdlib/zlib.rs | 2 +- vm/src/sysmodule.rs | 2 +- vm/src/vm.rs | 72 +++++++++++++++++++++++-------------- wasm/lib/src/convert.rs | 4 +-- wasm/lib/src/js_module.rs | 2 +- 24 files changed, 104 insertions(+), 75 deletions(-) diff --git a/src/shell.rs b/src/shell.rs index bf26af3a9..af4f3c6cb 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -118,9 +118,8 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> { ReadlineResult::Interrupt => { continuing = false; full_input.clear(); - let keyboard_interrupt = vm - .new_empty_exception(vm.ctx.exceptions.keyboard_interrupt.clone()) - .unwrap(); + let keyboard_interrupt = + vm.new_exception_empty(vm.ctx.exceptions.keyboard_interrupt.clone()); Err(keyboard_interrupt) } ReadlineResult::EOF => { diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index c052ee3f9..73f237a71 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -629,7 +629,7 @@ impl Printer for std::io::StdoutLock<'_> { pub fn builtin_exit(exit_code_arg: OptionalArg, vm: &VirtualMachine) -> PyResult { let code = exit_code_arg.unwrap_or_else(|| vm.new_int(0)); - Err(vm.new_exception_obj(vm.ctx.exceptions.system_exit.clone(), vec![code])?) + Err(vm.new_exception(vm.ctx.exceptions.system_exit.clone(), vec![code])) } pub fn builtin_print(objects: Args, options: PrintOptions, vm: &VirtualMachine) -> PyResult<()> { diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 5ed4ba5ba..5552eb154 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -44,20 +44,19 @@ impl PyValue for PyBaseException { #[pyimpl] impl PyBaseException { - #[pyslot(new)] - fn tp_new( - cls: PyClassRef, - args: PyFuncArgs, - vm: &VirtualMachine, - ) -> PyResult { + pub(crate) fn new(args: Vec, vm: &VirtualMachine) -> PyBaseException { PyBaseException { traceback: RefCell::new(None), cause: RefCell::new(None), context: RefCell::new(None), suppress_context: Cell::new(false), - args: RefCell::new(PyTuple::from(args.args).into_ref(vm)), + args: RefCell::new(PyTuple::from(args).into_ref(vm)), } - .into_ref_with_type(vm, cls) + } + + #[pyslot(new)] + fn tp_new(cls: PyClassRef, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult> { + PyBaseException::new(args.args, vm).into_ref_with_type(vm, cls) } #[pymethod(name = "__init__")] @@ -325,10 +324,20 @@ impl TryFromObject for ExceptionCtor { } } +pub fn invoke( + cls: PyClassRef, + args: Vec, + vm: &VirtualMachine, +) -> PyResult { + // TODO: fast-path built-in exceptions by directly instantiating them? Is that really worth it? + let res = vm.invoke(cls.as_object(), args)?; + PyBaseExceptionRef::try_from_object(vm, res) +} + impl ExceptionCtor { pub fn instantiate(self, vm: &VirtualMachine) -> PyResult { match self { - Self::Class(cls) => vm.new_empty_exception(cls), + Self::Class(cls) => invoke(cls, vec![], vm), Self::Instance(exc) => Ok(exc), } } @@ -357,7 +366,7 @@ impl ExceptionCtor { exc @ PyBaseException => exc.args().elements.clone(), obj => vec![obj], }); - vm.new_exception_obj(cls, args) + invoke(cls, args, vm) } } } diff --git a/vm/src/frame.rs b/vm/src/frame.rs index 9e122f9d3..ba13d5c54 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -127,7 +127,7 @@ impl ExecutionResult { } else { vec![value] }; - Err(vm.new_exception_obj(stop_iteration, args).unwrap()) + Err(vm.new_exception(stop_iteration, args)) } } } @@ -978,7 +978,7 @@ impl Frame { 0 => match vm.current_exception() { Some(exc) => exc, None => { - return Err(vm.new_exception( + return Err(vm.new_exception_msg( vm.ctx.exceptions.runtime_error.clone(), "No active exception to reraise".to_string(), )) diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 71f206a09..1f8fe9be4 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -72,7 +72,6 @@ mod version; mod vm; // pub use self::pyobject::Executor; -pub use self::exceptions::{print_exception, write_exception}; pub use self::vm::{InitParameter, PySettings, VirtualMachine}; pub use rustpython_bytecode::*; diff --git a/vm/src/obj/objcoroutine.rs b/vm/src/obj/objcoroutine.rs index 0fd686492..4dad7d71d 100644 --- a/vm/src/obj/objcoroutine.rs +++ b/vm/src/obj/objcoroutine.rs @@ -89,7 +89,7 @@ impl PyCoroutine { vm.frames.borrow_mut().pop(); self.closed.set(true); match result { - Ok(ExecutionResult::Yield(_)) => Err(vm.new_exception( + Ok(ExecutionResult::Yield(_)) => Err(vm.new_exception_msg( vm.ctx.exceptions.runtime_error.clone(), "generator ignored GeneratorExit".to_string(), )), diff --git a/vm/src/obj/objdict.rs b/vm/src/obj/objdict.rs index 47ee14564..c25c68b71 100644 --- a/vm/src/obj/objdict.rs +++ b/vm/src/obj/objdict.rs @@ -527,7 +527,7 @@ macro_rules! dict_iterator { let mut position = self.position.get(); let dict = self.dict.entries.borrow(); if dict.has_changed_size(&self.size) { - return Err(vm.new_exception( + return Err(vm.new_exception_msg( vm.ctx.exceptions.runtime_error.clone(), "dictionary changed size during iteration".to_string(), )); diff --git a/vm/src/obj/objgenerator.rs b/vm/src/obj/objgenerator.rs index c43fb57fd..56927bd19 100644 --- a/vm/src/obj/objgenerator.rs +++ b/vm/src/obj/objgenerator.rs @@ -102,7 +102,7 @@ impl PyGenerator { vm.frames.borrow_mut().pop(); self.closed.set(true); match result { - Ok(ExecutionResult::Yield(_)) => Err(vm.new_exception( + Ok(ExecutionResult::Yield(_)) => Err(vm.new_exception_msg( vm.ctx.exceptions.runtime_error.clone(), "generator ignored GeneratorExit".to_string(), )), diff --git a/vm/src/obj/objiter.rs b/vm/src/obj/objiter.rs index 94f69c064..b770e1e33 100644 --- a/vm/src/obj/objiter.rs +++ b/vm/src/obj/objiter.rs @@ -70,7 +70,7 @@ pub fn get_all(vm: &VirtualMachine, iter_obj: &PyObjectRef) -> pub fn new_stop_iteration(vm: &VirtualMachine) -> PyBaseExceptionRef { let stop_iteration_type = vm.ctx.exceptions.stop_iteration.clone(); - vm.new_empty_exception(stop_iteration_type).unwrap() + vm.new_exception_empty(stop_iteration_type) } pub fn stop_iter_value(vm: &VirtualMachine, exc: &PyBaseExceptionRef) -> PyResult { diff --git a/vm/src/obj/objweakproxy.rs b/vm/src/obj/objweakproxy.rs index 25d7cc01e..befc30f1d 100644 --- a/vm/src/obj/objweakproxy.rs +++ b/vm/src/obj/objweakproxy.rs @@ -41,7 +41,7 @@ impl PyWeakProxy { fn getattr(&self, attr_name: PyObjectRef, vm: &VirtualMachine) -> PyResult { match self.weak.upgrade() { Some(obj) => vm.get_attribute(obj, attr_name), - None => Err(vm.new_exception( + None => Err(vm.new_exception_msg( vm.ctx.exceptions.reference_error.clone(), "weakly-referenced object no longer exists".to_string(), )), @@ -52,7 +52,7 @@ impl PyWeakProxy { fn setattr(&self, attr_name: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult { match self.weak.upgrade() { Some(obj) => vm.set_attr(&obj, attr_name, value), - None => Err(vm.new_exception( + None => Err(vm.new_exception_msg( vm.ctx.exceptions.reference_error.clone(), "weakly-referenced object no longer exists".to_string(), )), diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index 0e2c36b38..e6b6b7312 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -619,7 +619,7 @@ impl PyRef { if obj.payload_is::() { Ok(Self::new_ref_unchecked(obj)) } else { - Err(vm.new_exception( + Err(vm.new_exception_msg( vm.ctx.exceptions.runtime_error.clone(), format!("Unexpected payload for type {:?}", obj.class().name), )) @@ -1085,7 +1085,7 @@ pub trait PyValue: fmt::Debug + Sized + 'static { fn class(vm: &VirtualMachine) -> PyClassRef; fn into_ref(self, vm: &VirtualMachine) -> PyRef { - PyRef::new_ref_unchecked(PyObject::new(self, Self::class(vm), None)) + self.into_ref_with_type_unchecked(Self::class(vm)) } fn into_ref_with_type(self, vm: &VirtualMachine, cls: PyClassRef) -> PyResult> { @@ -1103,6 +1103,10 @@ pub trait PyValue: fmt::Debug + Sized + 'static { Err(vm.new_type_error(format!("{} is not a subtype of {}", subtype, basetype))) } } + + fn into_ref_with_type_unchecked(self, cls: PyClassRef) -> PyRef { + PyRef::new_ref_unchecked(PyObject::new(self, cls, None)) + } } pub trait PyObjectPayload: Any + fmt::Debug + 'static { diff --git a/vm/src/stdlib/functools.rs b/vm/src/stdlib/functools.rs index a35bede73..320c57142 100644 --- a/vm/src/stdlib/functools.rs +++ b/vm/src/stdlib/functools.rs @@ -26,7 +26,7 @@ fn functools_reduce( objiter::call_next(vm, &iterator).map_err(|err| { if objtype::isinstance(&err, &vm.ctx.exceptions.stop_iteration) { let exc_type = vm.ctx.exceptions.type_error.clone(); - vm.new_exception( + vm.new_exception_msg( exc_type, "reduce() of empty sequence with no initial value".to_string(), ) diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index ecf1c9d3b..dc53d053c 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -386,7 +386,7 @@ fn io_base_checkclosed( let msg = msg .flat_option() .unwrap_or_else(|| vm.new_str("I/O operation on closed file.".to_string())); - Err(vm.new_exception_obj(vm.ctx.exceptions.value_error.clone(), vec![msg])?) + Err(vm.new_exception(vm.ctx.exceptions.value_error.clone(), vec![msg])) } else { Ok(()) } @@ -401,7 +401,7 @@ fn io_base_checkreadable( let msg = msg .flat_option() .unwrap_or_else(|| vm.new_str("File or stream is not readable.".to_string())); - Err(vm.new_exception_obj(vm.ctx.exceptions.value_error.clone(), vec![msg])?) + Err(vm.new_exception(vm.ctx.exceptions.value_error.clone(), vec![msg])) } else { Ok(()) } @@ -416,7 +416,7 @@ fn io_base_checkwritable( let msg = msg .flat_option() .unwrap_or_else(|| vm.new_str("File or stream is not writable.".to_string())); - Err(vm.new_exception_obj(vm.ctx.exceptions.value_error.clone(), vec![msg])?) + Err(vm.new_exception(vm.ctx.exceptions.value_error.clone(), vec![msg])) } else { Ok(()) } @@ -431,7 +431,7 @@ fn io_base_checkseekable( let msg = msg .flat_option() .unwrap_or_else(|| vm.new_str("File or stream is not seekable.".to_string())); - Err(vm.new_exception_obj(vm.ctx.exceptions.value_error.clone(), vec![msg])?) + Err(vm.new_exception(vm.ctx.exceptions.value_error.clone(), vec![msg])) } else { Ok(()) } diff --git a/vm/src/stdlib/json.rs b/vm/src/stdlib/json.rs index dc9f2e217..88216acc3 100644 --- a/vm/src/stdlib/json.rs +++ b/vm/src/stdlib/json.rs @@ -46,7 +46,7 @@ pub fn json_loads(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult { .unwrap(); let json_decode_error = vm.get_attribute(module, "JSONDecodeError").unwrap(); let json_decode_error = json_decode_error.downcast().unwrap(); - let exc = vm.new_exception(json_decode_error, format!("{}", err)); + let exc = vm.new_exception_msg(json_decode_error, format!("{}", err)); vm.set_attr(exc.as_object(), "lineno", vm.ctx.new_int(err.line())) .unwrap(); vm.set_attr(exc.as_object(), "colno", vm.ctx.new_int(err.column())) diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index 1fdf3b978..2aef879f4 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -171,7 +171,7 @@ pub fn convert_io_error(vm: &VirtualMachine, err: io::Error) -> PyBaseExceptionR _ => vm.ctx.exceptions.os_error.clone(), }, }; - let os_error = vm.new_exception(exc_type, err.to_string()); + let os_error = vm.new_exception_msg(exc_type, err.to_string()); let errno = match err.raw_os_error() { Some(errno) => vm.new_int(errno), None => vm.get_none(), @@ -185,19 +185,19 @@ pub fn convert_nix_error(vm: &VirtualMachine, err: nix::Error) -> PyBaseExceptio let nix_error = match err { nix::Error::InvalidPath => { let exc_type = vm.ctx.exceptions.file_not_found_error.clone(); - vm.new_exception(exc_type, err.to_string()) + vm.new_exception_msg(exc_type, err.to_string()) } nix::Error::InvalidUtf8 => { let exc_type = vm.ctx.exceptions.unicode_error.clone(); - vm.new_exception(exc_type, err.to_string()) + vm.new_exception_msg(exc_type, err.to_string()) } nix::Error::UnsupportedOperation => { let exc_type = vm.ctx.exceptions.runtime_error.clone(); - vm.new_exception(exc_type, err.to_string()) + vm.new_exception_msg(exc_type, err.to_string()) } nix::Error::Sys(errno) => { let exc_type = convert_nix_errno(vm, errno); - vm.new_exception(exc_type, err.to_string()) + vm.new_exception_msg(exc_type, err.to_string()) } }; diff --git a/vm/src/stdlib/random.rs b/vm/src/stdlib/random.rs index 398ce749b..f175423f2 100644 --- a/vm/src/stdlib/random.rs +++ b/vm/src/stdlib/random.rs @@ -19,7 +19,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { fn random_normalvariate(mu: f64, sigma: f64, vm: &VirtualMachine) -> PyResult { let normal = Normal::new(mu, sigma).map_err(|rand_err| { - vm.new_exception( + vm.new_exception_msg( vm.ctx.exceptions.arithmetic_error.clone(), format!("invalid normal distribution: {:?}", rand_err), ) diff --git a/vm/src/stdlib/signal.rs b/vm/src/stdlib/signal.rs index f20679b51..3cdb91341 100644 --- a/vm/src/stdlib/signal.rs +++ b/vm/src/stdlib/signal.rs @@ -108,7 +108,7 @@ pub fn check_signals(vm: &VirtualMachine) -> PyResult<()> { } fn default_int_handler(_signum: PyObjectRef, _arg: PyObjectRef, vm: &VirtualMachine) -> PyResult { - Err(vm.new_empty_exception(vm.ctx.exceptions.keyboard_interrupt.clone())?) + Err(vm.new_exception_empty(vm.ctx.exceptions.keyboard_interrupt.clone())) } pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index fdc599966..c6cbfc8a8 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -485,7 +485,7 @@ fn socket_getaddrinfo(opts: GAIOptions, vm: &VirtualMachine) -> PyResult { let addrs = dns_lookup::getaddrinfo(host, port, Some(hints)).map_err(|err| { let error_type = vm.class("_socket", "gaierror"); - vm.new_exception(error_type, io::Error::from(err).to_string()) + vm.new_exception_msg(error_type, io::Error::from(err).to_string()) })?; let list = addrs @@ -537,7 +537,7 @@ where Ok(mut sock_addrs) => { if sock_addrs.len() == 0 { let error_type = vm.class("_socket", "gaierror"); - Err(vm.new_exception( + Err(vm.new_exception_msg( error_type, "nodename nor servname provided, or not known".to_string(), )) @@ -547,7 +547,7 @@ where } Err(e) => { let error_type = vm.class("_socket", "gaierror"); - Err(vm.new_exception(error_type, e.to_string())) + Err(vm.new_exception_msg(error_type, e.to_string())) } } } @@ -593,7 +593,7 @@ fn invalid_sock() -> Socket { fn convert_sock_error(vm: &VirtualMachine, err: io::Error) -> PyBaseExceptionRef { if err.kind() == io::ErrorKind::TimedOut { let socket_timeout = vm.class("_socket", "timeout"); - vm.new_exception(socket_timeout, "Timed out".to_string()) + vm.new_exception_msg(socket_timeout, "Timed out".to_string()) } else { convert_io_error(vm, err) } diff --git a/vm/src/stdlib/subprocess.rs b/vm/src/stdlib/subprocess.rs index b2c538d75..bf6738694 100644 --- a/vm/src/stdlib/subprocess.rs +++ b/vm/src/stdlib/subprocess.rs @@ -152,7 +152,7 @@ impl PopenRef { .map_err(|s| vm.new_os_error(format!("Could not start program: {}", s)))?; if timeout.is_none() { let timeout_expired = vm.try_class("_subprocess", "TimeoutExpired")?; - Err(vm.new_exception(timeout_expired, "Timeout".to_string())) + Err(vm.new_exception_msg(timeout_expired, "Timeout".to_string())) } else { Ok(()) } diff --git a/vm/src/stdlib/zlib.rs b/vm/src/stdlib/zlib.rs index 0206d7743..62ef5df4c 100644 --- a/vm/src/stdlib/zlib.rs +++ b/vm/src/stdlib/zlib.rs @@ -121,5 +121,5 @@ fn zlib_error(message: &str, vm: &VirtualMachine) -> PyBaseExceptionRef { let zlib_error = vm.get_attribute(module, "error").unwrap(); let zlib_error = zlib_error.downcast().unwrap(); - vm.new_exception(zlib_error, message.to_string()) + vm.new_exception_msg(zlib_error, message.to_string()) } diff --git a/vm/src/sysmodule.rs b/vm/src/sysmodule.rs index f9553e6e2..2b943f801 100644 --- a/vm/src/sysmodule.rs +++ b/vm/src/sysmodule.rs @@ -198,7 +198,7 @@ fn sys_git_info(vm: &VirtualMachine) -> PyObjectRef { fn sys_exit(code: OptionalArg, vm: &VirtualMachine) -> PyResult { let code = code.unwrap_or_else(|| vm.new_int(0)); - Err(vm.new_exception_obj(vm.ctx.exceptions.system_exit.clone(), vec![code])?) + Err(vm.new_exception(vm.ctx.exceptions.system_exit.clone(), vec![code])) } pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectRef) { diff --git a/vm/src/vm.rs b/vm/src/vm.rs index d82cd012e..7a9052039 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -19,7 +19,7 @@ use rustpython_compiler::{compile, error::CompileError}; use crate::builtins::{self, to_ascii}; use crate::bytecode; -use crate::exceptions::PyBaseExceptionRef; +use crate::exceptions::{PyBaseException, PyBaseExceptionRef}; use crate::frame::{ExecutionResult, Frame, FrameRef}; use crate::frozen; use crate::function::PyFuncArgs; @@ -329,45 +329,63 @@ impl VirtualMachine { PyObject::new(PyModule {}, self.ctx.types.module_type.clone(), Some(dict)) } - #[cfg_attr(feature = "flame-it", flame("VirtualMachine"))] - pub fn new_exception_obj( + /// Instantiate an exception with arguments. + /// This function should only be used with builtin exception types; if a user-defined exception + /// type is passed in, it may not be fully initialized; try using [`exceptions::invoke`](invoke) + /// or [`exceptions::ExceptionCtor`](ctor) instead. + /// + /// [invoke]: rustpython_vm::exceptions::invoke + /// [ctor]: rustpython_vm::exceptions::ExceptionCtor + pub fn new_exception( &self, exc_type: PyClassRef, args: Vec, - ) -> PyResult { + ) -> PyBaseExceptionRef { // TODO: add repr of args into logging? vm_trace!("New exception created: {}", exc_type.name); - PyBaseExceptionRef::try_from_object(self, self.invoke(&exc_type.into_object(), args)?) + PyBaseException::new(args, self).into_ref_with_type_unchecked(exc_type) } - pub fn new_empty_exception(&self, exc_type: PyClassRef) -> PyResult { - self.new_exception_obj(exc_type, vec![]) + /// Instantiate an exception with no arguments. + /// This function should only be used with builtin exception types; if a user-defined exception + /// type is passed in, it may not be fully initialized; try using [`exceptions::invoke`](invoke) + /// or [`exceptions::ExceptionCtor`](ctor) instead. + /// + /// [invoke]: rustpython_vm::exceptions::invoke + /// [ctor]: rustpython_vm::exceptions::ExceptionCtor + pub fn new_exception_empty(&self, exc_type: PyClassRef) -> PyBaseExceptionRef { + self.new_exception(exc_type, vec![]) } - /// Create Python instance of `exc_type` with message as first element of `args` tuple - pub fn new_exception(&self, exc_type: PyClassRef, msg: String) -> PyBaseExceptionRef { - let pystr_msg = self.new_str(msg); - self.new_exception_obj(exc_type, vec![pystr_msg]).unwrap() + /// Instantiate an exception with `msg` as the only argument. + /// This function should only be used with builtin exception types; if a user-defined exception + /// type is passed in, it may not be fully initialized; try using [`exceptions::invoke`](invoke) + /// or [`exceptions::ExceptionCtor`](ctor) instead. + /// + /// [invoke]: rustpython_vm::exceptions::invoke + /// [ctor]: rustpython_vm::exceptions::ExceptionCtor + pub fn new_exception_msg(&self, exc_type: PyClassRef, msg: String) -> PyBaseExceptionRef { + self.new_exception(exc_type, vec![self.new_str(msg)]) } pub fn new_lookup_error(&self, msg: String) -> PyBaseExceptionRef { let lookup_error = self.ctx.exceptions.lookup_error.clone(); - self.new_exception(lookup_error, msg) + self.new_exception_msg(lookup_error, msg) } pub fn new_attribute_error(&self, msg: String) -> PyBaseExceptionRef { let attribute_error = self.ctx.exceptions.attribute_error.clone(); - self.new_exception(attribute_error, msg) + self.new_exception_msg(attribute_error, msg) } pub fn new_type_error(&self, msg: String) -> PyBaseExceptionRef { let type_error = self.ctx.exceptions.type_error.clone(); - self.new_exception(type_error, msg) + self.new_exception_msg(type_error, msg) } pub fn new_name_error(&self, msg: String) -> PyBaseExceptionRef { let name_error = self.ctx.exceptions.name_error.clone(); - self.new_exception(name_error, msg) + self.new_exception_msg(name_error, msg) } pub fn new_unsupported_operand_error( @@ -386,54 +404,54 @@ impl VirtualMachine { pub fn new_os_error(&self, msg: String) -> PyBaseExceptionRef { let os_error = self.ctx.exceptions.os_error.clone(); - self.new_exception(os_error, msg) + self.new_exception_msg(os_error, msg) } pub fn new_unicode_decode_error(&self, msg: String) -> PyBaseExceptionRef { let unicode_decode_error = self.ctx.exceptions.unicode_decode_error.clone(); - self.new_exception(unicode_decode_error, msg) + self.new_exception_msg(unicode_decode_error, msg) } pub fn new_unicode_encode_error(&self, msg: String) -> PyBaseExceptionRef { let unicode_encode_error = self.ctx.exceptions.unicode_encode_error.clone(); - self.new_exception(unicode_encode_error, msg) + self.new_exception_msg(unicode_encode_error, msg) } /// Create a new python ValueError object. Useful for raising errors from /// python functions implemented in rust. pub fn new_value_error(&self, msg: String) -> PyBaseExceptionRef { let value_error = self.ctx.exceptions.value_error.clone(); - self.new_exception(value_error, msg) + self.new_exception_msg(value_error, msg) } pub fn new_key_error(&self, obj: PyObjectRef) -> PyBaseExceptionRef { let key_error = self.ctx.exceptions.key_error.clone(); - self.new_exception_obj(key_error, vec![obj]).unwrap() + self.new_exception(key_error, vec![obj]) } pub fn new_index_error(&self, msg: String) -> PyBaseExceptionRef { let index_error = self.ctx.exceptions.index_error.clone(); - self.new_exception(index_error, msg) + self.new_exception_msg(index_error, msg) } pub fn new_not_implemented_error(&self, msg: String) -> PyBaseExceptionRef { let not_implemented_error = self.ctx.exceptions.not_implemented_error.clone(); - self.new_exception(not_implemented_error, msg) + self.new_exception_msg(not_implemented_error, msg) } pub fn new_recursion_error(&self, msg: String) -> PyBaseExceptionRef { let recursion_error = self.ctx.exceptions.recursion_error.clone(); - self.new_exception(recursion_error, msg) + self.new_exception_msg(recursion_error, msg) } pub fn new_zero_division_error(&self, msg: String) -> PyBaseExceptionRef { let zero_division_error = self.ctx.exceptions.zero_division_error.clone(); - self.new_exception(zero_division_error, msg) + self.new_exception_msg(zero_division_error, msg) } pub fn new_overflow_error(&self, msg: String) -> PyBaseExceptionRef { let overflow_error = self.ctx.exceptions.overflow_error.clone(); - self.new_exception(overflow_error, msg) + self.new_exception_msg(overflow_error, msg) } #[cfg(feature = "rustpython-compiler")] @@ -445,7 +463,7 @@ impl VirtualMachine { } else { self.ctx.exceptions.syntax_error.clone() }; - let syntax_error = self.new_exception(syntax_error_type, error.to_string()); + let syntax_error = self.new_exception_msg(syntax_error_type, error.to_string()); let lineno = self.new_int(error.location.row()); let offset = self.new_int(error.location.column()); self.set_attr(syntax_error.as_object(), "lineno", lineno) @@ -469,7 +487,7 @@ impl VirtualMachine { pub fn new_import_error(&self, msg: String) -> PyBaseExceptionRef { let import_error = self.ctx.exceptions.import_error.clone(); - self.new_exception(import_error, msg) + self.new_exception_msg(import_error, msg) } pub fn new_scope_with_builtins(&self) -> Scope { diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs index 789f6cb39..ffb324018 100644 --- a/wasm/lib/src/convert.rs +++ b/wasm/lib/src/convert.rs @@ -57,9 +57,9 @@ pub fn js_err_to_py_err(vm: &VirtualMachine, js_err: &JsValue) -> PyBaseExceptio _ => &vm.ctx.exceptions.exception_type, } .clone(); - vm.new_exception(exc_type, err.message().into()) + vm.new_exception_msg(exc_type, err.message().into()) } - None => vm.new_exception( + None => vm.new_exception_msg( vm.ctx.exceptions.exception_type.clone(), format!("{:?}", js_err), ), diff --git a/wasm/lib/src/js_module.rs b/wasm/lib/src/js_module.rs index 0ffcf2f6a..f640b1d14 100644 --- a/wasm/lib/src/js_module.rs +++ b/wasm/lib/src/js_module.rs @@ -235,7 +235,7 @@ struct NewObjectOptions { } fn new_js_error(vm: &VirtualMachine, err: JsValue) -> PyBaseExceptionRef { - let exc = vm.new_exception(vm.class("_js", "JsError"), format!("{:?}", err)); + let exc = vm.new_exception_msg(vm.class("_js", "JsError"), format!("{:?}", err)); vm.set_attr( exc.as_object(), "js_value",