From 75cfa40fc8c369ac58d9a4cbd685f4c1c431544d Mon Sep 17 00:00:00 2001 From: Ryan May Date: Fri, 2 Oct 2020 00:50:50 -0600 Subject: [PATCH] ENH: Support packing NamedStructs This paves the way towards writing instances of NamedStructs. --- src/metpy/io/_tools.py | 5 +++++ tests/io/test_tools.py | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/io/test_tools.py diff --git a/src/metpy/io/_tools.py b/src/metpy/io/_tools.py index a875e77ff74..cb68001d364 100644 --- a/src/metpy/io/_tools.py +++ b/src/metpy/io/_tools.py @@ -97,6 +97,11 @@ def unpack_file(self, fobj): """Unpack the next bytes from a file object.""" return self.unpack(fobj.read(self.size)) + def pack(self, **kwargs): + """Pack the arguments into bytes using the structure.""" + t = self.make_tuple(**kwargs) + return super().pack(*t) + # This works around times when we have more than 255 items and can't use # NamedStruct. This is a CPython limit for arguments. diff --git a/tests/io/test_tools.py b/tests/io/test_tools.py new file mode 100644 index 00000000000..5f279b870c9 --- /dev/null +++ b/tests/io/test_tools.py @@ -0,0 +1,22 @@ +# Copyright (c) 2020 MetPy Developers. +# Distributed under the terms of the BSD 3-Clause License. +# SPDX-License-Identifier: BSD-3-Clause +"""Test the `_tools` module.""" + +from metpy.io._tools import NamedStruct + +def test_unpack(): + """Test unpacking a NamedStruct from bytes.""" + struct = NamedStruct([('field1', 'i'), ('field2', 'h')], '>') + + s = struct.unpack(b'\x00\x01\x00\x01\x00\x02') + assert s.field1 == 65537 + assert s.field2 == 2 + + +def test_pack(): + """Test packing a NamedStruct into bytes.""" + struct = NamedStruct([('field1', 'i'), ('field2', 'h')], '>') + + b = struct.pack(field1=8, field2=3) + assert b == b'\x00\x00\x00\x08\x00\x03'