From bb97696c9c08899b93942be4d662cf9936e41f36 Mon Sep 17 00:00:00 2001 From: youknowdot Date: Tue, 20 Oct 2026 07:50:19 -0700 Subject: [PATCH] Include name and path in ImportError repr (#9247) Extract the independent Python 3.15 ImportError representation change from the upgrade work. Preserve BaseException positional arguments and include explicitly present name/path attributes for ImportError and ModuleNotFoundError. AI assistance: OpenAI Codex prepared the extraction and validation. Model version is not exposed in this session. Assisted-by: Codex:unknown (model version not exposed) --- crates/vm/src/exceptions.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/crates/vm/src/exceptions.rs b/crates/vm/src/exceptions.rs index b6f0cad93..bbdb17a9b 100644 --- a/crates/vm/src/exceptions.rs +++ b/crates/vm/src/exceptions.rs @@ -1824,7 +1824,7 @@ pub(super) mod types { }, convert::ToPyResult, function::{ArgBytesLike, FuncArgs, KwArgs, PySetterValue}, - types::{Constructor, Initializer}, + types::{Constructor, Initializer, Representable}, }; use core::sync::atomic::{AtomicBool, AtomicIsize, Ordering}; use crossbeam_utils::atomic::AtomicCell; @@ -2213,7 +2213,35 @@ pub(super) mod types { } } - #[pyexception(with(Constructor, Initializer))] + impl Representable for PyImportError { + fn repr_str(zelf: &Py, vm: &VirtualMachine) -> PyResult { + let base: &Py = zelf + .as_object() + .downcast_ref() + .expect("ImportError is a BaseException"); + let mut has_args = !base.args().is_empty(); + if zelf.name.load_owned().is_none() && zelf.path.load_owned().is_none() { + return PyBaseException::repr_str(base, vm); + } + let mut result = PyBaseException::repr_str(base, vm)?; + result.pop(); + for (name, field) in [("name", &zelf.name), ("path", &zelf.path)] { + if let Some(value) = field.load_owned() { + if has_args { + result.push_str(", "); + } + result.push_str(name); + result.push('='); + result.push_str(&value.repr(vm)?.to_string_lossy()); + has_args = true; + } + } + result.push(')'); + Ok(result) + } + } + + #[pyexception(with(Constructor, Initializer, Representable))] impl PyImportError { #[pyslot] fn slot_str(zelf: &PyObject, vm: &VirtualMachine) -> PyResult {