Skip to content

Commit 864b811

Browse files
committed
Add tests for CFieldInfo.
1 parent b14dd51 commit 864b811

3 files changed

Lines changed: 38 additions & 16 deletions

File tree

Lib/ctypes/util.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -516,9 +516,11 @@ def _process_struct(klass, /, *, align, layout, endian, pack):
516516
if get_origin(hint) is ClassVar:
517517
continue
518518

519-
field = [name, hint]
519+
field = [name]
520520
if get_origin(hint) is Annotated:
521-
field_info = get_args(hint)[1]
521+
args = get_args(hint)
522+
field.append(args[0])
523+
field_info = args[1]
522524
if not isinstance(field_info, CFieldInfo):
523525
raise TypeError(f"expected CFieldInfo in Annotated, got {field_info!r}")
524526

@@ -527,8 +529,8 @@ def _process_struct(klass, /, *, align, layout, endian, pack):
527529

528530
if field_info.anonymous is True:
529531
anonymous.append(name)
530-
531-
continue
532+
else:
533+
field.append(hint)
532534

533535
fields.append(field)
534536

Lib/test/test_ctypes/test_anon.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
11
import unittest
22
import test.support
33
from ctypes import c_int, Union, Structure, sizeof
4+
from ctypes.util import CFieldInfo, struct
5+
from typing import Annotated
46
from ._support import StructCheckMixin
57

68

79
class AnonTest(unittest.TestCase, StructCheckMixin):
810

9-
def test_anon(self):
11+
@test.support.subTests("use_struct_util", [False, True])
12+
def test_anon(self, use_struct_util):
1013
class ANON(Union):
1114
_fields_ = [("a", c_int),
1215
("b", c_int)]
1316
self.check_union(ANON)
1417

15-
class Y(Structure):
16-
_fields_ = [("x", c_int),
17-
("_", ANON),
18-
("y", c_int)]
19-
_anonymous_ = ["_"]
18+
if use_struct_util:
19+
@struct
20+
class Y:
21+
x: c_int
22+
_: Annotated[ANON, CFieldInfo(anonymous=True)]
23+
y: c_int
24+
else:
25+
class Y(Structure):
26+
_fields_ = [("x", c_int),
27+
("_", ANON),
28+
("y", c_int)]
29+
_anonymous_ = ["_"]
2030
self.check_struct(Y)
2131

2232
self.assertEqual(Y.a.offset, sizeof(c_int))

Lib/test/test_ctypes/test_bitfields.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import sys
3+
from typing import Annotated
34
import unittest
45
from ctypes import (CDLL, Structure, sizeof, POINTER, byref, alignment,
56
LittleEndianStructure, BigEndianStructure,
@@ -8,8 +9,9 @@
89
c_short, c_ushort, c_int, c_uint, c_long, c_ulong,
910
c_longlong, c_ulonglong,
1011
Union)
12+
from ctypes.util import struct, CFieldInfo
1113
from test import support
12-
from test.support import import_helper
14+
from test.support import import_helper, subTests
1315
from ._support import StructCheckMixin
1416
_ctypes_test = import_helper.import_module("_ctypes_test")
1517

@@ -126,11 +128,19 @@ def test_generic_checks(self):
126128
self.check_struct(BITS_msvc)
127129
self.check_struct(BITS_gcc)
128130

129-
def test_longlong(self):
130-
class X(Structure):
131-
_fields_ = [("a", c_longlong, 1),
132-
("b", c_longlong, 62),
133-
("c", c_longlong, 1)]
131+
@subTests("use_struct_util", [False, True])
132+
def test_longlong(self, use_struct_util):
133+
if use_struct_util:
134+
@struct
135+
class X:
136+
a: Annotated[c_longlong, CFieldInfo(bit_width=1)]
137+
b: Annotated[c_longlong, CFieldInfo(bit_width=62)]
138+
c: Annotated[c_longlong, CFieldInfo(bit_width=1)]
139+
else:
140+
class X(Structure):
141+
_fields_ = [("a", c_longlong, 1),
142+
("b", c_longlong, 62),
143+
("c", c_longlong, 1)]
134144
self.check_struct(X)
135145

136146
self.assertEqual(sizeof(X), sizeof(c_longlong))

0 commit comments

Comments
 (0)