10000 gh-132673: Fix `ctypes.Structure` with `_align_=0` (#132676) · python/cpython@678b8e1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 678b8e1

Browse files
sobolevnpicnixz
andauthored
gh-132673: Fix ctypes.Structure with _align_=0 (#132676)
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
1 parent 40ae889 commit 678b8e1

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

Lib/ctypes/_layout.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def get_layout(cls, input_fields, is_struct, base):
8484
raise ValueError('_align_ must be a non-negative integer')
8585
elif align == 0:
8686
# Setting `_align_ = 0` amounts to using the default alignment
87-
align == 1
87+
align = 1
8888

8989
if base:
9090
align = max(ctypes.alignment(base), align)

Lib/test/test_ctypes/test_aligned_structures.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from ctypes import (
22
c_char, c_uint32, c_uint16, c_ubyte, c_byte, alignment, sizeof,
33
BigEndianStructure, LittleEndianStructure,
4-
BigEndianUnion, LittleEndianUnion,
4+
BigEndianUnion, LittleEndianUnion, Structure,
55
)
66
import struct
77
import unittest
@@ -69,6 +69,41 @@ class Main(base):
6969
self.assertEqual(Main.z.offset, 8)
7070
self.assertEqual(main.z, 7)
7171

72+
def test_negative_align(self):
73+
for base in (Structure, LittleEndianStructure, BigEndianStructure):
74+
with (
75+
self.subTest(base=base),
76+
self.assertRaisesRegex(
77+
ValueError,
78+
'_align_ must be a non-negative integer',
79+
)
80+
):
81+
class MyStructure(base):
82+
_align_ = -1
83+
_fields_ = []
84+
85+
def test_zero_align_no_fields(self):
86+
for base in (Structure, LittleEndianStructure, BigEndianStructure):
87+
with self.subTest(base=base):
88+
class MyStructure(base):
89+
_align_ = 0
90+
_fields_ = []
91+
92+
self.assertEqual(alignment(MyStructure), 1)
93+
self.assertEqual(alignment(MyStructure()), 1)
94+
95+
def test_zero_align_with_fields(self):
96+
for base in (Structure, LittleEndianStructure, BigEndianStructure):
97+
with self.subTest(base=base):
98+
class MyStructure(base):
99+
_align_ = 0
100+
_fields_ = [
101+
("x", c_ubyte),
102+
]
103+
104+
self.assertEqual(alignment(MyStructure), 1)
105+
self.assertEqual(alignment(MyStructure()), 1)
106+
72107
def test_oversized_structure(self):
73108
data = bytearray(b"\0" * 8)
74109
for base in (LittleEndianStructure, BigEndianStructure):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :exc:`AssertionError` raised on :class:`ctypes.Structure` with
2+
``_align_ = 0`` and ``_fields_ = []``.

0 commit comments

Comments
 (0)
0