From 1ff5bbd920bf0caa84981d140998efe109a4f254 Mon Sep 17 00:00:00 2001 From: youknowdot Date: Sat, 10 Oct 2026 12:31:54 -0700 Subject: [PATCH] Accept the format keyword in Struct initialization (#9064) Keep the existing conversion and initialization path while binding format as positional-or-keyword, matching Python 3.14. Assisted-by: OpenAI Codex:model identifier unavailable --- crates/stdlib/src/pystruct.rs | 13 ++++++++++--- extra_tests/snippets/stdlib_struct.py | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/crates/stdlib/src/pystruct.rs b/crates/stdlib/src/pystruct.rs index 2a3c0dfe3..f586c1448 100644 --- a/crates/stdlib/src/pystruct.rs +++ b/crates/stdlib/src/pystruct.rs @@ -289,10 +289,17 @@ pub(crate) mod _struct { } } - impl Initializer for PyStruct { - type Args = IntoStructFormatBytes; + #[derive(FromArgs)] + struct StructArgs { + #[pyarg(any)] + format: IntoStructFormatBytes, + } - fn init(zelf: &Py, fmt: Self::Args, vm: &VirtualMachine) -> PyResult<()> { + impl Initializer for PyStruct { + type Args = StructArgs; + + fn init(zelf: &Py, args: Self::Args, vm: &VirtualMachine) -> PyResult<()> { + let fmt = args.format; // The format is read before anything is replaced, so a format that // cannot be read leaves the object as it was. let spec = fmt.format_spec(vm)?; diff --git a/extra_tests/snippets/stdlib_struct.py b/extra_tests/snippets/stdlib_struct.py index c80f55117..0f379df34 100644 --- a/extra_tests/snippets/stdlib_struct.py +++ b/extra_tests/snippets/stdlib_struct.py @@ -184,3 +184,21 @@ assert struct.pack("h", b">h"): + s = cls(format=fmt) + assert s.format == ">h" + assert s.pack(7) == b"\x00\x07" + s.__init__(format=">hh") + assert s.unpack(b"\x00\x01\x00\x02") == (1, 2) + with assert_raises(struct.error): + s.__init__(format="$") + assert s.format == ">hh" + assert s.pack(1, 2) == b"\x00\x01\x00\x02"