Skip to content

Commit b724031

Browse files
committed
After some footling, decided on leaving disallow_any_decorated OFF
1 parent 81f937d commit b724031

9 files changed

Lines changed: 95 additions & 60 deletions

File tree

kazoo/client.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,12 @@ def __init__(
424424

425425
# also this should be called with a func that returns nothing as the
426426
# 1st argument.
427-
def _retry(*args: Any, **kwargs: Any) -> Any:
428-
return self._retry.copy()(*args, **kwargs)
427+
def _retry(
428+
func: Callable[..., KazooRetry.RETRY_RETURN],
429+
*args: Any,
430+
**kwargs: Any,
431+
) -> KazooRetry.RETRY_RETURN:
432+
return self._retry.copy()(func, *args, **kwargs)
429433

430434
# (expression has type "Callable[[VarArg(Any), KwArg(Any)], Any]",
431435
# variable has type "KazooRetry") so basically self.retry needs to be
@@ -500,7 +504,7 @@ def client_state(self) -> KeeperState:
500504
return self._state
501505

502506
@property
503-
def client_id(self) -> tuple[Any, Any] | None:
507+
def client_id(self) -> tuple[int | None, bytes] | None:
504508
"""Returns the client id for this Zookeeper session if
505509
connected.
506510

kazoo/handlers/eventlet.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from kazoo.handlers.utils import selector_select
2121

2222
if TYPE_CHECKING:
23-
from kazoo.interfaces import Event, Lockable, ReentrantLock, Socket
23+
from kazoo.interfaces import Event, FdLike, Lockable, ReentrantLock, Socket
2424
from kazoo.protocol.states import Callback
2525

2626

@@ -201,7 +201,7 @@ def create_connection(self, *args: Any, **kwargs: Any) -> Socket:
201201

202202
def select(
203203
self, *args: Any, **kwargs: Any
204-
) -> tuple[list[int], list[int], list[int]]:
204+
) -> tuple[list[FdLike], list[FdLike], list[FdLike]]:
205205
with _yield_before_after():
206206
# Following appears to be a bug in mypy (see
207207
# https://github.com/python/mypy/issues/6799)

kazoo/handlers/gevent.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from kazoo.handlers import utils
2525

2626
if TYPE_CHECKING:
27-
from kazoo.interfaces import HasFileNo, Lockable, Socket
27+
from kazoo.interfaces import FdLike, Lockable, Socket
2828
from kazoo.protocol.states import Callback
2929

3030
_using_libevent = gevent.__version__.startswith("0.")
@@ -146,11 +146,7 @@ def stop(self) -> None:
146146

147147
def select(
148148
self, *args: Any, **kwargs: Any
149-
) -> tuple[
150-
Iterable[int | HasFileNo],
151-
Iterable[int | HasFileNo],
152-
Iterable[int | HasFileNo],
153-
]:
149+
) -> tuple[Iterable[FdLike], Iterable[FdLike], Iterable[FdLike]]:
154150
# FIXME use the correct arguments, not *args, *kwargs
155151
return selector_select(
156152
# Likely a bug in mypy (see

kazoo/handlers/threading.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
if TYPE_CHECKING:
3131
from kazoo.interfaces import (
3232
Event,
33-
HasFileNo,
33+
FdLike,
3434
Lockable,
3535
ReentrantLock,
3636
Socket,
@@ -187,11 +187,7 @@ def stop(self) -> None:
187187

188188
def select(
189189
self, *args: Any, **kwargs: Any
190-
) -> tuple[
191-
Iterable[int | HasFileNo],
192-
Iterable[int | HasFileNo],
193-
Iterable[int | HasFileNo],
194-
]:
190+
) -> tuple[Iterable[FdLike], Iterable[FdLike], Iterable[FdLike]]:
195191
return selector_select(*args, **kwargs)
196192

197193
def socket(self) -> Socket:

kazoo/handlers/utils.py

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111
import socket
1212
import time
1313
from 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

1819
if 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+
326330
def 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

349360
def 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

397417
def 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:

kazoo/interfaces.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
Callable,
1919
Iterable,
2020
Protocol,
21+
Union,
2122
TYPE_CHECKING,
2223
)
2324

@@ -28,12 +29,15 @@
2829

2930

3031
class HasFileNo(Protocol):
31-
"""Protocol for things like select"""
32+
"""Protocol for objects that support a fileno method."""
3233

3334
def fileno(self) -> int:
3435
...
3536

3637

38+
FdLike = Union[int, HasFileNo]
39+
40+
3741
class Socket(HasFileNo, Protocol):
3842
"""This is for things that provide a socket.socket-like interface.
3943
@@ -176,15 +180,11 @@ def stop(self) -> None:
176180
@abc.abstractmethod
177181
def select(
178182
self,
179-
rlist: Iterable[int | HasFileNo],
180-
wlist: Iterable[int | HasFileNo],
181-
xlist: Iterable[int | HasFileNo],
183+
rlist: Iterable[FdLike],
184+
wlist: Iterable[FdLike],
185+
xlist: Iterable[FdLike],
182186
timeout: float | None = None,
183-
) -> tuple[
184-
Iterable[int | HasFileNo],
185-
Iterable[int | HasFileNo],
186-
Iterable[int | HasFileNo],
187-
]:
187+
) -> tuple[Iterable[FdLike], Iterable[FdLike], Iterable[FdLike]]:
188188
"""A select method that implements Python's select.select
189189
API"""
190190

kazoo/protocol/connection.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import socket
1212
import ssl
1313
import time
14-
from typing import Any, Iterator, Literal, TYPE_CHECKING, cast
14+
from typing import Any, Iterator, Literal, TypeVar, TYPE_CHECKING, cast
1515

1616
from kazoo.exceptions import (
1717
AuthFailedError,
@@ -163,6 +163,9 @@ class RWServerAvailable(Exception):
163163
"""Thrown if a RW Server becomes available"""
164164

165165

166+
ReturnValue = TypeVar("ReturnValue")
167+
168+
166169
class ConnectionHandler(object):
167170
"""Zookeeper connection handler"""
168171

@@ -203,7 +206,7 @@ def __init__(
203206
# This is instance specific to avoid odd thread bug issues in Python
204207
# during shutdown global cleanup
205208
@contextmanager
206-
def _socket_error_handling(self) -> Any:
209+
def _socket_error_handling(self) -> Iterator[None]:
207210
try:
208211
yield
209212
except (socket.error, select.error) as e:

0 commit comments

Comments
 (0)