Skip to content

_CField as a generic descriptor protocol #10595

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions stdlib/_ctypes.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,23 @@ class CFuncPtr(_PointerLike, _CData):

def __call__(self, *args: Any, **kwargs: Any) -> Any: ...

class _CField:
_GetT = TypeVar("_GetT")
_SetT = TypeVar("_SetT")

class _CField(Generic[_CT, _GetT, _SetT]):
offset: int
size: int
@overload
def __get__(self, __instance: None, __owner: type[Any] | None) -> Self: ...
@overload
def __get__(self, __instance: Any, __owner: type[Any] | None) -> _GetT: ...
def __set__(self, __instance: Any, __value: _SetT) -> None: ...

class _StructUnionMeta(_CDataMeta):
_fields_: Sequence[tuple[str, type[_CData]] | tuple[str, type[_CData], int]]
_pack_: int
_anonymous_: Sequence[str]
def __getattr__(self, name: str) -> _CField: ...
def __getattr__(self, name: str) -> _CField[Any, Any, Any]: ...

class _StructUnionBase(_CData, metaclass=_StructUnionMeta):
def __init__(self, *args: Any, **kw: Any) -> None: ...
Expand Down
89 changes: 47 additions & 42 deletions stdlib/ctypes/wintypes.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from ctypes import (
Array,
Structure,
_CField,
_Pointer,
_SimpleCData,
c_byte,
Expand All @@ -20,6 +21,7 @@ from ctypes import (
c_wchar,
c_wchar_p,
)
from typing import TypeVar
from typing_extensions import TypeAlias

BYTE = c_byte
Expand Down Expand Up @@ -101,85 +103,88 @@ HWND = HANDLE
SC_HANDLE = HANDLE
SERVICE_STATUS_HANDLE = HANDLE

_CIntLikeT = TypeVar("_CIntLikeT", bound=_SimpleCData[int])
_CIntLikeField: TypeAlias = _CField[_CIntLikeT, int, _CIntLikeT | int]

class RECT(Structure):
left: LONG
top: LONG
right: LONG
bottom: LONG
left: _CIntLikeField[LONG]
top: _CIntLikeField[LONG]
right: _CIntLikeField[LONG]
bottom: _CIntLikeField[LONG]

RECTL = RECT
_RECTL = RECT
tagRECT = RECT

class _SMALL_RECT(Structure):
Left: SHORT
Top: SHORT
Right: SHORT
Bottom: SHORT
Left: _CIntLikeField[SHORT]
Top: _CIntLikeField[SHORT]
Right: _CIntLikeField[SHORT]
Bottom: _CIntLikeField[SHORT]

SMALL_RECT = _SMALL_RECT

class _COORD(Structure):
X: SHORT
Y: SHORT
X: _CIntLikeField[SHORT]
Y: _CIntLikeField[SHORT]

class POINT(Structure):
x: LONG
y: LONG
x: _CIntLikeField[LONG]
y: _CIntLikeField[LONG]

POINTL = POINT
_POINTL = POINT
tagPOINT = POINT

class SIZE(Structure):
cx: LONG
cy: LONG
cx: _CIntLikeField[LONG]
cy: _CIntLikeField[LONG]

SIZEL = SIZE
tagSIZE = SIZE

def RGB(red: int, green: int, blue: int) -> int: ...

class FILETIME(Structure):
dwLowDateTime: DWORD
dwHighDateTime: DWORD
dwLowDateTime: _CIntLikeField[DWORD]
dwHighDateTime: _CIntLikeField[DWORD]

_FILETIME = FILETIME

class MSG(Structure):
hWnd: HWND
message: UINT
wParam: WPARAM
lParam: LPARAM
time: DWORD
pt: POINT
hWnd: _CField[HWND, int | None, HWND | int | None]
message: _CIntLikeField[UINT]
wParam: _CIntLikeField[WPARAM]
lParam: _CIntLikeField[LPARAM]
time: _CIntLikeField[DWORD]
pt: _CField[POINT, POINT, POINT]

tagMSG = MSG
MAX_PATH: int

class WIN32_FIND_DATAA(Structure):
dwFileAttributes: DWORD
ftCreationTime: FILETIME
ftLastAccessTime: FILETIME
ftLastWriteTime: FILETIME
nFileSizeHigh: DWORD
nFileSizeLow: DWORD
dwReserved0: DWORD
dwReserved1: DWORD
cFileName: Array[CHAR]
cAlternateFileName: Array[CHAR]
dwFileAttributes: _CIntLikeField[DWORD]
ftCreationTime: _CField[FILETIME, FILETIME, FILETIME]
ftLastAccessTime: _CField[FILETIME, FILETIME, FILETIME]
ftLastWriteTime: _CField[FILETIME, FILETIME, FILETIME]
nFileSizeHigh: _CIntLikeField[DWORD]
nFileSizeLow: _CIntLikeField[DWORD]
dwReserved0: _CIntLikeField[DWORD]
dwReserved1: _CIntLikeField[DWORD]
cFileName: _CField[Array[CHAR], bytes, bytes]
cAlternateFileName: _CField[Array[CHAR], bytes, bytes]

class WIN32_FIND_DATAW(Structure):
dwFileAttributes: DWORD
ftCreationTime: FILETIME
ftLastAccessTime: FILETIME
ftLastWriteTime: FILETIME
nFileSizeHigh: DWORD
nFileSizeLow: DWORD
dwReserved0: DWORD
dwReserved1: DWORD
cFileName: Array[WCHAR]
cAlternateFileName: Array[WCHAR]
dwFileAttributes: _CIntLikeField[DWORD]
ftCreationTime: _CField[FILETIME, FILETIME, FILETIME]
ftLastAccessTime: _CField[FILETIME, FILETIME, FILETIME]
ftLastWriteTime: _CField[FILETIME, FILETIME, FILETIME]
nFileSizeHigh: _CIntLikeField[DWORD]
nFileSizeLow: _CIntLikeField[DWORD]
dwReserved0: _CIntLikeField[DWORD]
dwReserved1: _CIntLikeField[DWORD]
cFileName: _CField[Array[WCHAR], str, str]
cAlternateFileName: _CField[Array[WCHAR], str, str]

# These pointer type definitions use _Pointer[...] instead of POINTER(...), to allow them
# to be used in type annotations.
Expand Down
17 changes: 9 additions & 8 deletions stubs/pyserial/serial/tools/list_ports_windows.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ctypes
import sys
from _typeshed import Incomplete
from collections.abc import Generator
from ctypes.wintypes import DWORD

Expand All @@ -24,16 +25,16 @@ if sys.platform == "win32":
REGSAM = ACCESS_MASK

class GUID(ctypes.Structure):
Data1: ctypes._CField
Data2: ctypes._CField
Data3: ctypes._CField
Data4: ctypes._CField
Data1: ctypes._CField[Incomplete, Incomplete, Incomplete]
Data2: ctypes._CField[Incomplete, Incomplete, Incomplete]
Data3: ctypes._CField[Incomplete, Incomplete, Incomplete]
Data4: ctypes._CField[Incomplete, Incomplete, Incomplete]

class SP_DEVINFO_DATA(ctypes.Structure):
cbSize: ctypes._CField
ClassGuid: ctypes._CField
DevInst: ctypes._CField
Reserved: ctypes._CField
cbSize: ctypes._CField[Incomplete, Incomplete, Incomplete]
ClassGuid: ctypes._CField[Incomplete, Incomplete, Incomplete]
DevInst: ctypes._CField[Incomplete, Incomplete, Incomplete]
Reserved: ctypes._CField[Incomplete, Incomplete, Incomplete]
PSP_DEVINFO_DATA: type[ctypes._Pointer[SP_DEVINFO_DATA]]
PSP_DEVICE_INTERFACE_DETAIL_DATA = ctypes.c_void_p
setupapi: ctypes.WinDLL
Expand Down
115 changes: 58 additions & 57 deletions stubs/pyserial/serial/win32.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sys
from _typeshed import Incomplete
from ctypes import Structure, Union, _CField, _NamedFuncPointer, _Pointer, c_int64, c_ulong, c_void_p
from ctypes.wintypes import DWORD
from typing_extensions import TypeAlias
Expand All @@ -9,9 +10,9 @@ if sys.platform == "win32":
ULONG_PTR: type[c_int64 | c_ulong]

class _SECURITY_ATTRIBUTES(Structure):
nLength: _CField
lpSecurityDescriptor: _CField
bInheritHandle: _CField
nLength: _CField[Incomplete, Incomplete, Incomplete]
lpSecurityDescriptor: _CField[Incomplete, Incomplete, Incomplete]
bInheritHandle: _CField[Incomplete, Incomplete, Incomplete]
LPSECURITY_ATTRIBUTES: type[_Pointer[_SECURITY_ATTRIBUTES]]
CreateEvent: _NamedFuncPointer
CreateFile: _NamedFuncPointer
Expand All @@ -21,64 +22,64 @@ if sys.platform == "win32":
CreateFileW: _NamedFuncPointer

class _OVERLAPPED(Structure):
Internal: _CField
InternalHigh: _CField
Offset: _CField
OffsetHigh: _CField
Pointer: _CField
hEvent: _CField
Internal: _CField[Incomplete, Incomplete, Incomplete]
InternalHigh: _CField[Incomplete, Incomplete, Incomplete]
Offset: _CField[Incomplete, Incomplete, Incomplete]
OffsetHigh: _CField[Incomplete, Incomplete, Incomplete]
Pointer: _CField[Incomplete, Incomplete, Incomplete]
hEvent: _CField[Incomplete, Incomplete, Incomplete]
OVERLAPPED: TypeAlias = _OVERLAPPED

class _COMSTAT(Structure):
fCtsHold: _CField
fDsrHold: _CField
fRlsdHold: _CField
fXoffHold: _CField
fXoffSent: _CField
fEof: _CField
fTxim: _CField
fReserved: _CField
cbInQue: _CField
cbOutQue: _CField
fCtsHold: _CField[Incomplete, Incomplete, Incomplete]
fDsrHold: _CField[Incomplete, Incomplete, Incomplete]
fRlsdHold: _CField[Incomplete, Incomplete, Incomplete]
fXoffHold: _CField[Incomplete, Incomplete, Incomplete]
fXoffSent: _CField[Incomplete, Incomplete, Incomplete]
fEof: _CField[Incomplete, Incomplete, Incomplete]
fTxim: _CField[Incomplete, Incomplete, Incomplete]
fReserved: _CField[Incomplete, Incomplete, Incomplete]
cbInQue: _CField[Incomplete, Incomplete, Incomplete]
cbOutQue: _CField[Incomplete, Incomplete, Incomplete]
COMSTAT: TypeAlias = _COMSTAT

class _DCB(Structure):
DCBlength: _CField
BaudRate: _CField
fBinary: _CField
fParity: _CField
fOutxCtsFlow: _CField
fOutxDsrFlow: _CField
fDtrControl: _CField
fDsrSensitivity: _CField
fTXContinueOnXoff: _CField
fOutX: _CField
fInX: _CField
fErrorChar: _CField
fNull: _CField
fRtsControl: _CField
fAbortOnError: _CField
fDummy2: _CField
wReserved: _CField
XonLim: _CField
XoffLim: _CField
ByteSize: _CField
Parity: _CField
StopBits: _CField
XonChar: _CField
XoffChar: _CField
ErrorChar: _CField
EofChar: _CField
EvtChar: _CField
wReserved1: _CField
DCBlength: _CField[Incomplete, Incomplete, Incomplete]
BaudRate: _CField[Incomplete, Incomplete, Incomplete]
fBinary: _CField[Incomplete, Incomplete, Incomplete]
fParity: _CField[Incomplete, Incomplete, Incomplete]
fOutxCtsFlow: _CField[Incomplete, Incomplete, Incomplete]
fOutxDsrFlow: _CField[Incomplete, Incomplete, Incomplete]
fDtrControl: _CField[Incomplete, Incomplete, Incomplete]
fDsrSensitivity: _CField[Incomplete, Incomplete, Incomplete]
fTXContinueOnXoff: _CField[Incomplete, Incomplete, Incomplete]
fOutX: _CField[Incomplete, Incomplete, Incomplete]
fInX: _CField[Incomplete, Incomplete, Incomplete]
fErrorChar: _CField[Incomplete, Incomplete, Incomplete]
fNull: _CField[Incomplete, Incomplete, Incomplete]
fRtsControl: _CField[Incomplete, Incomplete, Incomplete]
fAbortOnError: _CField[Incomplete, Incomplete, Incomplete]
fDummy2: _CField[Incomplete, Incomplete, Incomplete]
wReserved: _CField[Incomplete, Incomplete, Incomplete]
XonLim: _CField[Incomplete, Incomplete, Incomplete]
XoffLim: _CField[Incomplete, Incomplete, Incomplete]
ByteSize: _CField[Incomplete, Incomplete, Incomplete]
Parity: _CField[Incomplete, Incomplete, Incomplete]
StopBits: _CField[Incomplete, Incomplete, Incomplete]
XonChar: _CField[Incomplete, Incomplete, Incomplete]
XoffChar: _CField[Incomplete, Incomplete, Incomplete]
ErrorChar: _CField[Incomplete, Incomplete, Incomplete]
EofChar: _CField[Incomplete, Incomplete, Incomplete]
EvtChar: _CField[Incomplete, Incomplete, Incomplete]
wReserved1: _CField[Incomplete, Incomplete, Incomplete]
DCB: TypeAlias = _DCB

class _COMMTIMEOUTS(Structure):
ReadIntervalTimeout: _CField
ReadTotalTimeoutMultiplier: _CField
ReadTotalTimeoutConstant: _CField
WriteTotalTimeoutMultiplier: _CField
WriteTotalTimeoutConstant: _CField
ReadIntervalTimeout: _CField[Incomplete, Incomplete, Incomplete]
ReadTotalTimeoutMultiplier: _CField[Incomplete, Incomplete, Incomplete]
ReadTotalTimeoutConstant: _CField[Incomplete, Incomplete, Incomplete]
WriteTotalTimeoutMultiplier: _CField[Incomplete, Incomplete, Incomplete]
WriteTotalTimeoutConstant: _CField[Incomplete, Incomplete, Incomplete]
COMMTIMEOUTS: TypeAlias = _COMMTIMEOUTS

GetLastError: _NamedFuncPointer
Expand Down Expand Up @@ -151,11 +152,11 @@ if sys.platform == "win32":
PURGE_RXCLEAR: int

class N11_OVERLAPPED4DOLLAR_48E(Union):
Offset: _CField
OffsetHigh: _CField
Pointer: _CField
Offset: _CField[Incomplete, Incomplete, Incomplete]
OffsetHigh: _CField[Incomplete, Incomplete, Incomplete]
Pointer: _CField[Incomplete, Incomplete, Incomplete]

class N11_OVERLAPPED4DOLLAR_484DOLLAR_49E(Structure):
Offset: _CField
OffsetHigh: _CField
Offset: _CField[Incomplete, Incomplete, Incomplete]
OffsetHigh: _CField[Incomplete, Incomplete, Incomplete]
PVOID: TypeAlias = c_void_p