From bfe3d8ba68802130b60a2fac8edac6c5c2754458 Mon Sep 17 00:00:00 2001 From: Lee Dogeon Date: Sat, 21 Mar 2026 01:24:49 +0900 Subject: [PATCH 1/3] Implement bytearray.__str__ --- crates/vm/src/builtins/bytearray.rs | 8 ++++++++ crates/vm/src/bytes_inner.rs | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/crates/vm/src/builtins/bytearray.rs b/crates/vm/src/builtins/bytearray.rs index dec5cacc972..5d1da5340d1 100644 --- a/crates/vm/src/builtins/bytearray.rs +++ b/crates/vm/src/builtins/bytearray.rs @@ -215,6 +215,14 @@ impl PyByteArray { size_of::() + self.borrow_buf().len() * size_of::() } + #[pymethod] + fn __str__(zelf: &Py, vm: &VirtualMachine) -> PyResult { + PyBytesInner::warn_on_str("str() on a bytearray instance", vm)?; + let class_name = zelf.class().name(); + let repr = zelf.inner().repr_with_name(&class_name, vm)?; + Ok(vm.ctx.new_str(repr)) + } + fn __add__(&self, other: ArgBytesLike) -> Self { self.inner().add(&other.borrow_buf()).into() } diff --git a/crates/vm/src/bytes_inner.rs b/crates/vm/src/bytes_inner.rs index 2318415f0fe..6a1aa73c6b8 100644 --- a/crates/vm/src/bytes_inner.rs +++ b/crates/vm/src/bytes_inner.rs @@ -237,6 +237,18 @@ impl PyBytesInner { vm.new_overflow_error("bytes object is too large to make repr") } + pub(crate) fn warn_on_str(message: &'static str, vm: &VirtualMachine) -> PyResult<()> { + if vm.state.config.settings.bytes_warning > 0 { + crate::stdlib::_warnings::warn( + vm.ctx.exceptions.bytes_warning, + message.to_owned(), + 1, + vm, + )?; + } + Ok(()) + } + pub fn repr_with_name(&self, class_name: &str, vm: &VirtualMachine) -> PyResult { const DECORATION_LEN: isize = 2 + 3; // 2 for (), 3 for b"" => bytearray(b"") let escape = crate::literal::escape::AsciiEscape::new_repr(&self.elements); From 08fbe7a1b91edc64c253452e655a4e3cd4f29fee Mon Sep 17 00:00:00 2001 From: Lee Dogeon Date: Sat, 21 Mar 2026 01:25:19 +0900 Subject: [PATCH 2/3] Implement bytes.__str__ --- crates/vm/src/builtins/bytes.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/vm/src/builtins/bytes.rs b/crates/vm/src/builtins/bytes.rs index 9e5d7d0ae51..c5b4508391b 100644 --- a/crates/vm/src/builtins/bytes.rs +++ b/crates/vm/src/builtins/bytes.rs @@ -224,6 +224,12 @@ impl PyBytes { size_of::() + self.len() * size_of::() } + #[pymethod] + fn __str__(zelf: &Py, vm: &VirtualMachine) -> PyResult { + PyBytesInner::warn_on_str("str() on a bytes instance", vm)?; + Ok(vm.ctx.new_str(zelf.inner.repr_bytes(vm)?)) + } + fn __add__(&self, other: ArgBytesLike) -> Vec { self.inner.add(&other.borrow_buf()) } From 590e514f623ebd75f301e2f0dfc57f13f551ea71 Mon Sep 17 00:00:00 2001 From: Lee Dogeon Date: Sat, 21 Mar 2026 22:06:11 +0900 Subject: [PATCH 3/3] Turn __str__ method into slot --- crates/vm/src/builtins/bytearray.rs | 5 +++-- crates/vm/src/builtins/bytes.rs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/vm/src/builtins/bytearray.rs b/crates/vm/src/builtins/bytearray.rs index 5d1da5340d1..0285526692c 100644 --- a/crates/vm/src/builtins/bytearray.rs +++ b/crates/vm/src/builtins/bytearray.rs @@ -215,8 +215,9 @@ impl PyByteArray { size_of::() + self.borrow_buf().len() * size_of::() } - #[pymethod] - fn __str__(zelf: &Py, vm: &VirtualMachine) -> PyResult { + #[pyslot] + fn slot_str(zelf: &PyObject, vm: &VirtualMachine) -> PyResult { + let zelf = zelf.downcast_ref::().expect("expected bytearray"); PyBytesInner::warn_on_str("str() on a bytearray instance", vm)?; let class_name = zelf.class().name(); let repr = zelf.inner().repr_with_name(&class_name, vm)?; diff --git a/crates/vm/src/builtins/bytes.rs b/crates/vm/src/builtins/bytes.rs index c5b4508391b..00cf3d2d113 100644 --- a/crates/vm/src/builtins/bytes.rs +++ b/crates/vm/src/builtins/bytes.rs @@ -224,8 +224,9 @@ impl PyBytes { size_of::() + self.len() * size_of::() } - #[pymethod] - fn __str__(zelf: &Py, vm: &VirtualMachine) -> PyResult { + #[pyslot] + fn slot_str(zelf: &PyObject, vm: &VirtualMachine) -> PyResult { + let zelf = zelf.downcast_ref::().expect("expected bytes"); PyBytesInner::warn_on_str("str() on a bytes instance", vm)?; Ok(vm.ctx.new_str(zelf.inner.repr_bytes(vm)?)) }