from collections.abc import Callable, Iterable
from types import TracebackType
from typing import Any

from typing_extensions import Self

__all__ = ["Client", "Listener", "Pipe", "wait"]

from socket import socket

class _SocketContainer:
    def __init__(self, sock: socket) -> None: ...

class _ConnectionBase:
    def __init__(
        self, handle: int, readable: bool = ..., writable: bool = ...
    ) -> None: ...
    def __del__(self) -> None: ...
    def close(self) -> None: ...
    def send(self, obj: Any) -> None: ...
    def recv(self) -> Any: ...
    def poll(self, timeout: float = ...) -> bool: ...
    def send_bytes(
        self, buf: bytes, offset: int = ..., size: int | None = ...
    ) -> None: ...
    def recv_bytes(self, maxlength: int | None = ...) -> bytes: ...
    def recv_bytes_into(self, buf: bytearray, offset: int = ...) -> int: ...
    def send_offset(self, buf: bytes, offset: int) -> None: ...
    def setblocking(self, blocking: bool) -> None: ...
    @property
    def closed(self) -> bool: ...
    @property
    def readable(self) -> bool: ...
    @property
    def writable(self) -> bool: ...
    def fileno(self) -> int: ...
    def __enter__(self) -> Self: ...
    def __exit__(
        self,
        exc_type: type[BaseException] | None,
        exc_value: BaseException | None,
        exc_tb: TracebackType | None,
    ) -> None: ...

class Connection(_ConnectionBase): ...

class Listener:
    def __init__(
        self,
        address: str | tuple[str, int] | None = ...,
        family: str | None = ...,
        backlog: int = ...,
        authkey: bytes | None = ...,
    ) -> None: ...
    def accept(self) -> Connection: ...
    def close(self) -> None: ...
    @property
    def address(self) -> str | tuple[str, int]: ...
    @property
    def last_accepted(self) -> str | tuple[str, int] | None: ...
    def __enter__(self) -> Self: ...
    def __exit__(
        self,
        exc_type: type[BaseException] | None,
        exc_value: BaseException | None,
        exc_tb: TracebackType | None,
    ) -> None: ...

class SocketListener:
    def __init__(
        self,
        address: str | tuple[str, int],
        family: str,
        backlog: int = ...,
    ) -> None: ...
    def accept(self) -> Connection: ...
    def close(self) -> None: ...

class ConnectionWrapper:
    def __init__(
        self,
        conn: Connection,
        dumps: Callable[..., bytes],
        loads: Callable[..., Any],
    ) -> None: ...
    def send(self, obj: Any) -> None: ...
    def recv(self) -> Any: ...

class XmlListener(Listener): ...

def Client(
    address: str | tuple[str, int],
    family: str | None = ...,
    authkey: bytes | None = ...,
) -> Connection: ...
def Pipe(
    duplex: bool = ..., rnonblock: bool = ..., wnonblock: bool = ...
) -> tuple[Connection, Connection]: ...
def wait(object_list: Iterable[Any], timeout: float | None = ...) -> list[Any]: ...
