7
7
from contextlib import contextmanager
8
8
from typing import (
9
9
TYPE_CHECKING ,
10
- Any ,
11
10
Literal ,
11
+ Protocol ,
12
12
TypeVar ,
13
13
cast ,
14
14
)
24
24
AFDPollFlags ,
25
25
CData ,
26
26
CompletionModes ,
27
+ CType ,
27
28
ErrorCodes ,
28
29
FileFlags ,
29
30
Handle ,
@@ -249,13 +250,28 @@ class AFDWaiters:
249
250
current_op : AFDPollOp | None = None
250
251
251
252
253
+ # Just used for internal type checking.
254
+ class _AFDHandle (Protocol ):
255
+ Handle : Handle
256
+ Status : int
257
+ Events : int
258
+
259
+
260
+ # Just used for internal type checking.
261
+ class _AFDPollInfo (Protocol ):
262
+ Timeout : int
263
+ NumberOfHandles : int
264
+ Exclusive : int
265
+ Handles : list [_AFDHandle ]
266
+
267
+
252
268
# We also need to bundle up all the info for a single op into a standalone
253
269
# object, because we need to keep all these objects alive until the operation
254
270
# finishes, even if we're throwing it away.
255
271
@attrs .frozen (eq = False )
256
272
class AFDPollOp :
257
273
lpOverlapped : CData
258
- poll_info : Any
274
+ poll_info : _AFDPollInfo
259
275
waiters : AFDWaiters
260
276
afd_group : AFDGroup
261
277
@@ -684,7 +700,7 @@ def _refresh_afd(self, base_handle: Handle) -> None:
684
700
685
701
lpOverlapped = ffi .new ("LPOVERLAPPED" )
686
702
687
- poll_info : Any = ffi .new ("AFD_POLL_INFO *" )
703
+ poll_info = cast ( _AFDPollInfo , ffi .new ("AFD_POLL_INFO *" ) )
688
704
poll_info .Timeout = 2 ** 63 - 1 # INT64_MAX
689
705
poll_info .NumberOfHandles = 1
690
706
poll_info .Exclusive = 0
@@ -697,9 +713,9 @@ def _refresh_afd(self, base_handle: Handle) -> None:
697
713
kernel32 .DeviceIoControl (
698
714
afd_group .handle ,
699
715
IoControlCodes .IOCTL_AFD_POLL ,
700
- poll_info ,
716
+ cast ( CType , poll_info ) ,
701
717
ffi .sizeof ("AFD_POLL_INFO" ),
702
- poll_info ,
718
+ cast ( CType , poll_info ) ,
703
719
ffi .sizeof ("AFD_POLL_INFO" ),
704
720
ffi .NULL ,
705
721
lpOverlapped ,
0 commit comments