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"