-
Notifications
You must be signed in to change notification settings - Fork 14
Windows compatibility fix #408
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -22,6 +22,11 @@ | |||||
| TYPE_CHECKING, | ||||||
| ) | ||||||
|
|
||||||
| import logging | ||||||
| import platform | ||||||
| import socket | ||||||
|
|
||||||
|
|
||||||
| from bidict import bidict | ||||||
| from trio import ( | ||||||
| SocketListener, | ||||||
|
|
@@ -32,14 +37,31 @@ | |||||
| _def_tpt_proto, | ||||||
| ) | ||||||
| from .ipc._tcp import TCPAddress | ||||||
| from .ipc._uds import UDSAddress | ||||||
|
|
||||||
|
|
||||||
| if TYPE_CHECKING: | ||||||
| from ._runtime import Actor | ||||||
|
|
||||||
| log = get_logger(__name__) | ||||||
|
|
||||||
|
|
||||||
| HAS_AF_UNIX = getattr(socket, "AF_UNIX", None) is not None | ||||||
| IS_WINDOWS = platform.system() == "Windows" | ||||||
|
|
||||||
| UDSAddress = None # so references exist but do nothing on Windows | ||||||
|
|
||||||
| if HAS_AF_UNIX and not IS_WINDOWS: | ||||||
| try: | ||||||
| from .ipc._uds import UDSAddress as _UDSAddress | ||||||
| UDSAddress = _UDSAddress | ||||||
| except Exception as e: | ||||||
| log.warning("UDS backend import failed: %s", e) | ||||||
| else: | ||||||
| log.warning("UDS backend disabled on this platform.") | ||||||
|
|
||||||
| if TYPE_CHECKING: | ||||||
| from ._runtime import Actor | ||||||
|
|
||||||
|
Comment on lines
+62
to
+64
|
||||||
| if TYPE_CHECKING: | |
| from ._runtime import Actor |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -31,12 +31,22 @@ | |||||
| RLock, | ||||||
| ) | ||||||
| import multiprocessing as mp | ||||||
| from signal import ( | ||||||
|
|
||||||
| import platform | ||||||
| import signal | ||||||
|
||||||
| import signal |
Copilot
AI
Jan 25, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace detected at the end of line 38. This should be removed for code cleanliness.
| from signal import ( | |
| from signal import ( |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,8 @@ | |
| from itertools import chain | ||
| import inspect | ||
| import textwrap | ||
| import platform | ||
| import socket | ||
| from types import ( | ||
| ModuleType, | ||
| ) | ||
|
|
@@ -64,16 +66,23 @@ | |
| from .._addr import Address | ||
| from ._chan import Channel | ||
| from ._transport import MsgTransport | ||
| from ._uds import UDSAddress | ||
| from ._tcp import TCPAddress | ||
|
|
||
|
|
||
| if TYPE_CHECKING: | ||
| from .._runtime import Actor | ||
| from .._supervise import ActorNursery | ||
|
|
||
|
|
||
| from ._tcp import TCPAddress | ||
|
|
||
| log = log.get_logger(__name__) | ||
|
|
||
| UDSAddress = None | ||
|
|
||
| if getattr(socket, "AF_UNIX", None) is not None and platform.system() != "Windows": | ||
|
||
| from ._uds import UDSAddress | ||
| else: | ||
| pass | ||
|
|
||
| async def maybe_wait_on_canced_subs( | ||
| uid: tuple[str, str], | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -18,106 +18,132 @@ | |||||
| IPC subsys type-lookup helpers? | ||||||
|
|
||||||
| ''' | ||||||
| from typing import ( | ||||||
| Type, | ||||||
| # TYPE_CHECKING, | ||||||
| ) | ||||||
|
|
||||||
| import trio | ||||||
| from typing import Type | ||||||
| import logging | ||||||
| import platform | ||||||
| import socket | ||||||
| import trio | ||||||
|
|
||||||
| from tractor.ipc._transport import ( | ||||||
| MsgTransportKey, | ||||||
| MsgTransport | ||||||
| MsgTransport, | ||||||
| ) | ||||||
| from tractor.ipc._tcp import ( | ||||||
| TCPAddress, | ||||||
| MsgpackTCPStream, | ||||||
| ) | ||||||
| from tractor.ipc._uds import ( | ||||||
| UDSAddress, | ||||||
| MsgpackUDSStream, | ||||||
| ) | ||||||
|
|
||||||
| # if TYPE_CHECKING: | ||||||
| # from tractor._addr import Address | ||||||
| log = logging.getLogger(__name__) | ||||||
|
|
||||||
| # ------------------------------------------------------------ | ||||||
| # Optional UDS backend (Windows / some Pythons may not have AF_UNIX) | ||||||
| # ------------------------------------------------------------ | ||||||
| HAS_AF_UNIX = getattr(socket, "AF_UNIX", None) is not None | ||||||
| IS_WINDOWS = platform.system() == "Windows" | ||||||
|
|
||||||
| Address = TCPAddress|UDSAddress | ||||||
| HAS_UDS = False | ||||||
| UDSAddress = None # type: ignore | ||||||
| MsgpackUDSStream = None # type: ignore | ||||||
|
|
||||||
| # manually updated list of all supported msg transport types | ||||||
| _msg_transports = [ | ||||||
| if HAS_AF_UNIX and not IS_WINDOWS: | ||||||
| try: | ||||||
| from tractor.ipc._uds import ( # type: ignore | ||||||
| UDSAddress as _UDSAddress, | ||||||
| MsgpackUDSStream as _MsgpackUDSStream, | ||||||
| ) | ||||||
| UDSAddress = _UDSAddress # type: ignore | ||||||
| MsgpackUDSStream = _MsgpackUDSStream # type: ignore | ||||||
| HAS_UDS = True | ||||||
| except Exception as e: | ||||||
| log.warning("UDS backend unavailable (%s); continuing without it.", e) | ||||||
| else: | ||||||
| if not HAS_AF_UNIX: | ||||||
| log.warning("AF_UNIX not exposed by this Python; disabling UDS backend.") | ||||||
| elif IS_WINDOWS: | ||||||
| # Even if the Windows kernel supports AF_UNIX, CPython may not expose it, | ||||||
| # and this project currently targets POSIX for the UDS backend. | ||||||
| log.warning("Windows detected; disabling UDS backend.") | ||||||
|
|
||||||
| # ------------------------------------------------------------ | ||||||
| # Public types and transport registries | ||||||
| # ------------------------------------------------------------ | ||||||
|
|
||||||
| # Address is TCP-only unless UDS is available. | ||||||
| if HAS_UDS: | ||||||
| Address = TCPAddress | UDSAddress # type: ignore | ||||||
| else: | ||||||
| Address = TCPAddress # type: ignore | ||||||
|
|
||||||
| # Manually updated list of all supported msg transport types | ||||||
| _msg_transports: list[Type[MsgTransport]] = [ | ||||||
| MsgpackTCPStream, | ||||||
| MsgpackUDSStream | ||||||
| ] | ||||||
| if HAS_UDS: | ||||||
| _msg_transports.append(MsgpackUDSStream) # type: ignore | ||||||
|
|
||||||
|
|
||||||
| # convert a MsgTransportKey to the corresponding transport type | ||||||
| _key_to_transport: dict[ | ||||||
| MsgTransportKey, | ||||||
| Type[MsgTransport], | ||||||
| ] = { | ||||||
| ('msgpack', 'tcp'): MsgpackTCPStream, | ||||||
| ('msgpack', 'uds'): MsgpackUDSStream, | ||||||
| # Map MsgTransportKey -> transport type | ||||||
| _key_to_transport: dict[MsgTransportKey, Type[MsgTransport]] = { | ||||||
| ("msgpack", "tcp"): MsgpackTCPStream, | ||||||
| } | ||||||
| if HAS_UDS: | ||||||
| _key_to_transport[("msgpack", "uds")] = MsgpackUDSStream # type: ignore | ||||||
|
|
||||||
| # convert an Address wrapper to its corresponding transport type | ||||||
| _addr_to_transport: dict[ | ||||||
| Type[TCPAddress|UDSAddress], | ||||||
| Type[MsgTransport] | ||||||
| ] = { | ||||||
| # Map Address wrapper -> transport type | ||||||
| _addr_to_transport: dict[Type[Address], Type[MsgTransport]] = { # type: ignore | ||||||
| TCPAddress: MsgpackTCPStream, | ||||||
| UDSAddress: MsgpackUDSStream, | ||||||
| } | ||||||
| if HAS_UDS: | ||||||
| _addr_to_transport[UDSAddress] = MsgpackUDSStream # type: ignore | ||||||
|
|
||||||
|
|
||||||
| # ------------------------------------------------------------ | ||||||
| # Helpers | ||||||
| # ------------------------------------------------------------ | ||||||
| def transport_from_addr( | ||||||
| addr: Address, | ||||||
| codec_key: str = 'msgpack', | ||||||
| codec_key: str = "msgpack", | ||||||
| ) -> Type[MsgTransport]: | ||||||
| ''' | ||||||
| """ | ||||||
| Given a destination address and a desired codec, find the | ||||||
| corresponding `MsgTransport` type. | ||||||
|
|
||||||
| ''' | ||||||
| """ | ||||||
| try: | ||||||
| return _addr_to_transport[type(addr)] | ||||||
|
|
||||||
| return _addr_to_transport[type(addr)] # type: ignore[call-arg] | ||||||
| except KeyError: | ||||||
| raise NotImplementedError( | ||||||
| f'No known transport for address {repr(addr)}' | ||||||
| f"No known transport for address {repr(addr)}" | ||||||
| ) | ||||||
|
|
||||||
|
|
||||||
| def transport_from_stream( | ||||||
| stream: trio.abc.Stream, | ||||||
| codec_key: str = 'msgpack' | ||||||
| codec_key: str = "msgpack", | ||||||
| ) -> Type[MsgTransport]: | ||||||
| ''' | ||||||
| """ | ||||||
| Given an arbitrary `trio.abc.Stream` and a desired codec, | ||||||
| find the corresponding `MsgTransport` type. | ||||||
|
|
||||||
| ''' | ||||||
| """ | ||||||
| transport = None | ||||||
|
|
||||||
| if isinstance(stream, trio.SocketStream): | ||||||
| sock: socket.socket = stream.socket | ||||||
| match sock.family: | ||||||
| case socket.AF_INET | socket.AF_INET6: | ||||||
| transport = 'tcp' | ||||||
| fam = sock.family | ||||||
|
|
||||||
| if fam in (socket.AF_INET, getattr(socket, "AF_INET6", None)): | ||||||
| transport = "tcp" | ||||||
|
|
||||||
| case socket.AF_UNIX: | ||||||
| transport = 'uds' | ||||||
| # Only consider AF_UNIX when both Python exposes it and our backend is active | ||||||
| if transport is None and HAS_UDS and HAS_AF_UNIX and fam == socket.AF_UNIX: # type: ignore[attr-defined] | ||||||
|
||||||
| if transport is None and HAS_UDS and HAS_AF_UNIX and fam == socket.AF_UNIX: # type: ignore[attr-defined] | |
| if transport is None and HAS_UDS and fam == socket.AF_UNIX: # type: ignore[attr-defined] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import of 'logging' is not used.