1111import socket
1212import time
1313from types import ModuleType
14- from typing import Any , Callable , TYPE_CHECKING
14+ from typing import Any , Callable , Iterable , TypeVar , TYPE_CHECKING
1515
16- from kazoo .interfaces import IAsyncResult
16+
17+ from kazoo .interfaces import IAsyncResult , FdLike
1718
1819if TYPE_CHECKING :
1920 from kazoo .interfaces import Socket
@@ -323,23 +324,33 @@ def create_tcp_connection(
323324 return sock
324325
325326
327+ CapturedResult = TypeVar ("CapturedResult" )
328+
329+
326330def capture_exceptions (
327331 async_result : IAsyncResult ,
328- ) -> Callable [[Callable [..., Any ]], Callable [..., Any ]]:
332+ ) -> Callable [
333+ [Callable [..., CapturedResult ]], Callable [..., CapturedResult | None ]
334+ ]:
329335 """Return a new decorated function that propagates the exceptions of the
330336 wrapped function to an async_result.
331337
332338 :param async_result: An async result implementing :class:`IAsyncResult`
333339
334340 """
335341
336- def capture (function : Callable [..., Any ]) -> Callable [..., Any ]:
342+ def capture (
343+ function : Callable [..., CapturedResult ]
344+ ) -> Callable [..., CapturedResult | None ]:
337345 @functools .wraps (function )
338- def captured_function (* args : Any , ** kwargs : Any ) -> Any :
346+ def captured_function (
347+ * args : Any , ** kwargs : Any
348+ ) -> CapturedResult | None :
339349 try :
340350 return function (* args , ** kwargs )
341351 except Exception as exc :
342352 async_result .set_exception (exc )
353+ return None
343354
344355 return captured_function
345356
@@ -348,7 +359,9 @@ def captured_function(*args: Any, **kwargs: Any) -> Any:
348359
349360def wrap (
350361 async_result : IAsyncResult ,
351- ) -> Callable [[Callable [..., Any ]], Callable [..., Any ]]:
362+ ) -> Callable [
363+ [Callable [..., CapturedResult ]], Callable [..., CapturedResult | None ]
364+ ]:
352365 """Return a new decorated function that propagates the return value or
353366 exception of wrapped function to an async_result. NOTE: Only propagates a
354367 non-None return value.
@@ -357,9 +370,13 @@ def wrap(
357370
358371 """
359372
360- def capture (function : Callable [..., Any ]) -> Callable [..., Any ]:
373+ def capture (
374+ function : Callable [..., CapturedResult ]
375+ ) -> Callable [..., CapturedResult | None ]:
361376 @capture_exceptions (async_result )
362- def captured_function (* args : Any , ** kwargs : Any ) -> Any :
377+ def captured_function (
378+ * args : Any , ** kwargs : Any
379+ ) -> CapturedResult | None :
363380 value = function (* args , ** kwargs )
364381 if value is not None :
365382 async_result .set (value )
@@ -370,7 +387,7 @@ def captured_function(*args: Any, **kwargs: Any) -> Any:
370387 return capture
371388
372389
373- def fileobj_to_fd (fileobj : Any ) -> int :
390+ def fileobj_to_fd (fileobj : FdLike ) -> int :
374391 """Return a file descriptor from a file object.
375392
376393 Parameters:
@@ -385,22 +402,25 @@ def fileobj_to_fd(fileobj: Any) -> int:
385402 if isinstance (fileobj , int ):
386403 fd = fileobj
387404 else :
405+ # FIXME given the protocol I don't think the try/catch/int are
406+ # required.
388407 try :
389408 fd = int (fileobj .fileno ())
390409 except (AttributeError , TypeError , ValueError ):
391410 raise TypeError ("Invalid file object: " "{!r}" .format (fileobj ))
411+ # FIXME Questionable, just let select deal with it.
392412 if fd < 0 :
393413 raise TypeError ("Invalid file descriptor: {}" .format (fd ))
394414 return fd
395415
396416
397417def selector_select (
398- rlist : list [ Any ],
399- wlist : list [ Any ],
400- xlist : list [ Any ],
418+ rlist : Iterable [ FdLike ],
419+ wlist : Iterable [ FdLike ],
420+ xlist : Iterable [ FdLike ],
401421 timeout : float | None = None ,
402422 selectors_module : ModuleType = selectors ,
403- ) -> tuple [list [int ], list [int ], list [int ]]:
423+ ) -> tuple [list [FdLike ], list [FdLike ], list [FdLike ]]:
404424 """Selector-based drop-in replacement for select to overcome select
405425 limitation on a maximum filehandle value.
406426 """
@@ -415,7 +435,7 @@ def selector_select(
415435 selectors_module .EVENT_WRITE : wlist ,
416436 }
417437 fd_events : defaultdict [int , int ] = defaultdict (int )
418- fd_fileobjs : defaultdict [int , list [int ]] = defaultdict (list )
438+ fd_fileobjs : defaultdict [int , list [FdLike ]] = defaultdict (list )
419439
420440 for event , fileobjs in events_mapping .items ():
421441 for fileobj in fileobjs :
@@ -431,9 +451,9 @@ def selector_select(
431451 # gevent can raise OSError
432452 raise ValueError ("Invalid event mask or fd" ) from e
433453
434- revents : list [int ] = []
435- wevents : list [int ] = []
436- xevents : list [int ] = []
454+ revents : list [FdLike ] = []
455+ wevents : list [FdLike ] = []
456+ xevents : list [FdLike ] = []
437457 try :
438458 ready = selector .select (timeout )
439459 finally :
0 commit comments