mirror of
https://github.com/python/cpython.git
synced 2025-10-22 06:32:43 +00:00
gh-132673: Fix ctypes.Structure
with _align_=0
(#132676)
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
parent
40ae88988c
commit
678b8e1656
3 changed files with 39 additions and 2 deletions
|
@ -84,7 +84,7 @@ def get_layout(cls, input_fields, is_struct, base):
|
||||||
raise ValueError('_align_ must be a non-negative integer')
|
raise ValueError('_align_ must be a non-negative integer')
|
||||||
elif align == 0:
|
elif align == 0:
|
||||||
# Setting `_align_ = 0` amounts to using the default alignment
|
# Setting `_align_ = 0` amounts to using the default alignment
|
||||||
align == 1
|
align = 1
|
||||||
|
|
||||||
if base:
|
if base:
|
||||||
align = max(ctypes.alignment(base), align)
|
align = max(ctypes.alignment(base), align)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from ctypes import (
|
from ctypes import (
|
||||||
c_char, c_uint32, c_uint16, c_ubyte, c_byte, alignment, sizeof,
|
c_char, c_uint32, c_uint16, c_ubyte, c_byte, alignment, sizeof,
|
||||||
BigEndianStructure, LittleEndianStructure,
|
BigEndianStructure, LittleEndianStructure,
|
||||||
BigEndianUnion, LittleEndianUnion,
|
BigEndianUnion, LittleEndianUnion, Structure,
|
||||||
)
|
)
|
||||||
import struct
|
import struct
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -69,6 +69,41 @@ class TestAlignedStructures(unittest.TestCase, StructCheckMixin):
|
||||||
self.assertEqual(Main.z.offset, 8)
|
self.assertEqual(Main.z.offset, 8)
|
||||||
self.assertEqual(main.z, 7)
|
self.assertEqual(main.z, 7)
|
||||||
|
|
||||||
|
def test_negative_align(self):
|
||||||
|
for base in (Structure, LittleEndianStructure, BigEndianStructure):
|
||||||
|
with (
|
||||||
|
self.subTest(base=base),
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
ValueError,
|
||||||
|
'_align_ must be a non-negative integer',
|
||||||
|
)
|
||||||
|
):
|
||||||
|
class MyStructure(base):
|
||||||
|
_align_ = -1
|
||||||
|
_fields_ = []
|
||||||
|
|
||||||
|
def test_zero_align_no_fields(self):
|
||||||
|
for base in (Structure, LittleEndianStructure, BigEndianStructure):
|
||||||
|
with self.subTest(base=base):
|
||||||
|
class MyStructure(base):
|
||||||
|
_align_ = 0
|
||||||
|
_fields_ = []
|
||||||
|
|
||||||
|
self.assertEqual(alignment(MyStructure), 1)
|
||||||
|
self.assertEqual(alignment(MyStructure()), 1)
|
||||||
|
|
||||||
|
def test_zero_align_with_fields(self):
|
||||||
|
for base in (Structure, LittleEndianStructure, BigEndianStructure):
|
||||||
|
with self.subTest(base=base):
|
||||||
|
class MyStructure(base):
|
||||||
|
_align_ = 0
|
||||||
|
_fields_ = [
|
||||||
|
("x", c_ubyte),
|
||||||
|
]
|
||||||
|
|
||||||
|
self.assertEqual(alignment(MyStructure), 1)
|
||||||
|
self.assertEqual(alignment(MyStructure()), 1)
|
||||||
|
|
||||||
def test_oversized_structure(self):
|
def test_oversized_structure(self):
|
||||||
data = bytearray(b"\0" * 8)
|
data = bytearray(b"\0" * 8)
|
||||||
for base in (LittleEndianStructure, BigEndianStructure):
|
for base in (LittleEndianStructure, BigEndianStructure):
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix :exc:`AssertionError` raised on :class:`ctypes.Structure` with
|
||||||
|
``_align_ = 0`` and ``_fields_ = []``.
|
Loading…
Add table
Add a link
Reference in a new issue