From 073007c6304d3d76d98580bc02e28267ef3ea441 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sun, 22 Jun 2025 09:13:30 +0900 Subject: [PATCH] Fix struct tests --- Lib/test/test_struct.py | 4 ---- stdlib/src/pystruct.rs | 11 +++++++++-- vm/src/buffer.rs | 6 ++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index bc801a08d6..6fe1524d68 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -718,8 +718,6 @@ def test__struct_types_immutable(self): cls.x = 1 - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_issue35714(self): # Embedded null characters should not be allowed in format strings. for s in '\0', '2\0i', b'\0': @@ -790,8 +788,6 @@ def __init__(self): my_struct = MyStruct() self.assertEqual(my_struct.pack(12345), b'\x30\x39') - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_repr(self): s = struct.Struct('=i2H') self.assertEqual(repr(s), f'Struct({s.format!r})') diff --git a/stdlib/src/pystruct.rs b/stdlib/src/pystruct.rs index 9426470911..31f22c05f4 100644 --- a/stdlib/src/pystruct.rs +++ b/stdlib/src/pystruct.rs @@ -16,7 +16,7 @@ pub(crate) mod _struct { function::{ArgBytesLike, ArgMemoryBuffer, PosArgs}, match_class, protocol::PyIterReturn, - types::{Constructor, IterNext, Iterable, SelfIter}, + types::{Constructor, IterNext, Iterable, Representable, SelfIter}, }; use crossbeam_utils::atomic::AtomicCell; @@ -251,7 +251,7 @@ pub(crate) mod _struct { } } - #[pyclass(with(Constructor))] + #[pyclass(with(Constructor, Representable))] impl PyStruct { #[pygetset] fn format(&self) -> PyStrRef { @@ -306,6 +306,13 @@ pub(crate) mod _struct { } } + impl Representable for PyStruct { + #[inline] + fn repr_str(zelf: &Py, _vm: &VirtualMachine) -> PyResult { + Ok(format!("Struct('{}')", zelf.format.as_str())) + } + } + // seems weird that this is part of the "public" API, but whatever // TODO: implement a format code->spec cache like CPython does? #[pyfunction] diff --git a/vm/src/buffer.rs b/vm/src/buffer.rs index 0bab22c10a..5c78975cb8 100644 --- a/vm/src/buffer.rs +++ b/vm/src/buffer.rs @@ -242,6 +242,12 @@ impl FormatCode { let c = chars .next() .ok_or_else(|| "repeat count given without format specifier".to_owned())?; + + // Check for embedded null character + if c == 0 { + return Err("embedded null character".to_owned()); + } + let code = FormatType::try_from(c) .ok() .filter(|c| match c {