Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-cstruct for openSUSE:Factory checked in at 2022-11-05 14:46:59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-cstruct (Old) and /work/SRC/openSUSE:Factory/.python-cstruct.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-cstruct" Sat Nov 5 14:46:59 2022 rev:4 rq:1033640 version:4.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-cstruct/python-cstruct.changes 2022-10-25 11:20:28.434198683 +0200 +++ /work/SRC/openSUSE:Factory/.python-cstruct.new.2275/python-cstruct.changes 2022-11-05 14:47:05.142704661 +0100 @@ -1,0 +2,7 @@ +Fri Nov 4 19:12:43 UTC 2022 - Martin Hauke <[email protected]> + +- Update to version 4.0 + * Add enum support to cstruct.parse + * Add typedef parsing + +------------------------------------------------------------------- Old: ---- python-cstruct-3.3.tar.gz New: ---- python-cstruct-4.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-cstruct.spec ++++++ --- /var/tmp/diff_new_pack.hwZIgj/_old 2022-11-05 14:47:05.794708465 +0100 +++ /var/tmp/diff_new_pack.hwZIgj/_new 2022-11-05 14:47:05.798708488 +0100 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-cstruct -Version: 3.3 +Version: 4.0 Release: 0 Summary: C-style structs for Python License: MIT ++++++ python-cstruct-3.3.tar.gz -> python-cstruct-4.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-cstruct-3.3/changelog.txt new/python-cstruct-4.0/changelog.txt --- old/python-cstruct-3.3/changelog.txt 2022-10-24 10:20:02.000000000 +0200 +++ new/python-cstruct-4.0/changelog.txt 2022-11-01 14:19:44.000000000 +0100 @@ -163,3 +163,15 @@ ### Fix - Fix padding tests on 32bit architectures + +### 4.0 + +2022-11-01 + +### Added + +- Add support for nameless inline struct + +### Improved + +- Python 3.11 support diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-cstruct-3.3/cstruct/__init__.py new/python-cstruct-4.0/cstruct/__init__.py --- old/python-cstruct-3.3/cstruct/__init__.py 2022-10-24 10:20:02.000000000 +0200 +++ new/python-cstruct-4.0/cstruct/__init__.py 2022-11-01 14:19:44.000000000 +0100 @@ -24,7 +24,7 @@ __author__ = 'Andrea Bonomi <[email protected]>' __license__ = 'MIT' -__version__ = '3.3' +__version__ = '4.0' __date__ = '15 August 2013' import struct diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-cstruct-3.3/cstruct/c_parser.py new/python-cstruct-4.0/cstruct/c_parser.py --- old/python-cstruct-3.3/cstruct/c_parser.py 2022-10-24 10:20:02.000000000 +0200 +++ new/python-cstruct-4.0/cstruct/c_parser.py 2022-11-01 14:19:44.000000000 +0100 @@ -78,43 +78,47 @@ # signed/unsigned/struct if c_type in ['signed', 'unsigned', 'struct', 'union'] and len(tokens) > 1: c_type = c_type + " " + tokens.pop() - next_token = tokens.pop() - # short int, long int, or long long - if next_token in ['int', 'long']: - c_type = c_type + " " + next_token - next_token = tokens.pop() - # void * - if next_token.startswith("*"): - next_token = next_token[1:] - c_type = 'void *' - # parse length + vlen = 1 flexible_array = False - if "[" in next_token: - t = next_token.split("[") - if len(t) != 2: - raise ParserError("Error parsing: " + next_token) - next_token = t[0].strip() - vlen_part = t[1] - vlen_expr = [] - while not vlen_part.endswith("]"): + + if not c_type.endswith("{"): + next_token = tokens.pop() + # short int, long int, or long long + if next_token in ['int', 'long']: + c_type = c_type + " " + next_token + next_token = tokens.pop() + # void * + if next_token.startswith("*"): + next_token = next_token[1:] + c_type = 'void *' + # parse length + if "[" in next_token: + t = next_token.split("[") + if len(t) != 2: + raise ParserError("Error parsing: " + next_token) + next_token = t[0].strip() + vlen_part = t[1] + vlen_expr = [] + while not vlen_part.endswith("]"): + vlen_expr.append(vlen_part.split("]")[0].strip()) + vlen_part = tokens.pop() + t_vlen = vlen_part.split("]")[0].strip() vlen_expr.append(vlen_part.split("]")[0].strip()) - vlen_part = tokens.pop() - t_vlen = vlen_part.split("]")[0].strip() - vlen_expr.append(vlen_part.split("]")[0].strip()) - t_vlen = " ".join(vlen_expr) - if not t_vlen: - flexible_array = True - vlen = 0 - else: - try: - vlen = c_eval(t_vlen) - except (ValueError, TypeError): - vlen = int(t_vlen) - tokens.push(next_token) - # resolve typedefs - while c_type in TYPEDEFS: - c_type = TYPEDEFS[c_type] + t_vlen = " ".join(vlen_expr) + if not t_vlen: + flexible_array = True + vlen = 0 + else: + try: + vlen = c_eval(t_vlen) + except (ValueError, TypeError): + vlen = int(t_vlen) + tokens.push(next_token) + # resolve typedefs + while c_type in TYPEDEFS: + c_type = TYPEDEFS[c_type] + # calculate fmt if c_type.startswith('struct ') or c_type.startswith('union '): # struct/union c_type, tail = c_type.split(' ', 1) @@ -178,6 +182,7 @@ flexible_array: bool = False offset: int = 0 max_alignment: int = 0 + anonymous: int = 0 if isinstance(__struct__, Tokens): tokens = __struct__ else: @@ -191,6 +196,18 @@ raise CStructException("Flexible array member must be the last member of such a struct") field_type = parse_type(tokens, __cls__, __byte_order__, offset) vname = tokens.pop() + if vname in fields_types: + raise ParserError("Duplicate member '{}'".format(vname)) + # anonymous nested union + if vname == ';' and field_type.ref is not None and (__is_union__ or field_type.ref.__is_union__): + # add the anonymous struct fields to the parent + for nested_field_name, nested_field_type in field_type.ref.__fields_types__.items(): + if nested_field_name in fields_types: + raise ParserError("Duplicate member '{}'".format(nested_field_name)) + fields_types[nested_field_name] = nested_field_type + vname = "__anonymous{}".format(anonymous) + anonymous += 1 + tokens.push(';') fields_types[vname] = field_type # calculate the max field size (for the alignment) max_alignment = max(max_alignment, field_type.alignment) @@ -200,7 +217,7 @@ offset = field_type.offset + field_type.vsize t = tokens.pop() if t != ';': - raise ParserError("; expected but %s found" % t) + raise ParserError("; expected but {} found".format(t)) if __is_union__: # C union # Calculate the sizeof union as size of its largest element diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-cstruct-3.3/cstruct/field.py new/python-cstruct-4.0/cstruct/field.py --- old/python-cstruct-3.3/cstruct/field.py 2022-10-24 10:20:02.000000000 +0200 +++ new/python-cstruct-4.0/cstruct/field.py 2022-11-01 14:19:44.000000000 +0100 @@ -220,3 +220,6 @@ def copy(self) -> "FieldType": "Return a shallow copy of this FieldType" return copy.copy(self) + + def __repr__(self) -> str: # pragma: no cover + return repr(self.__dict__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-cstruct-3.3/setup.py new/python-cstruct-4.0/setup.py --- old/python-cstruct-3.3/setup.py 2022-10-24 10:20:02.000000000 +0200 +++ new/python-cstruct-4.0/setup.py 2022-11-01 14:19:44.000000000 +0100 @@ -22,6 +22,7 @@ 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', ], keywords='struct', author='Andrea Bonomi', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-cstruct-3.3/tests/test_cstruct.py new/python-cstruct-4.0/tests/test_cstruct.py --- old/python-cstruct-3.3/tests/test_cstruct.py 2022-10-24 10:20:02.000000000 +0200 +++ new/python-cstruct-4.0/tests/test_cstruct.py 2022-11-01 14:19:44.000000000 +0100 @@ -25,11 +25,13 @@ # # ***************************************************************************** +import pytest import cstruct from cstruct import sizeof, typedef import io import os from pathlib import Path +from cstruct.exceptions import ParserError MBR_DATA = (Path(__file__).parent.parent / 'mbr').read_bytes() @@ -75,10 +77,12 @@ class Dummy(cstruct.CStruct): __byte_order__ = cstruct.LITTLE_ENDIAN __def__ = """ + struct { struct { + int i; + } s; char c; char vc[10]; - int i; int vi[10]; long long l; long vl[10]; @@ -210,6 +214,7 @@ def test_dummy(): dummy = Dummy() + dummy.c = b'A' dummy.vc = b'ABCDEFGHIJ' dummy.i = 123456 @@ -252,3 +257,11 @@ c = Dummy() assert c is not None assert c != None + + +def test_invalid_inline(): + with pytest.raises(ParserError): + cstruct.MemCStruct.parse( + 'struct { unsigned char head; unsigned char head; }', __byte_order__=cstruct.LITTLE_ENDIAN + ) + assert False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-cstruct-3.3/tests/test_memcstruct.py new/python-cstruct-4.0/tests/test_memcstruct.py --- old/python-cstruct-3.3/tests/test_memcstruct.py 2022-10-24 10:20:02.000000000 +0200 +++ new/python-cstruct-4.0/tests/test_memcstruct.py 2022-11-01 14:19:44.000000000 +0100 @@ -25,10 +25,12 @@ # # ***************************************************************************** +import pytest import cstruct from cstruct import sizeof, typedef import os from pathlib import Path +from cstruct.exceptions import ParserError MBR_DATA = (Path(__file__).parent.parent / 'mbr').read_bytes() @@ -249,3 +251,11 @@ c = Dummy() assert c is not None assert c != None + + +def test_invalid_inline(): + with pytest.raises(ParserError): + cstruct.MemCStruct.parse( + 'struct { unsigned char head; unsigned char head; }', __byte_order__=cstruct.LITTLE_ENDIAN + ) + assert False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-cstruct-3.3/tests/test_nested.py new/python-cstruct-4.0/tests/test_nested.py --- old/python-cstruct-3.3/tests/test_nested.py 1970-01-01 01:00:00.000000000 +0100 +++ new/python-cstruct-4.0/tests/test_nested.py 2022-11-01 14:19:44.000000000 +0100 @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# ***************************************************************************** +# +# Copyright (c) 2013-2019 Andrea Bonomi <[email protected]> +# +# Published under the terms of the MIT license. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# ***************************************************************************** + +import pytest +import cstruct +from cstruct import sizeof +from cstruct.exceptions import ParserError + + +INVALID_ANONYMOUS = """ + struct NestedStruct { + struct { + int a; + int b; + }; + int a; + int b; + }; +""" + + +class NestedStruct(cstruct.MemCStruct): + __byte_order__ = cstruct.LITTLE_ENDIAN + __def__ = """ + struct NestedStruct { + struct { + int a; + int b; + } s; + int a; + int b; + }; + """ + + +class NestedUnion(cstruct.MemCStruct): + __byte_order__ = cstruct.LITTLE_ENDIAN + __def__ = """ + union NestedUnion { + struct { + int a; + int b; + } s; + int a; + }; + """ + + +class NestedAnonymousUnion(cstruct.MemCStruct): + __byte_order__ = cstruct.LITTLE_ENDIAN + __def__ = """ + union NestedAnonymousUnion { + struct { + int a; + int b; + }; + int c; + }; + """ + + +class Packet(cstruct.MemCStruct): + __byte_order__ = cstruct.LITTLE_ENDIAN + __def__ = """ + #define MaxPacket 20 + + struct Packet { + uint8_t packetLength; + union { + uint8_t bytes[MaxPacket]; + struct { + uint16_t field1; + uint16_t field2; + uint16_t field3; + } format1; + struct { + double value1; + double value2; + } format2; + }; + }; + """ + + +def test_invalid_anonymous(): + with pytest.raises(ParserError): + cstruct.parse(INVALID_ANONYMOUS) + assert True + + +def test_sizeof_nested_struct(): + assert sizeof('struct NestedStruct') == 16 + o = NestedStruct() + assert len(o) == 16 + + +def test_pack_unpack_nested_struct(): + o = NestedStruct() + o.s.a = 1 + o.s.b = 2 + o.a = 10 + o.b = 20 + b = o.pack() + o1 = NestedStruct() + + o1.unpack(b) + assert o1.s.a == 1 + assert o1.s.b == 2 + assert o1.a == 10 + assert o1.b == 20 + + +def test_sizeof_nested_union(): + assert sizeof('struct NestedUnion') == 8 + o = NestedUnion() + assert len(o) == 8 + + +def test_pack_unpack_nested_union(): + o = NestedUnion() + o.s.a = 1 + o.s.b = 2 + b = o.pack() + + o1 = NestedUnion() + o1.unpack(b) + assert o1.s.a == 1 + assert o1.s.b == 2 + + o = NestedUnion() + o.a = 1979 + b = o.pack() + + o1 = NestedUnion() + o1.unpack(b) + assert o1.a == 1979 + o1.s.b = 0 + assert o1.a == 1979 + o1.s.a = 0 + assert o1.a == 0 + + +def test_sizeof_nested_anonymous_union(): + assert sizeof('struct NestedAnonymousUnion') == 8 + o = NestedAnonymousUnion() + assert len(o) == 8 + + +def test_pack_unpack_nested_anonymous_union(): + o = NestedAnonymousUnion() + o.a = 1 + o.b = 2 + b = o.pack() + + o1 = NestedAnonymousUnion() + o1.unpack(b) + assert o1.a == 1 + assert o1.b == 2 + + o = NestedAnonymousUnion() + o.c = 1979 + b = o.pack() + + o1 = NestedAnonymousUnion() + o1.unpack(b) + assert o1.c == 1979 + o1.b = 0 + assert o1.c == 1979 + o1.a = 0 + assert o1.c == 0 + + +def test_nested_anonymous_union_struct(): + o = Packet() + assert sizeof("struct Packet") == len(o) + + o = Packet() + o.packetLength = 10 + o.format1.field1 = 11 + o.format1.field2 = 12 + o.format1.field3 = 13 + b = o.pack() + + o1 = Packet() + o1.unpack(b) + assert o1.format1.field1 == 11 + assert o1.format1.field2 == 12 + assert o1.format1.field3 == 13
