This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2021-01-30 04:38 by MrSurly, last changed 2022-04-11 14:59 by admin.
Messages (2) | |||
---|---|---|---|
msg385970 - (view) | Author: Eric Poulsen (MrSurly) | Date: 2021-01-30 04:38 | |
Placing a ctypes.Union inside of a ctypes.BigEndianStructure results in "TypeError: This type does not support other endian". I believe this is a similar problem to issue #4376 (https://bugs.python.org/issue4376) Minimum repro test case: import ctypes as ct class U(ct.Union): _pack_=True _fields_=[ ('a', ct.c_int), ('b', ct.c_int), ] class S(ct.BigEndianStructure): _pack_=True _fields_=[ ('x', ct.c_int), ('y', U), ] I believe the fix is similar to that issue, though I admit I don't know enough about this code to be sure. diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py index 37444bd6a7..525c5e58c9 100644 --- a/Lib/ctypes/_endian.py +++ b/Lib/ctypes/_endian.py @@ -18,6 +18,9 @@ def _other_endian(typ): # if typ is structure if issubclass(typ, Structure): return typ + # if typ is union: + if issubclass(typ, Union): + return typ raise TypeError("This type does not support other endian: %s" % typ) class _swapped_meta(type(Structure)): |
|||
msg405906 - (view) | Author: Jan Chren (rindeal) | Date: 2021-11-07 14:24 | |
I have created a workaround, since it might take years to fix this in master. Hope it'll come in useful. For the example in https://bugs.python.org/issue43073#msg385970, but probably any combination of Unions and BigEndianStructures can be constructed this way. ``` class U_a(ct.BigEndianStructure): _pack_ = True _fields_ = [('a', ct.c_int)] class U_b(ct.BigEndianStructure): _pack_ = True _fields_ = [('b', ct.c_int)] class U(ct.Union): _pack_ = True _fields_ = [ ('_a', U_a), ('_b', U_b), ] _anonymous_ = ['_a', '_b'] class _S_be_fields_only(ct.Structure): _pack_ = True _fields_ = [ ('_x', ct.c_int), ('y', U), ] class _S_2be_fields_only(ct.BigEndianStructure): _pack_ = True _fields_ = [ ('x', ct.c_int), ('_y', ct.c_byte * ct.sizeof(U)), ] class _S_U(ct.Union): _pack_ = True _fields_ = [ ('_be_fields_only', _S_be_fields_only), ('_2be_fields_only', _S_2be_fields_only), ] _anonymous_ = [f[0] for f in _fields_] class S(ct.Structure): _pack_ = True _fields_ = [('_s_u', _S_U)] _anonymous_ = [_fields_[0][0]] issubclass(S, ct.Structure) == True s = S(x=0x11223344, y=U(a=0xaabbccdd)) s.y.a == s.y.b bytes(s).hex() == "11223344aabbccdd" ``` |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:59:40 | admin | set | github: 87239 |
2021-11-07 14:24:54 | rindeal | set | nosy:
+ rindeal messages: + msg405906 |
2021-01-30 04:38:58 | MrSurly | create |