https://github.com/python/cpython/commit/678b8e165646e72a2f39f017ad237210d3d481ef
commit: 678b8e165646e72a2f39f017ad237210d3d481ef
branch: main
author: sobolevn <m...@sobolevn.me>
committer: sobolevn <m...@sobolevn.me>
date: 2025-04-18T17:32:28+03:00
summary:

gh-132673: Fix `ctypes.Structure` with `_align_=0` (#132676)

Co-authored-by: Bénédikt Tran <10796600+picn...@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2025-04-18-14-34-43.gh-issue-132673.0sliCv.rst
M Lib/ctypes/_layout.py
M Lib/test/test_ctypes/test_aligned_structures.py

diff --git a/Lib/ctypes/_layout.py b/Lib/ctypes/_layout.py
index beb3b86414c010..0719e72cfed312 100644
--- a/Lib/ctypes/_layout.py
+++ b/Lib/ctypes/_layout.py
@@ -84,7 +84,7 @@ def get_layout(cls, input_fields, is_struct, base):
         raise ValueError('_align_ must be a non-negative integer')
     elif align == 0:
         # Setting `_align_ = 0` amounts to using the default alignment
-        align == 1
+        align = 1
 
     if base:
         align = max(ctypes.alignment(base), align)
diff --git a/Lib/test/test_ctypes/test_aligned_structures.py 
b/Lib/test/test_ctypes/test_aligned_structures.py
index 26d24f31b29f7b..0c563ab80559a6 100644
--- a/Lib/test/test_ctypes/test_aligned_structures.py
+++ b/Lib/test/test_ctypes/test_aligned_structures.py
@@ -1,7 +1,7 @@
 from ctypes import (
     c_char, c_uint32, c_uint16, c_ubyte, c_byte, alignment, sizeof,
     BigEndianStructure, LittleEndianStructure,
-    BigEndianUnion, LittleEndianUnion,
+    BigEndianUnion, LittleEndianUnion, Structure,
 )
 import struct
 import unittest
@@ -69,6 +69,41 @@ class Main(base):
             self.assertEqual(Main.z.offset, 8)
             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):
         data = bytearray(b"\0" * 8)
         for base in (LittleEndianStructure, BigEndianStructure):
diff --git 
a/Misc/NEWS.d/next/Library/2025-04-18-14-34-43.gh-issue-132673.0sliCv.rst 
b/Misc/NEWS.d/next/Library/2025-04-18-14-34-43.gh-issue-132673.0sliCv.rst
new file mode 100644
index 00000000000000..4d5a26caf0ea90
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-04-18-14-34-43.gh-issue-132673.0sliCv.rst
@@ -0,0 +1,2 @@
+Fix :exc:`AssertionError` raised on :class:`ctypes.Structure` with
+``_align_ = 0`` and ``_fields_ = []``.

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to