Skip to content

Commit fc0d904

Browse files
jorenhammingyu.park
authored andcommitted
_type_ class attributes in ctypes, and fix ctypes.wintypes.BYTE (python#13777)
1 parent f7c903b commit fc0d904

File tree

2 files changed

+104
-48
lines changed

2 files changed

+104
-48
lines changed

stdlib/ctypes/__init__.pyi

Lines changed: 94 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ from _ctypes import (
2727
from _typeshed import StrPath
2828
from ctypes._endian import BigEndianStructure as BigEndianStructure, LittleEndianStructure as LittleEndianStructure
2929
from types import GenericAlias
30-
from typing import Any, ClassVar, Generic, type_check_only
31-
from typing_extensions import Self, TypeAlias, TypeVar, deprecated
30+
from typing import Any, ClassVar, Generic, Literal, TypeVar, type_check_only
31+
from typing_extensions import Self, TypeAlias, deprecated
3232

3333
if sys.platform == "win32":
3434
from _ctypes import FormatError as FormatError, get_last_error as get_last_error, set_last_error as set_last_error
@@ -186,73 +186,121 @@ if sys.platform == "win32":
186186

187187
def wstring_at(ptr: _CVoidConstPLike, size: int = -1) -> str: ...
188188

189-
class c_byte(_SimpleCData[int]): ...
189+
class py_object(_CanCastTo, _SimpleCData[_T]):
190+
_type_: ClassVar[Literal["O"]]
191+
192+
class c_bool(_SimpleCData[bool]):
193+
_type_: ClassVar[Literal["?"]]
194+
def __init__(self, value: bool = ...) -> None: ...
195+
196+
class c_byte(_SimpleCData[int]):
197+
_type_: ClassVar[Literal["b"]]
198+
199+
class c_ubyte(_SimpleCData[int]):
200+
_type_: ClassVar[Literal["B"]]
201+
202+
class c_short(_SimpleCData[int]):
203+
_type_: ClassVar[Literal["h"]]
204+
205+
class c_ushort(_SimpleCData[int]):
206+
_type_: ClassVar[Literal["H"]]
207+
208+
class c_long(_SimpleCData[int]):
209+
_type_: ClassVar[Literal["l"]]
210+
211+
class c_ulong(_SimpleCData[int]):
212+
_type_: ClassVar[Literal["L"]]
213+
214+
class c_int(_SimpleCData[int]): # can be an alias for c_long
215+
_type_: ClassVar[Literal["i", "l"]]
216+
217+
class c_uint(_SimpleCData[int]): # can be an alias for c_ulong
218+
_type_: ClassVar[Literal["I", "L"]]
219+
220+
class c_longlong(_SimpleCData[int]): # can be an alias for c_long
221+
_type_: ClassVar[Literal["q", "l"]]
222+
223+
class c_ulonglong(_SimpleCData[int]): # can be an alias for c_ulong
224+
_type_: ClassVar[Literal["Q", "L"]]
225+
226+
c_int8 = c_byte
227+
c_uint8 = c_ubyte
228+
229+
class c_int16(_SimpleCData[int]): # can be an alias for c_short or c_int
230+
_type_: ClassVar[Literal["h", "i"]]
231+
232+
class c_uint16(_SimpleCData[int]): # can be an alias for c_ushort or c_uint
233+
_type_: ClassVar[Literal["H", "I"]]
234+
235+
class c_int32(_SimpleCData[int]): # can be an alias for c_int or c_long
236+
_type_: ClassVar[Literal["i", "l"]]
237+
238+
class c_uint32(_SimpleCData[int]): # can be an alias for c_uint or c_ulong
239+
_type_: ClassVar[Literal["I", "L"]]
240+
241+
class c_int64(_SimpleCData[int]): # can be an alias for c_long or c_longlong
242+
_type_: ClassVar[Literal["l", "q"]]
243+
244+
class c_uint64(_SimpleCData[int]): # can be an alias for c_ulong or c_ulonglong
245+
_type_: ClassVar[Literal["L", "Q"]]
246+
247+
class c_ssize_t(_SimpleCData[int]): # alias for c_int, c_long, or c_longlong
248+
_type_: ClassVar[Literal["i", "l", "q"]]
249+
250+
class c_size_t(_SimpleCData[int]): # alias for c_uint, c_ulong, or c_ulonglong
251+
_type_: ClassVar[Literal["I", "L", "Q"]]
252+
253+
class c_float(_SimpleCData[float]):
254+
_type_: ClassVar[Literal["f"]]
255+
256+
class c_double(_SimpleCData[float]):
257+
_type_: ClassVar[Literal["d"]]
258+
259+
class c_longdouble(_SimpleCData[float]): # can be an alias for c_double
260+
_type_: ClassVar[Literal["d", "g"]]
261+
262+
if sys.version_info >= (3, 14):
263+
class c_float_complex(_SimpleCData[complex]):
264+
_type_: ClassVar[Literal["E"]]
265+
266+
class c_double_complex(_SimpleCData[complex]):
267+
_type_: ClassVar[Literal["C"]]
268+
269+
class c_longdouble_complex(_SimpleCData[complex]):
270+
_type_: ClassVar[Literal["F"]]
190271

191272
class c_char(_SimpleCData[bytes]):
273+
_type_: ClassVar[Literal["c"]]
192274
def __init__(self, value: int | bytes | bytearray = ...) -> None: ...
193275

194276
class c_char_p(_PointerLike, _SimpleCData[bytes | None]):
277+
_type_: ClassVar[Literal["z"]]
195278
def __init__(self, value: int | bytes | None = ...) -> None: ...
196279
@classmethod
197280
def from_param(cls, value: Any, /) -> Self | _CArgObject: ...
198281

199-
class c_double(_SimpleCData[float]): ...
200-
class c_longdouble(_SimpleCData[float]): ... # can be an alias for c_double
201-
class c_float(_SimpleCData[float]): ...
202-
class c_int(_SimpleCData[int]): ... # can be an alias for c_long
203-
class c_long(_SimpleCData[int]): ...
204-
class c_longlong(_SimpleCData[int]): ... # can be an alias for c_long
205-
class c_short(_SimpleCData[int]): ...
206-
class c_size_t(_SimpleCData[int]): ... # alias for c_uint, c_ulong, or c_ulonglong
207-
class c_ssize_t(_SimpleCData[int]): ... # alias for c_int, c_long, or c_longlong
208-
class c_ubyte(_SimpleCData[int]): ...
209-
class c_uint(_SimpleCData[int]): ... # can be an alias for c_ulong
210-
class c_ulong(_SimpleCData[int]): ...
211-
class c_ulonglong(_SimpleCData[int]): ... # can be an alias for c_ulong
212-
class c_ushort(_SimpleCData[int]): ...
213-
214282
class c_void_p(_PointerLike, _SimpleCData[int | None]):
283+
_type_: ClassVar[Literal["P"]]
215284
@classmethod
216285
def from_param(cls, value: Any, /) -> Self | _CArgObject: ...
217286

218287
c_voidp = c_void_p # backwards compatibility (to a bug)
219288

220-
class c_wchar(_SimpleCData[str]): ...
221-
222-
c_int8 = c_byte
223-
224-
# these are actually dynamic aliases for c_short, c_int, c_long, or c_longlong
225-
class c_int16(_SimpleCData[int]): ...
226-
class c_int32(_SimpleCData[int]): ...
227-
class c_int64(_SimpleCData[int]): ...
228-
229-
c_uint8 = c_ubyte
230-
231-
# these are actually dynamic aliases for c_ushort, c_uint, c_ulong, or c_ulonglong
232-
class c_uint16(_SimpleCData[int]): ...
233-
class c_uint32(_SimpleCData[int]): ...
234-
class c_uint64(_SimpleCData[int]): ...
289+
class c_wchar(_SimpleCData[str]):
290+
_type_: ClassVar[Literal["u"]]
235291

236292
class c_wchar_p(_PointerLike, _SimpleCData[str | None]):
293+
_type_: ClassVar[Literal["Z"]]
237294
def __init__(self, value: int | str | None = ...) -> None: ...
238295
@classmethod
239296
def from_param(cls, value: Any, /) -> Self | _CArgObject: ...
240297

241-
class c_bool(_SimpleCData[bool]):
242-
def __init__(self, value: bool = ...) -> None: ...
243-
244298
if sys.platform == "win32":
245-
class HRESULT(_SimpleCData[int]): ... # TODO: undocumented
299+
class HRESULT(_SimpleCData[int]): # TODO: undocumented
300+
_type_: ClassVar[Literal["l"]]
246301

247302
if sys.version_info >= (3, 12):
248303
# At runtime, this is an alias for either c_int32 or c_int64,
249-
# which are themselves an alias for one of c_short, c_int, c_long, or c_longlong
304+
# which are themselves an alias for one of c_int, c_long, or c_longlong
250305
# This covers all our bases.
251-
c_time_t: type[c_int32 | c_int64 | c_short | c_int | c_long | c_longlong]
252-
253-
class py_object(_CanCastTo, _SimpleCData[_T]): ...
254-
255-
if sys.version_info >= (3, 14):
256-
class c_float_complex(_SimpleCData[complex]): ...
257-
class c_double_complex(_SimpleCData[complex]): ...
258-
class c_longdouble_complex(_SimpleCData[complex]): ...
306+
c_time_t: type[c_int32 | c_int64 | c_int | c_long | c_longlong]

stdlib/ctypes/wintypes.pyi

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import sys
12
from _ctypes import _CArgObject, _CField
23
from ctypes import (
34
Array,
45
Structure,
56
_Pointer,
67
_SimpleCData,
7-
c_byte,
88
c_char,
99
c_char_p,
1010
c_double,
@@ -24,7 +24,15 @@ from ctypes import (
2424
from typing import Any, TypeVar
2525
from typing_extensions import Self, TypeAlias
2626

27-
BYTE = c_byte
27+
if sys.version_info >= (3, 12):
28+
from ctypes import c_ubyte
29+
30+
BYTE = c_ubyte
31+
else:
32+
from ctypes import c_byte
33+
34+
BYTE = c_byte
35+
2836
WORD = c_ushort
2937
DWORD = c_ulong
3038
CHAR = c_char

0 commit comments

Comments
 (0)