From f0d3a48f80637af86cc1cec685c2db4edc8f5a78 Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Sun, 28 Jun 2026 20:24:09 +0200 Subject: [PATCH 01/28] Implement Named Pipe and Websocket support --- pyproject.toml | 2 + src/splitguides/livesplit_client.py | 189 ++++++++++++++---- src/splitguides/server/split_server.py | 2 +- src/splitguides/settings.py | 1 + src/splitguides/ui/layouts/server_settings.ui | 113 +++++++---- src/splitguides/ui/layouts/settings.ui | 138 +++++++++---- src/splitguides/ui/main_window.py | 5 +- src/splitguides/ui/server_settings_ui.py | 2 + src/splitguides/ui/settings_ui.py | 2 + uv.lock | 13 ++ 10 files changed, 342 insertions(+), 125 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8de0e4d..100a5e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,8 @@ dependencies = [ "ducktools-classbuilder>=0.7.4", "waitress~=3.0", "platformdirs~=4.3", + "websocket-client>=1.9.0", + "pywin32>=311", ] classifiers = [ "Development Status :: 4 - Beta", diff --git a/src/splitguides/livesplit_client.py b/src/splitguides/livesplit_client.py index aa3a82c..42249f2 100644 --- a/src/splitguides/livesplit_client.py +++ b/src/splitguides/livesplit_client.py @@ -1,5 +1,8 @@ import re import socket +import time +import websocket +import win32pipe, win32file, pywintypes from datetime import timedelta import typing @@ -40,36 +43,97 @@ class LivesplitConnection(Prefab): """ Socket based livesplit connection model """ - server: str = "localhost" - port: int = 16834 - timeout: int = 1 - sock: socket.socket | None = attribute(default=None, init=False, repr=False) + server: str = attribute(default="localhost", init=True) + port: int = attribute(default=16834, init=True) + connectionType: int = attribute(default=1, init=True) # 0: named pipe, 1: TCP, 2: websocket + timeout: int = attribute(default=1, init=True) + sockTCP: socket.socket | None = attribute(default=None, init=False, repr=False) + sockWS: websocket.WebSocketApp | None = attribute(default=None, init=False, repr=False) + handlePipe = attribute(default=None, init=False, repr=False) def connect(self) -> bool: """ Attempt to connect to the livesplit server :return: True if connected, otherwise False """ - self.sock = socket.socket() - try: - self.sock.connect((self.server, self.port)) - except ConnectionRefusedError: - self.sock.close() - self.sock = None - return False - except socket.gaierror: - # Could not resolve hostname - self.sock.close() - self.sock = None - return False + self.close() + + if self.connectionType == 1: + self.sockTCP = socket.socket() + try: + self.sockTCP.connect((self.server, self.port)) + self.sockTCP.settimeout(self.timeout) + self.sockTCP.send(b"ping\r\n") + ping_resp = self.sockTCP.recv(BUFFER_SIZE).decode("UTF-8").strip("\r\n") + return (ping_resp == "pong") + except ConnectionRefusedError: + self.sockTCP.close() + self.sockTCP = None + return False + except socket.gaierror: + # Could not resolve hostname + self.sockTCP.close() + self.sockTCP = None + return False + elif self.connectionType == 2: + self.sockWS = websocket.WebSocket() + try: + self.sockWS.connect(f"ws://{self.server}:{self.port}/livesplit", origin="SplitGuides", timeout=10) + except Exception as e: + self.sockWS.close() + self.sockWS = None + return False + else: + return True else: - self.sock.settimeout(self.timeout) - return True + try: + self.handlePipe = win32file.CreateFile( + r'\\.\pipe\livesplit', + win32file.GENERIC_READ | win32file.GENERIC_WRITE, + 0, + None, + win32file.OPEN_EXISTING, + 0, + None + ) + res = win32pipe.SetNamedPipeHandleState(self.handlePipe, win32pipe.PIPE_READMODE_BYTE | win32pipe.PIPE_NOWAIT, None, None) + if res == 0: # errored + self.handlePipe = None + return False + except pywintypes.error as e: + self.handlePipe = None + print('Pipe error: ' + e.args[2]) + return False + else: + return True + + def ensureConnected(self) -> bool: + if self.connectionType == 1: + if not self.sockTCP: + return self.connect() + else: + return True + elif self.connectionType == 2: + if not self.sockWS: + return self.connect() + else: + return True + else: + if not self.handlePipe: + return self.connect() + else: + return True def close(self) -> None: - if self.sock: - self.sock.close() - self.sock = None + if self.sockTCP: + self.sockTCP.close() + self.sockTCP = None + if self.sockWS: + self.sockWS.close() + self.sockWS = None + if self.handlePipe: + win32file.CloseHandle(self.handlePipe) + self.handlePipe = None def send(self, msg: bytes) -> None: """ @@ -77,53 +141,87 @@ def send(self, msg: bytes) -> None: If the connection is aborted (ie: if livesplit server has been closed) raise a ConnectionAbortedError - :param msg: bytes message to send (should end with "\r\n") + :param msg: bytes message to send :return: """ - if not self.sock: - self.connect() + if not self.ensureConnected(): + return - if self.sock: # Check again in case connection failed + if self.connectionType == 1: + try: + self.sockTCP.send(msg + b"\r\n") + except: + self.sockTCP.close() + self.sockTCP = None + raise ConnectionAbortedError("The connection has been closed by the host") + elif self.connectionType == 2: try: - self.sock.send(msg) - except ConnectionAbortedError: - self.sock.close() - self.sock = None + self.sockWS.send(msg) #no CRLF on WS + except Exception as e: + self.sockWS.close() + self.sockWS = None raise ConnectionAbortedError("The connection has been closed by the host") + else: + try: + win32file.WriteFile(self.handlePipe, msg + b"\r\n") + except Exception as e: + print("pipe sending error: " + str(e)) + win32file.CloseHandle(self.handlePipe) + self.handlePipe = None + raise ConnectionAbortedError("Pipe broken") - def receive(self) -> bytes: + def receive(self) -> typing.Union[bytes, str]: """ Attempt to receive a message from the livesplit server raise ConnectionError if the connection has been terminated. - :return: bytes received from the server + :return: bytes or string received from the server """ - if not self.sock: - self.connect() + if not self.ensureConnected(): + return b"" - if self.sock: + data_received = b"" + if self.connectionType == 1: try: - data_received = self.sock.recv(BUFFER_SIZE) + data_received = self.sockTCP.recv(BUFFER_SIZE) except socket.timeout: raise TimeoutError( "No response received from the server within " f"the timeout period ({self.timeout}s)" ) except OSError: - self.sock.close() - self.sock = None + self.sockTCP.close() + self.sockTCP = None raise ConnectionError("The connection has been closed by the host") if data_received == b"": - self.sock.close() - self.sock = None + self.sockTCP.close() + self.sockTCP = None raise ConnectionError("The connection has been closed by the host") return data_received + elif self.connectionType == 2: + try: + data_received : bytes = self.sockWS.recv() + except Exception as e: + self.sockWS.close() + self.sockWS = None + raise ConnectionAbortedError("The connection has been closed by the host") + return data_received + else: + time.sleep(0.05) + try: + data_received = win32file.ReadFile(self.handlePipe, BUFFER_SIZE) + # this is returned as tuple, only pass the data onwards + data_received = data_received[1] + except Exception as e: + win32file.CloseHandle(self.handlePipe) + self.handlePipe = None + raise ConnectionAbortedError("Pipe broken") + return data_received return b"" - class LivesplitMessaging(Prefab): connection: LivesplitConnection @@ -135,7 +233,7 @@ def close(self) -> None: def send(self, message) -> None: m = message.encode("UTF8") - self.connection.send(m + b"\r\n") + self.connection.send(m) @typing.overload def receive(self, datatype: typing.Literal["time"]) -> timedelta: ... @@ -146,7 +244,11 @@ def receive(self, datatype: typing.Literal["text"] = "text") -> str: ... def receive(self, datatype="text"): result = self.connection.receive() - result = result.strip().decode("UTF8") + if isinstance(result, bytes): + result = result.decode("UTF8").strip() + else: #str + result = result.strip() + if datatype == "time": result = parse_time(result) elif datatype == "int": @@ -298,6 +400,7 @@ def get_current_timer_phase(self) -> str: def get_client( server: str = "localhost", port: int = 16834, + connectionType: int = 1, timeout: int = 1 ) -> LivesplitMessaging: - return LivesplitMessaging(connection=LivesplitConnection(server, port, timeout)) + return LivesplitMessaging(connection=LivesplitConnection(server, port, connectionType, timeout)) diff --git a/src/splitguides/server/split_server.py b/src/splitguides/server/split_server.py index 2ce9726..c14fdb6 100644 --- a/src/splitguides/server/split_server.py +++ b/src/splitguides/server/split_server.py @@ -58,7 +58,7 @@ def event_stream(): current_note_index = None last_update = 0 - client = get_client(settings.hostname, settings.port) + client = get_client(settings.hostname, settings.port, settings.connectionType) connected = client.connect() # Note if the previous state was not connected disconnected = True diff --git a/src/splitguides/settings.py b/src/splitguides/settings.py index 0385118..911f11d 100644 --- a/src/splitguides/settings.py +++ b/src/splitguides/settings.py @@ -73,6 +73,7 @@ class BaseSettings(metaclass=ABCMeta): # Networking Settings hostname: str = "localhost" port: int = 16834 + connectionType: int = 1 # Parser Settings split_separator: str = "" diff --git a/src/splitguides/ui/layouts/server_settings.ui b/src/splitguides/ui/layouts/server_settings.ui index 6347010..f4d0912 100644 --- a/src/splitguides/ui/layouts/server_settings.ui +++ b/src/splitguides/ui/layouts/server_settings.ui @@ -7,7 +7,7 @@ 0 0 400 - 535 + 596 @@ -29,6 +29,13 @@ 5 + + + Livesplit Connection Type + + + + @@ -40,7 +47,7 @@ - + @@ -52,7 +59,7 @@ - + @@ -64,7 +71,7 @@ - + @@ -76,28 +83,28 @@ - + - Qt::Horizontal + Qt::Orientation::Horizontal - + Show Previous Splits: - + 0 - + @@ -109,7 +116,7 @@ - + @@ -121,7 +128,7 @@ - + @@ -133,7 +140,7 @@ - + @@ -148,31 +155,31 @@ - + - Qt::Horizontal + Qt::Orientation::Horizontal - + Font Size: - + - + Text Colour: - + @@ -186,14 +193,14 @@ - + Background Colour: - + @@ -207,21 +214,21 @@ - + - Qt::Horizontal + Qt::Orientation::Horizontal - + HTML Template: - + @@ -239,14 +246,14 @@ - + CSS: - + @@ -264,21 +271,21 @@ - + - Qt::Horizontal + Qt::Orientation::Horizontal - + Next Split Hotkey: - + @@ -296,14 +303,14 @@ - + Previous Split Hotkey: - + @@ -321,31 +328,50 @@ - + + + + Qt::Orientation::Horizontal + + + + Note Server Hostname: - + - + Note Server Port: - + - - - - Qt::Horizontal - + + + + + Named Pipe + + + + + TCP Server + + + + + Websocket Server + + @@ -358,16 +384,17 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + lstype_cbox hostname_edit port_edit previous_edit diff --git a/src/splitguides/ui/layouts/settings.ui b/src/splitguides/ui/layouts/settings.ui index cb4df10..0247147 100644 --- a/src/splitguides/ui/layouts/settings.ui +++ b/src/splitguides/ui/layouts/settings.ui @@ -3,14 +3,14 @@ Settings - Qt::ApplicationModal + Qt::WindowModality::ApplicationModal 0 0 400 - 478 + 532 @@ -30,10 +30,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok @@ -51,7 +51,7 @@ 5 - + @@ -63,7 +63,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -87,7 +87,7 @@ - + @@ -99,28 +99,28 @@ - + - Qt::Horizontal + Qt::Orientation::Horizontal - + Show Previous Splits: - + 0 - + @@ -132,7 +132,7 @@ - + @@ -144,7 +144,7 @@ - + @@ -156,7 +156,7 @@ - + @@ -171,31 +171,31 @@ - + - Qt::Horizontal + Qt::Orientation::Horizontal - + Font Size: - + - + Text Colour: - + @@ -209,14 +209,14 @@ - + Background Colour: - + @@ -230,14 +230,14 @@ - + HTML Template: - + @@ -255,14 +255,14 @@ - + CSS: - + @@ -280,35 +280,35 @@ - + - Qt::Horizontal + Qt::Orientation::Horizontal - + - Qt::Horizontal + Qt::Orientation::Horizontal - + Next Split Hotkey: - + Previous Split Hotkey: - + @@ -326,7 +326,7 @@ - + @@ -344,11 +344,53 @@ + + + + Livesplit Connection Type + + + + + + + Qt::FocusPolicy::StrongFocus + + + true + + + true + + + Named Pipe + + + 3 + + + + Named Pipe + + + + + TCP Server + + + + + Websocket Server + + + + + lstype_cbox hostname_edit port_edit previous_edit @@ -363,6 +405,10 @@ htmltemplate_button css_edit css_button + nextsplitkey_edit + nextsplitkey_button + previoussplitkey_edit + previoussplitkey_button @@ -371,12 +417,32 @@ accepted() Settings accept() + + + 29 + 516 + + + 20 + 20 + + buttonBox rejected() Settings reject() + + + 29 + 516 + + + 20 + 20 + + diff --git a/src/splitguides/ui/main_window.py b/src/splitguides/ui/main_window.py index 6042d88..0f35289 100644 --- a/src/splitguides/ui/main_window.py +++ b/src/splitguides/ui/main_window.py @@ -129,7 +129,7 @@ def __init__(self): self.render_blank() - self.client = get_client(self.settings.hostname, self.settings.port) + self.client = get_client(self.settings.hostname, self.settings.port, self.settings.connectionType) self.ls = LivesplitLink(self.client, self) self.split_index = 0 @@ -406,9 +406,10 @@ def open_settings(self): if ( self.client.connection.server != self.settings.hostname or self.client.connection.port != self.settings.port + or self.client.connection.connectionType != self.settings.connectionType ): self.ls.close() - self.client = get_client(self.settings.hostname, self.settings.port) + self.client = get_client(self.settings.hostname, self.settings.port, self.settings.connectionType) self.ls = LivesplitLink(self.client, self) self.ls.start_loops() diff --git a/src/splitguides/ui/server_settings_ui.py b/src/splitguides/ui/server_settings_ui.py index 46af2af..17d84e4 100644 --- a/src/splitguides/ui/server_settings_ui.py +++ b/src/splitguides/ui/server_settings_ui.py @@ -87,6 +87,7 @@ def setup_validators(self): self.ui.bgcolor_edit.setValidator(color_validator) def fill_settings(self): + self.ui.lstype_cbox.setCurrentIndex(self.settings.connectionType) self.ui.hostname_edit.setText(self.settings.hostname) self.ui.port_edit.setText(str(self.settings.port)) self.ui.previous_edit.setText(str(self.settings.previous_splits)) @@ -111,6 +112,7 @@ def fill_settings(self): self.ui.noteserverport_edit.setText(str(self.settings.server_port)) def store_settings(self): + self.settings.connectionType = self.ui.lstype_cbox.currentIndex() self.settings.hostname = self.ui.hostname_edit.text() self.settings.port = int(self.ui.port_edit.text()) self.settings.previous_splits = int(self.ui.previous_edit.text()) diff --git a/src/splitguides/ui/settings_ui.py b/src/splitguides/ui/settings_ui.py index 0abd7b6..98d3446 100644 --- a/src/splitguides/ui/settings_ui.py +++ b/src/splitguides/ui/settings_ui.py @@ -69,6 +69,7 @@ def setup_validators(self): self.ui.bgcolor_edit.setValidator(color_validator) def fill_settings(self): + self.ui.lstype_cbox.setCurrentIndex(self.settings.connectionType) self.ui.hostname_edit.setText(self.settings.hostname) self.ui.port_edit.setText(str(self.settings.port)) self.ui.previous_edit.setText(str(self.settings.previous_splits)) @@ -90,6 +91,7 @@ def fill_settings(self): self.previoussplitkey = self.settings.decrease_offset_hotkey def store_settings(self): + self.settings.connectionType = self.ui.lstype_cbox.currentIndex() self.settings.hostname = self.ui.hostname_edit.text() self.settings.port = int(self.ui.port_edit.text()) self.settings.previous_splits = int(self.ui.previous_edit.text()) diff --git a/uv.lock b/uv.lock index f62f20f..5188a94 100644 --- a/uv.lock +++ b/uv.lock @@ -3366,7 +3366,9 @@ dependencies = [ { name = "markdown" }, { name = "platformdirs" }, { name = "pyside6" }, + { name = "pywin32" }, { name = "waitress" }, + { name = "websocket-client" }, ] [package.dev-dependencies] @@ -3390,7 +3392,9 @@ requires-dist = [ { name = "markdown", specifier = "~=3.6" }, { name = "platformdirs", specifier = "~=4.3" }, { name = "pyside6", specifier = "~=6.11.0" }, + { name = "pywin32", specifier = ">=311" }, { name = "waitress", specifier = "~=3.0" }, + { name = "websocket-client", specifier = ">=1.9.0" }, ] [package.metadata.requires-dev] @@ -3452,6 +3456,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774, upload-time = "2017-04-05T20:21:32.581Z" }, ] +[[package]] +name = "websocket-client" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/41/aa4bf9664e4cda14c3b39865b12251e8e7d239f4cd0e3cc1b6c2ccde25c1/websocket_client-1.9.0.tar.gz", hash = "sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98", size = 70576, upload-time = "2025-10-07T21:16:36.495Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl", hash = "sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef", size = 82616, upload-time = "2025-10-07T21:16:34.951Z" }, +] + [[package]] name = "werkzeug" version = "3.1.8" From 1910a4e904e3f6be50ce5a29b9be78e955d8c153 Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Sun, 28 Jun 2026 20:24:57 +0200 Subject: [PATCH 02/28] Preseve position on restart --- src/splitguides/settings.py | 2 ++ src/splitguides/ui/main_window.py | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/splitguides/settings.py b/src/splitguides/settings.py index 911f11d..63c962a 100644 --- a/src/splitguides/settings.py +++ b/src/splitguides/settings.py @@ -214,6 +214,8 @@ class DesktopSettings(BaseSettings): transparency: bool = False width: int = 800 height: int = 800 + pos_x: int = 10 + pos_y: int = 10 @prefab diff --git a/src/splitguides/ui/main_window.py b/src/splitguides/ui/main_window.py index 0f35289..016b31a 100644 --- a/src/splitguides/ui/main_window.py +++ b/src/splitguides/ui/main_window.py @@ -85,6 +85,7 @@ def __init__(self): # Window size self.resize(self.settings.width, self.settings.height) + self.move(self.settings.pos_x, self.settings.pos_y) # noinspection PyUnresolvedReferences self.setWindowFlag(QtCore.Qt.WindowType.WindowStaysOnTopHint, self.settings.on_top) @@ -264,6 +265,12 @@ def resizeEvent(self, event): self.settings.width = self.width() self.settings.height = self.height() event.accept() + + def moveEvent(self, event): + """Store the new window position to keep it between launches.""" + self.settings.pos_x = self.pos().x() + self.settings.pos_y = self.pos().y() + return super().moveEvent(event) def setup_actions(self): """Setup the browser element with custom options""" From f6e7b9aef1480f5360162dd600213de2a3053ff6 Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Sun, 28 Jun 2026 20:26:57 +0200 Subject: [PATCH 03/28] Move status updates to single function --- src/splitguides/ui/main_window.py | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/splitguides/ui/main_window.py b/src/splitguides/ui/main_window.py index 016b31a..3cfeb46 100644 --- a/src/splitguides/ui/main_window.py +++ b/src/splitguides/ui/main_window.py @@ -218,29 +218,21 @@ def disable_hotkeys(self): # type: ignore def increase_offset(self): self.split_offset += 1 - # Rerender if not connected (if connected this will happen automatically) if not self.ls.connected: self.update_notes(0) - self.ui.statusbar.showMessage( - f"Trying to connect to Livesplit. | Split Offset: {self.split_offset}" - ) + self.update_StatusMessage() else: - self.ui.statusbar.showMessage( - f"Connected to Livesplit. | Split Offset: {self.split_offset}" - ) + self.update_notes(self.split_index) + self.update_StatusMessage() def decrease_offset(self): self.split_offset -= 1 # Rerender if not connected (if connected this will happen automatically) if not self.ls.connected: self.update_notes(0) - self.ui.statusbar.showMessage( - f"Trying to connect to Livesplit. | Split Offset: {self.split_offset}" - ) + self.update_StatusMessage() else: - self.ui.statusbar.showMessage( - f"Connected to Livesplit. | Split Offset: {self.split_offset}" - ) + self.update_StatusMessage() def start_loops(self): """Start the livesplit server connection thread.""" @@ -396,6 +388,19 @@ def update_notes(self, idx, refresh=False): self.ui.notes.setHtml(html, baseUrl=note_uri) self.split_index = idx + + def update_StatusMessage(self): + if self.ls.connected: + msgLS = "Connected to Livesplit via " + else: + msgLS = "Trying to connect to Livesplit via " + if self.ls.client.connection.connectionType == 1: + msgLS += "TCP" + elif self.ls.client.connection.connectionType == 2: + msgLS += "Websocket" + else: + msgLS += "Pipe" + self.ui.statusbar.showMessage(msgLS + f" | Split Index rendered: {self.split_index} | Split Offset to LS: {self.split_offset}") def open_settings(self): """Open the settings dialog, refresh everything if the settings have changed.""" @@ -476,20 +481,14 @@ def close(self): self.stop_loops() self.client.close() - def update_status(self, message): - self.main_window.ui.statusbar.showMessage(message) + def update_status(self): + self.main_window.update_StatusMessage() def ls_connect(self): - self.update_status( - f"Trying to connect to Livesplit. | " - f"Split Offset: {self.main_window.split_offset}" - ) + self.main_window.update_StatusMessage() self.connected = self.client.connect() if self.connected: - self.update_status( - f"Connected to Livesplit. | " - f"Split Offset: {self.main_window.split_offset}" - ) + self.main_window.update_StatusMessage() def loop_update_split(self): while not self.break_loop: @@ -506,4 +505,5 @@ def loop_update_split(self): self.note_signal.emit(split_index) else: self.ls_connect() - time.sleep(0.1) + self.main_window.update_StatusMessage() + time.sleep(0.5) From 3c71b2eef72dbd840827512b9b72802ee09df31c Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Sun, 28 Jun 2026 20:29:37 +0200 Subject: [PATCH 04/28] Catch any exception that occurs in connections --- src/splitguides/ui/main_window.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/splitguides/ui/main_window.py b/src/splitguides/ui/main_window.py index 3cfeb46..75f6018 100644 --- a/src/splitguides/ui/main_window.py +++ b/src/splitguides/ui/main_window.py @@ -499,6 +499,10 @@ def loop_update_split(self): except (ConnectionError, TimeoutError): self.connected = False self.client.close() + except Exception as e: + print(f"Unexpected error while getting livesplit index: {str(e)}. Retrying") + self.connected = False + self.client.close() else: # Send the signal to the main window to update. # noinspection PyUnresolvedReferences From 2a445c42e58f52270caf571448c2dbb946d435ef Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Sun, 28 Jun 2026 20:31:26 +0200 Subject: [PATCH 05/28] Add reload option for updating notesfile in-between --- src/splitguides/ui/main_window.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/splitguides/ui/main_window.py b/src/splitguides/ui/main_window.py index 75f6018..fce5d53 100644 --- a/src/splitguides/ui/main_window.py +++ b/src/splitguides/ui/main_window.py @@ -286,6 +286,9 @@ def build_menu(self): open_notes = self.rc_menu.addAction("Open Notes") open_notes.triggered.connect(self.open_notes) + reload_notes = self.rc_menu.addAction("Reload Notes File") + reload_notes.triggered.connect(self.reload_notes) + open_settings = self.rc_menu.addAction("Settings") open_settings.triggered.connect(self.open_settings) @@ -337,12 +340,17 @@ def open_notes(self): if notefile: self.notefile = notefile + self.reload_notes() + + def reload_notes(self): + """Recreate a Notes instanceby re-reading the file""" + if self.notefile: # Reset split index and load notes self.notes = Notes.from_file( - notefile, separator=self.settings.split_separator + self.notefile, separator=self.settings.split_separator ) # Remember this notes folder next time notes are loaded. - self.settings.notes_folder = str(Path(notefile).parent) + self.settings.notes_folder = str(Path(self.notefile).parent) # Reset the split offset self.split_offset = 0 From 2a4de3339d11ebcf40719f0174e531133431b276 Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Sun, 28 Jun 2026 20:53:03 +0200 Subject: [PATCH 06/28] Update Readme --- readme.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 5e62f42..e068c2d 100644 --- a/readme.md +++ b/readme.md @@ -37,6 +37,15 @@ platforms. containing the notes you wish to use. 3. Some configuration is available from the settings dialog. +If you are already using the Livesplit Server for something else, +this appliction shouldn't interfere with that, but only a TCP or a Websocket server can be running at a time. +You can change the connection to Livesplit that will be used in the settings. +There are 3 options: +* Named Pipe +* TCP Server (default) +* Websocket Server +The Named Pipe does not use the hostname and port, it should "just work", as long as livesplit is running on the same PC. + Plain text formatting works the same way as SplitNotes. Notes made for that should function fine in SplitGuides. @@ -50,10 +59,11 @@ inserted in between lines. * If a split separator is given, newlines are left as in the input to the markdown/html processors. +If you edited your notes while the program was running, you can reload the notes in the context menu "Reload Notes File". + ### If the notes are not advancing ### -If the text at the bottom says "Trying to connect to Livesplit." make sure that the TCP server -is running. +If the text at the bottom says "Trying to connect to Livesplit." make sure that the selected server in the settings is running. If that doesn't work, check in the Splitguides settings (from the right click menu) * "Livesplit Server Hostname" should be `localhost` @@ -81,7 +91,7 @@ and port given in a web browser. Configuration Options: -* Livesplit server hostname and port +* Livesplit server hostname, port and wanted connection type * Display previous/next splits * Split separator (leave blank for empty line separator) * Font Size From 7d39419a40ba0c70febae72cdb40345dd0e740ac Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Wed, 1 Jul 2026 01:19:39 +0200 Subject: [PATCH 07/28] Move to individual connection classes; Platform dependent Pipes --- pyproject.toml | 2 +- src/splitguides/livesplit_client.py | 431 +++++++++++------- src/splitguides/server/split_server.py | 2 +- src/splitguides/ui/main_window.py | 35 +- .../test_livesplit_client/test_get_client.py | 3 +- uv.lock | 2 +- 6 files changed, 290 insertions(+), 185 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 100a5e6..e64ca7f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ dependencies = [ "waitress~=3.0", "platformdirs~=4.3", "websocket-client>=1.9.0", - "pywin32>=311", + "pywin32>=311; sys_platform == 'win32'", ] classifiers = [ "Development Status :: 4 - Beta", diff --git a/src/splitguides/livesplit_client.py b/src/splitguides/livesplit_client.py index 42249f2..2faf105 100644 --- a/src/splitguides/livesplit_client.py +++ b/src/splitguides/livesplit_client.py @@ -2,7 +2,9 @@ import socket import time import websocket -import win32pipe, win32file, pywintypes +import sys +if sys.platform == "win32": + import win32pipe, win32file, pywintypes from datetime import timedelta import typing @@ -38,102 +40,289 @@ def parse_time(time_str: str) -> timedelta: return result +class ConnectionTypeBase: + def connect(self) -> bool: + return False + + def close(self) -> None: + return + + def send(self, msg: bytes) -> None: + return + + def receive(self) -> bytes: + return b"" + +class ConnectionTCP(ConnectionTypeBase, Prefab): + server: str = "localhost" + port: int = 16834 + timeout: int = 1 + sock: socket.socket | None = attribute(default=None, init=False, repr=False) + + def connect(self) -> bool: + self.close() + self.sock = socket.socket() + try: + self.sock.connect((self.server, self.port)) + self.sock.settimeout(self.timeout) + # We need to ping the connection to make sure we are connected to a TCP server, + # the Websocket server also allows this socket connection + self.sock.send(b"ping\r\n") + ping_resp = self.sock.recv(BUFFER_SIZE).decode("UTF-8").strip("\r\n") + return (ping_resp == "pong") + except TimeoutError: + self.sock.close() + self.sock = None + return False + except ConnectionRefusedError: + self.sock.close() + self.sock = None + return False + except socket.gaierror: + # Could not resolve hostname + self.sock.close() + self.sock = None + return False + + def close(self) -> None: + if self.sock: + self.sock.close() + self.sock = None + + def send(self, msg: bytes) -> None: + try: + self.sock.send(msg + b"\r\n") + except: + self.sock.close() + self.sock = None + raise ConnectionError("The connection has been closed by the host") + + def receive(self) -> bytes: + data_received = b"" + try: + data_received = self.sock.recv(BUFFER_SIZE) + except socket.timeout: + raise TimeoutError( + "No response received from the server within " + f"the timeout period ({self.timeout}s)" + ) + except OSError: + self.sock.close() + self.sock = None + raise ConnectionError("The connection has been closed by the host") + if data_received == b"": + self.sock.close() + self.sock = None + raise ConnectionError("The connection has been closed by the host") + return data_received + +class ConnectionWS(ConnectionTypeBase, Prefab): + server: str = "localhost" + port: int = 16834 + timeout: int = 4 # 1 second not enough to establish a connection + ws: websocket.WebSocket | None = attribute(default=None, init=False, repr=False) + + def connect(self) -> bool: + self.close() + self.ws = websocket.WebSocket() + try: + self.ws.connect(f"ws://{self.server}:{self.port}/livesplit", origin="SplitGuides", timeout=self.timeout) + return True + except Exception as e: + self.ws.close() + self.ws = None + return False + + def close(self) -> None: + if self.ws: + self.ws.close() + self.ws = None + + def send(self, msg: bytes) -> None: + try: + self.ws.send(msg) # no CRLF on Websocket + except Exception as e: + self.ws.close() + self.ws = None + raise ConnectionError("The connection has been closed by the host") + + def receive(self) -> bytes: + try: + data_received : bytes = self.ws.recv() + except Exception as e: + self.ws.close() + self.ws = None + raise ConnectionError("The connection has been closed by the host") + if isinstance(data_received, str): + # should always be string, encode to bytes for unified handling + data_received = data_received.encode("UTF8") + if data_received == b"": + self.ws.close() + self.ws = None + raise ConnectionError("The connection has been closed by the host") + return data_received + +class ConnectionPipe(ConnectionTypeBase): + # pipe is Windows and localhost only, localhost setting is not checked + handle = None + + def connect(self) -> bool: + if sys.platform != "win32": + raise NotImplementedError('ConnectionPipe class only on Windows') + self.close() + try: + self.handle = win32file.CreateFile( + r'\\.\pipe\livesplit', + win32file.GENERIC_READ | win32file.GENERIC_WRITE, + 0, + None, + win32file.OPEN_EXISTING, + 0, + None + ) + res = win32pipe.SetNamedPipeHandleState(self.handle, win32pipe.PIPE_READMODE_BYTE | win32pipe.PIPE_NOWAIT, None, None) + if res == 0: # errored + self.handle = None + return False + except pywintypes.error as e: + self.handle = None + if e.args[0] != 2: # 2 is unable to find the file -> don't spam the console with that + print('Pipe error: ' + str(e)) + return False + return True + + def close(self) -> None: + if sys.platform != "win32": + raise NotImplementedError('ConnectionPipe class only on Windows') + if self.handle: + win32file.CloseHandle(self.handle) + self.handle = None + + def send(self, msg: bytes) -> None: + if sys.platform != "win32": + raise NotImplementedError('ConnectionPipe class only on Windows') + try: + win32file.WriteFile(self.handle, msg + b"\r\n") + except Exception as e: + win32file.CloseHandle(self.handle) + self.handle = None + raise ConnectionError("Pipe sending error: " + str(e)) + + def receive(self) -> bytes: + if sys.platform != "win32": + raise NotImplementedError('ConnectionPipe class only on Windows') + try: + # wait a bit for data to arrive, the ReadFile would stall otherwise + time.sleep(0.05) + data_received = win32file.ReadFile(self.handle, BUFFER_SIZE) + # this is returned as tuple, only pass the data onwards + data_received = data_received[1] + except Exception as e: + win32file.CloseHandle(self.handle) + self.handle = None + raise ConnectionError("Pipe broken: " + str(e)) + return data_received + +CONNECTIONTYPE_PIPE=0 +CONNECTIONTYPE_TCP=1 +CONNECTIONTYPE_WS=2 + +STABLE_RETRY=10 class LivesplitConnection(Prefab): """ - Socket based livesplit connection model + Livesplit connection model supporting Named Pipe (Windows-only), TCP and Websocket connections """ - server: str = attribute(default="localhost", init=True) - port: int = attribute(default=16834, init=True) - connectionType: int = attribute(default=1, init=True) # 0: named pipe, 1: TCP, 2: websocket - timeout: int = attribute(default=1, init=True) - sockTCP: socket.socket | None = attribute(default=None, init=False, repr=False) - sockWS: websocket.WebSocketApp | None = attribute(default=None, init=False, repr=False) - handlePipe = attribute(default=None, init=False, repr=False) + server: str = "localhost" + port: int = 16834 + + stable_type : int = attribute(default=-1, init=False, repr=False) + stable_retry : int = attribute(default=0, init=False, repr=False) + next_attempt_idx : int = attribute(default=0, init=False, repr=False) + connection_obj : ConnectionTypeBase | None = attribute(default=None, init=False, repr=False) + list_connection_types : list = attribute(default=[], init=False, repr=False) + + def _get_valid_list(self): + if sys.platform != "win32": + self.list_connection_types = [CONNECTIONTYPE_TCP, CONNECTIONTYPE_WS] + return + # these hostnames will try the Named Pipe on Windows along with the other types + loopback_hosts = ["localhost", "127.0.0.1", "::1"] + if self.server.lower() in loopback_hosts: + self.list_connection_types = [CONNECTIONTYPE_PIPE, CONNECTIONTYPE_TCP, CONNECTIONTYPE_WS] + else: + self.list_connection_types = [CONNECTIONTYPE_TCP, CONNECTIONTYPE_WS] + + def is_connected(self) -> bool: + return (bool)(self.connection_obj) + + def get_connection_friendly_name(self) -> str: + if self.connection_obj: + if self.stable_type == CONNECTIONTYPE_PIPE: + status = "Named Pipe" + elif self.stable_type == CONNECTIONTYPE_TCP: + status = "TCP" + elif self.stable_type == CONNECTIONTYPE_WS: + status = "Websocket" + else: + status = "" + else: + status = "" + return status def connect(self) -> bool: """ Attempt to connect to the livesplit server :return: True if connected, otherwise False """ + if len(self.list_connection_types) == 0: + # post init to fill the valid connections once + self._get_valid_list() + self.close() - - if self.connectionType == 1: - self.sockTCP = socket.socket() - try: - self.sockTCP.connect((self.server, self.port)) - self.sockTCP.settimeout(self.timeout) - self.sockTCP.send(b"ping\r\n") - ping_resp = self.sockTCP.recv(BUFFER_SIZE).decode("UTF-8").strip("\r\n") - return (ping_resp == "pong") - except ConnectionRefusedError: - self.sockTCP.close() - self.sockTCP = None - return False - except socket.gaierror: - # Could not resolve hostname - self.sockTCP.close() - self.sockTCP = None - return False - elif self.connectionType == 2: - self.sockWS = websocket.WebSocket() - try: - self.sockWS.connect(f"ws://{self.server}:{self.port}/livesplit", origin="SplitGuides", timeout=10) - except Exception as e: - self.sockWS.close() - self.sockWS = None - return False - else: - return True + + if self.stable_type >= 0: + cur_type : int = self.stable_type else: - try: - self.handlePipe = win32file.CreateFile( - r'\\.\pipe\livesplit', - win32file.GENERIC_READ | win32file.GENERIC_WRITE, - 0, - None, - win32file.OPEN_EXISTING, - 0, - None - ) - res = win32pipe.SetNamedPipeHandleState(self.handlePipe, win32pipe.PIPE_READMODE_BYTE | win32pipe.PIPE_NOWAIT, None, None) - if res == 0: # errored - self.handlePipe = None - return False - except pywintypes.error as e: - self.handlePipe = None - print('Pipe error: ' + e.args[2]) - return False - else: - return True + cur_type : int = self.list_connection_types[self.next_attempt_idx] + + if cur_type == CONNECTIONTYPE_PIPE: + self.connection_obj = ConnectionPipe() + elif cur_type == CONNECTIONTYPE_TCP: + self.connection_obj = ConnectionTCP(self.server, self.port) + elif cur_type == CONNECTIONTYPE_WS: + self.connection_obj = ConnectionWS(self.server, self.port) + else: # out of range, logic error + raise Exception('logic error') + + connection_successful = self.connection_obj.connect() - def ensureConnected(self) -> bool: - if self.connectionType == 1: - if not self.sockTCP: - return self.connect() - else: - return True - elif self.connectionType == 2: - if not self.sockWS: - return self.connect() + if connection_successful: + if self.stable_type >= 0: + # restablished after connection drop + self.stable_retry = 0 else: - return True + # connected after searching + self.stable_type = cur_type + self.stable_retry = 0 else: - if not self.handlePipe: - return self.connect() + self.connection_obj = None + if self.stable_type >= 0: + # try to reconnect on that method + self.stable_retry += 1 + if self.stable_retry >= STABLE_RETRY: + # give up on the stable index + self.stable_type = -1 + self.next_attempt_idx = 0 else: - return True + # try next method + self.next_attempt_idx = (self.next_attempt_idx + 1) % len(self.list_connection_types) + return connection_successful def close(self) -> None: - if self.sockTCP: - self.sockTCP.close() - self.sockTCP = None - if self.sockWS: - self.sockWS.close() - self.sockWS = None - if self.handlePipe: - win32file.CloseHandle(self.handlePipe) - self.handlePipe = None + if self.connection_obj: + self.connection_obj.close() + self.connection_obj = None def send(self, msg: bytes) -> None: """ @@ -144,83 +333,22 @@ def send(self, msg: bytes) -> None: :param msg: bytes message to send :return: """ - if not self.ensureConnected(): + if not self.is_connected(): return - if self.connectionType == 1: - try: - self.sockTCP.send(msg + b"\r\n") - except: - self.sockTCP.close() - self.sockTCP = None - raise ConnectionAbortedError("The connection has been closed by the host") - elif self.connectionType == 2: - try: - self.sockWS.send(msg) #no CRLF on WS - except Exception as e: - self.sockWS.close() - self.sockWS = None - raise ConnectionAbortedError("The connection has been closed by the host") - else: - try: - win32file.WriteFile(self.handlePipe, msg + b"\r\n") - except Exception as e: - print("pipe sending error: " + str(e)) - win32file.CloseHandle(self.handlePipe) - self.handlePipe = None - raise ConnectionAbortedError("Pipe broken") + self.connection_obj.send(msg) - def receive(self) -> typing.Union[bytes, str]: + def receive(self) -> bytes: """ Attempt to receive a message from the livesplit server raise ConnectionError if the connection has been terminated. :return: bytes or string received from the server """ - if not self.ensureConnected(): + if not self.is_connected(): return b"" - data_received = b"" - if self.connectionType == 1: - try: - data_received = self.sockTCP.recv(BUFFER_SIZE) - except socket.timeout: - raise TimeoutError( - "No response received from the server within " - f"the timeout period ({self.timeout}s)" - ) - except OSError: - self.sockTCP.close() - self.sockTCP = None - raise ConnectionError("The connection has been closed by the host") - - if data_received == b"": - self.sockTCP.close() - self.sockTCP = None - raise ConnectionError("The connection has been closed by the host") - - return data_received - elif self.connectionType == 2: - try: - data_received : bytes = self.sockWS.recv() - except Exception as e: - self.sockWS.close() - self.sockWS = None - raise ConnectionAbortedError("The connection has been closed by the host") - return data_received - else: - time.sleep(0.05) - try: - data_received = win32file.ReadFile(self.handlePipe, BUFFER_SIZE) - # this is returned as tuple, only pass the data onwards - data_received = data_received[1] - except Exception as e: - win32file.CloseHandle(self.handlePipe) - self.handlePipe = None - raise ConnectionAbortedError("Pipe broken") - return data_received - - return b"" + return self.connection_obj.receive() class LivesplitMessaging(Prefab): connection: LivesplitConnection @@ -231,7 +359,7 @@ def connect(self) -> bool: def close(self) -> None: self.connection.close() - def send(self, message) -> None: + def send(self, message: str) -> None: m = message.encode("UTF8") self.connection.send(m) @@ -244,10 +372,7 @@ def receive(self, datatype: typing.Literal["text"] = "text") -> str: ... def receive(self, datatype="text"): result = self.connection.receive() - if isinstance(result, bytes): - result = result.decode("UTF8").strip() - else: #str - result = result.strip() + result = result.decode("UTF8").strip() if datatype == "time": result = parse_time(result) @@ -399,8 +524,6 @@ def get_current_timer_phase(self) -> str: def get_client( server: str = "localhost", - port: int = 16834, - connectionType: int = 1, - timeout: int = 1 + port: int = 16834 ) -> LivesplitMessaging: - return LivesplitMessaging(connection=LivesplitConnection(server, port, connectionType, timeout)) + return LivesplitMessaging(connection=LivesplitConnection(server, port)) diff --git a/src/splitguides/server/split_server.py b/src/splitguides/server/split_server.py index c14fdb6..2ce9726 100644 --- a/src/splitguides/server/split_server.py +++ b/src/splitguides/server/split_server.py @@ -58,7 +58,7 @@ def event_stream(): current_note_index = None last_update = 0 - client = get_client(settings.hostname, settings.port, settings.connectionType) + client = get_client(settings.hostname, settings.port) connected = client.connect() # Note if the previous state was not connected disconnected = True diff --git a/src/splitguides/ui/main_window.py b/src/splitguides/ui/main_window.py index fce5d53..2951695 100644 --- a/src/splitguides/ui/main_window.py +++ b/src/splitguides/ui/main_window.py @@ -130,7 +130,7 @@ def __init__(self): self.render_blank() - self.client = get_client(self.settings.hostname, self.settings.port, self.settings.connectionType) + self.client = get_client(self.settings.hostname, self.settings.port) self.ls = LivesplitLink(self.client, self) self.split_index = 0 @@ -398,17 +398,12 @@ def update_notes(self, idx, refresh=False): self.split_index = idx def update_StatusMessage(self): - if self.ls.connected: - msgLS = "Connected to Livesplit via " + conn_status = self.ls.client.connection.get_connection_friendly_name() + if conn_status == "": + msgLS = "Trying to connect to Livesplit" else: - msgLS = "Trying to connect to Livesplit via " - if self.ls.client.connection.connectionType == 1: - msgLS += "TCP" - elif self.ls.client.connection.connectionType == 2: - msgLS += "Websocket" - else: - msgLS += "Pipe" - self.ui.statusbar.showMessage(msgLS + f" | Split Index rendered: {self.split_index} | Split Offset to LS: {self.split_offset}") + msgLS = "Connected to Livesplit via " + conn_status + self.ui.statusbar.showMessage(f"{msgLS} | Split Index rendered: {self.split_index} | Split Offset to LS: {self.split_offset}") def open_settings(self): """Open the settings dialog, refresh everything if the settings have changed.""" @@ -429,7 +424,7 @@ def open_settings(self): or self.client.connection.connectionType != self.settings.connectionType ): self.ls.close() - self.client = get_client(self.settings.hostname, self.settings.port, self.settings.connectionType) + self.client = get_client(self.settings.hostname, self.settings.port) self.ls = LivesplitLink(self.client, self) self.ls.start_loops() @@ -469,7 +464,6 @@ def __init__(self, client, main_window): super().__init__() self.client = client self.main_window = main_window # type: MainWindow - self.connected = False self.break_loop = False self.pool = None # noinspection PyUnresolvedReferences @@ -489,33 +483,22 @@ def close(self): self.stop_loops() self.client.close() - def update_status(self): - self.main_window.update_StatusMessage() - - def ls_connect(self): - self.main_window.update_StatusMessage() - self.connected = self.client.connect() - if self.connected: - self.main_window.update_StatusMessage() - def loop_update_split(self): while not self.break_loop: # If not connected attempt to connect - if self.connected: + if self.client.connection.is_connected(): try: split_index = self.client.get_split_index() except (ConnectionError, TimeoutError): - self.connected = False self.client.close() except Exception as e: print(f"Unexpected error while getting livesplit index: {str(e)}. Retrying") - self.connected = False self.client.close() else: # Send the signal to the main window to update. # noinspection PyUnresolvedReferences self.note_signal.emit(split_index) else: - self.ls_connect() + self.client.connect() self.main_window.update_StatusMessage() time.sleep(0.5) diff --git a/tests/test_livesplit_client/test_get_client.py b/tests/test_livesplit_client/test_get_client.py index 912e31e..3031ac1 100644 --- a/tests/test_livesplit_client/test_get_client.py +++ b/tests/test_livesplit_client/test_get_client.py @@ -2,7 +2,6 @@ def test_get_client(): - client = get_client("servername", 12, 2) + client = get_client("servername", 12) assert client.connection.server == "servername" assert client.connection.port == 12 - assert client.connection.timeout == 2 diff --git a/uv.lock b/uv.lock index 5188a94..d1ba17d 100644 --- a/uv.lock +++ b/uv.lock @@ -3366,7 +3366,7 @@ dependencies = [ { name = "markdown" }, { name = "platformdirs" }, { name = "pyside6" }, - { name = "pywin32" }, + { name = "pywin32", marker = "sys_platform == 'win32'" }, { name = "waitress" }, { name = "websocket-client" }, ] From 41735fb093af62540e57b31f580325e163055f1f Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Wed, 1 Jul 2026 01:28:26 +0200 Subject: [PATCH 08/28] Revert settings UI changes --- src/splitguides/settings.py | 1 - src/splitguides/ui/layouts/server_settings.ui | 113 ++++++-------- src/splitguides/ui/layouts/settings.ui | 138 +++++------------- src/splitguides/ui/main_window.py | 1 - src/splitguides/ui/server_settings_ui.py | 2 - src/splitguides/ui/settings_ui.py | 2 - 6 files changed, 79 insertions(+), 178 deletions(-) diff --git a/src/splitguides/settings.py b/src/splitguides/settings.py index 63c962a..85c654e 100644 --- a/src/splitguides/settings.py +++ b/src/splitguides/settings.py @@ -73,7 +73,6 @@ class BaseSettings(metaclass=ABCMeta): # Networking Settings hostname: str = "localhost" port: int = 16834 - connectionType: int = 1 # Parser Settings split_separator: str = "" diff --git a/src/splitguides/ui/layouts/server_settings.ui b/src/splitguides/ui/layouts/server_settings.ui index f4d0912..6347010 100644 --- a/src/splitguides/ui/layouts/server_settings.ui +++ b/src/splitguides/ui/layouts/server_settings.ui @@ -7,7 +7,7 @@ 0 0 400 - 596 + 535 @@ -29,13 +29,6 @@ 5 - - - Livesplit Connection Type - - - - @@ -47,7 +40,7 @@ - + @@ -59,7 +52,7 @@ - + @@ -71,7 +64,7 @@ - + @@ -83,28 +76,28 @@ - + - Qt::Orientation::Horizontal + Qt::Horizontal - + Show Previous Splits: - + 0 - + @@ -116,7 +109,7 @@ - + @@ -128,7 +121,7 @@ - + @@ -140,7 +133,7 @@ - + @@ -155,31 +148,31 @@ - + - Qt::Orientation::Horizontal + Qt::Horizontal - + Font Size: - + - + Text Colour: - + @@ -193,14 +186,14 @@ - + Background Colour: - + @@ -214,21 +207,21 @@ - + - Qt::Orientation::Horizontal + Qt::Horizontal - + HTML Template: - + @@ -246,14 +239,14 @@ - + CSS: - + @@ -271,21 +264,21 @@ - + - Qt::Orientation::Horizontal + Qt::Horizontal - + Next Split Hotkey: - + @@ -303,14 +296,14 @@ - + Previous Split Hotkey: - + @@ -328,50 +321,31 @@ - - - - Qt::Orientation::Horizontal - - - - + Note Server Hostname: - + - + Note Server Port: - + - - - - - Named Pipe - - - - - TCP Server - - - - - Websocket Server - - + + + + Qt::Horizontal + @@ -384,17 +358,16 @@ - Qt::Orientation::Horizontal + Qt::Horizontal - QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::Ok - lstype_cbox hostname_edit port_edit previous_edit diff --git a/src/splitguides/ui/layouts/settings.ui b/src/splitguides/ui/layouts/settings.ui index 0247147..cb4df10 100644 --- a/src/splitguides/ui/layouts/settings.ui +++ b/src/splitguides/ui/layouts/settings.ui @@ -3,14 +3,14 @@ Settings - Qt::WindowModality::ApplicationModal + Qt::ApplicationModal 0 0 400 - 532 + 478 @@ -30,10 +30,10 @@ - Qt::Orientation::Horizontal + Qt::Horizontal - QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -51,7 +51,7 @@ 5 - + @@ -63,7 +63,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -87,7 +87,7 @@ - + @@ -99,28 +99,28 @@ - + - Qt::Orientation::Horizontal + Qt::Horizontal - + Show Previous Splits: - + 0 - + @@ -132,7 +132,7 @@ - + @@ -144,7 +144,7 @@ - + @@ -156,7 +156,7 @@ - + @@ -171,31 +171,31 @@ - + - Qt::Orientation::Horizontal + Qt::Horizontal - + Font Size: - + - + Text Colour: - + @@ -209,14 +209,14 @@ - + Background Colour: - + @@ -230,14 +230,14 @@ - + HTML Template: - + @@ -255,14 +255,14 @@ - + CSS: - + @@ -280,35 +280,35 @@ - + - Qt::Orientation::Horizontal + Qt::Horizontal - + - Qt::Orientation::Horizontal + Qt::Horizontal - + Next Split Hotkey: - + Previous Split Hotkey: - + @@ -326,7 +326,7 @@ - + @@ -344,53 +344,11 @@ - - - - Livesplit Connection Type - - - - - - - Qt::FocusPolicy::StrongFocus - - - true - - - true - - - Named Pipe - - - 3 - - - - Named Pipe - - - - - TCP Server - - - - - Websocket Server - - - - - lstype_cbox hostname_edit port_edit previous_edit @@ -405,10 +363,6 @@ htmltemplate_button css_edit css_button - nextsplitkey_edit - nextsplitkey_button - previoussplitkey_edit - previoussplitkey_button @@ -417,32 +371,12 @@ accepted() Settings accept() - - - 29 - 516 - - - 20 - 20 - - buttonBox rejected() Settings reject() - - - 29 - 516 - - - 20 - 20 - - diff --git a/src/splitguides/ui/main_window.py b/src/splitguides/ui/main_window.py index 2951695..c2fc187 100644 --- a/src/splitguides/ui/main_window.py +++ b/src/splitguides/ui/main_window.py @@ -421,7 +421,6 @@ def open_settings(self): if ( self.client.connection.server != self.settings.hostname or self.client.connection.port != self.settings.port - or self.client.connection.connectionType != self.settings.connectionType ): self.ls.close() self.client = get_client(self.settings.hostname, self.settings.port) diff --git a/src/splitguides/ui/server_settings_ui.py b/src/splitguides/ui/server_settings_ui.py index 17d84e4..46af2af 100644 --- a/src/splitguides/ui/server_settings_ui.py +++ b/src/splitguides/ui/server_settings_ui.py @@ -87,7 +87,6 @@ def setup_validators(self): self.ui.bgcolor_edit.setValidator(color_validator) def fill_settings(self): - self.ui.lstype_cbox.setCurrentIndex(self.settings.connectionType) self.ui.hostname_edit.setText(self.settings.hostname) self.ui.port_edit.setText(str(self.settings.port)) self.ui.previous_edit.setText(str(self.settings.previous_splits)) @@ -112,7 +111,6 @@ def fill_settings(self): self.ui.noteserverport_edit.setText(str(self.settings.server_port)) def store_settings(self): - self.settings.connectionType = self.ui.lstype_cbox.currentIndex() self.settings.hostname = self.ui.hostname_edit.text() self.settings.port = int(self.ui.port_edit.text()) self.settings.previous_splits = int(self.ui.previous_edit.text()) diff --git a/src/splitguides/ui/settings_ui.py b/src/splitguides/ui/settings_ui.py index 98d3446..0abd7b6 100644 --- a/src/splitguides/ui/settings_ui.py +++ b/src/splitguides/ui/settings_ui.py @@ -69,7 +69,6 @@ def setup_validators(self): self.ui.bgcolor_edit.setValidator(color_validator) def fill_settings(self): - self.ui.lstype_cbox.setCurrentIndex(self.settings.connectionType) self.ui.hostname_edit.setText(self.settings.hostname) self.ui.port_edit.setText(str(self.settings.port)) self.ui.previous_edit.setText(str(self.settings.previous_splits)) @@ -91,7 +90,6 @@ def fill_settings(self): self.previoussplitkey = self.settings.decrease_offset_hotkey def store_settings(self): - self.settings.connectionType = self.ui.lstype_cbox.currentIndex() self.settings.hostname = self.ui.hostname_edit.text() self.settings.port = int(self.ui.port_edit.text()) self.settings.previous_splits = int(self.ui.previous_edit.text()) From cff98fb8c5e45b6c8222a066b4147c3284ae9735 Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 13:18:35 +0100 Subject: [PATCH 09/28] Make livesplit_client into a package. This is to prepare to split off the windows-only elements into a separate file. --- .../{livesplit_client.py => livesplit_client/__init__.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/splitguides/{livesplit_client.py => livesplit_client/__init__.py} (100%) diff --git a/src/splitguides/livesplit_client.py b/src/splitguides/livesplit_client/__init__.py similarity index 100% rename from src/splitguides/livesplit_client.py rename to src/splitguides/livesplit_client/__init__.py From dedd5c7ecdef2f2559bd7fe0210be0be7b7e032d Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 13:29:29 +0100 Subject: [PATCH 10/28] Split the connection out into separate files --- src/splitguides/livesplit_client/__init__.py | 205 +----------------- .../livesplit_client/connection_shared.py | 130 +++++++++++ .../livesplit_client/connection_windows.py | 75 +++++++ 3 files changed, 216 insertions(+), 194 deletions(-) create mode 100644 src/splitguides/livesplit_client/connection_shared.py create mode 100644 src/splitguides/livesplit_client/connection_windows.py diff --git a/src/splitguides/livesplit_client/__init__.py b/src/splitguides/livesplit_client/__init__.py index 2faf105..315ac92 100644 --- a/src/splitguides/livesplit_client/__init__.py +++ b/src/splitguides/livesplit_client/__init__.py @@ -1,16 +1,15 @@ import re -import socket -import time -import websocket import sys -if sys.platform == "win32": - import win32pipe, win32file, pywintypes + from datetime import timedelta import typing from ducktools.classbuilder.prefab import Prefab, attribute -BUFFER_SIZE = 4096 +from .connection_shared import ConnectionTypeBase, ConnectionTCP, ConnectionWS + +if sys.platform == "win32": + from .connection_windows import ConnectionPipe pattern = re.compile( @@ -40,188 +39,6 @@ def parse_time(time_str: str) -> timedelta: return result -class ConnectionTypeBase: - def connect(self) -> bool: - return False - - def close(self) -> None: - return - - def send(self, msg: bytes) -> None: - return - - def receive(self) -> bytes: - return b"" - -class ConnectionTCP(ConnectionTypeBase, Prefab): - server: str = "localhost" - port: int = 16834 - timeout: int = 1 - sock: socket.socket | None = attribute(default=None, init=False, repr=False) - - def connect(self) -> bool: - self.close() - self.sock = socket.socket() - try: - self.sock.connect((self.server, self.port)) - self.sock.settimeout(self.timeout) - # We need to ping the connection to make sure we are connected to a TCP server, - # the Websocket server also allows this socket connection - self.sock.send(b"ping\r\n") - ping_resp = self.sock.recv(BUFFER_SIZE).decode("UTF-8").strip("\r\n") - return (ping_resp == "pong") - except TimeoutError: - self.sock.close() - self.sock = None - return False - except ConnectionRefusedError: - self.sock.close() - self.sock = None - return False - except socket.gaierror: - # Could not resolve hostname - self.sock.close() - self.sock = None - return False - - def close(self) -> None: - if self.sock: - self.sock.close() - self.sock = None - - def send(self, msg: bytes) -> None: - try: - self.sock.send(msg + b"\r\n") - except: - self.sock.close() - self.sock = None - raise ConnectionError("The connection has been closed by the host") - - def receive(self) -> bytes: - data_received = b"" - try: - data_received = self.sock.recv(BUFFER_SIZE) - except socket.timeout: - raise TimeoutError( - "No response received from the server within " - f"the timeout period ({self.timeout}s)" - ) - except OSError: - self.sock.close() - self.sock = None - raise ConnectionError("The connection has been closed by the host") - if data_received == b"": - self.sock.close() - self.sock = None - raise ConnectionError("The connection has been closed by the host") - return data_received - -class ConnectionWS(ConnectionTypeBase, Prefab): - server: str = "localhost" - port: int = 16834 - timeout: int = 4 # 1 second not enough to establish a connection - ws: websocket.WebSocket | None = attribute(default=None, init=False, repr=False) - - def connect(self) -> bool: - self.close() - self.ws = websocket.WebSocket() - try: - self.ws.connect(f"ws://{self.server}:{self.port}/livesplit", origin="SplitGuides", timeout=self.timeout) - return True - except Exception as e: - self.ws.close() - self.ws = None - return False - - def close(self) -> None: - if self.ws: - self.ws.close() - self.ws = None - - def send(self, msg: bytes) -> None: - try: - self.ws.send(msg) # no CRLF on Websocket - except Exception as e: - self.ws.close() - self.ws = None - raise ConnectionError("The connection has been closed by the host") - - def receive(self) -> bytes: - try: - data_received : bytes = self.ws.recv() - except Exception as e: - self.ws.close() - self.ws = None - raise ConnectionError("The connection has been closed by the host") - if isinstance(data_received, str): - # should always be string, encode to bytes for unified handling - data_received = data_received.encode("UTF8") - if data_received == b"": - self.ws.close() - self.ws = None - raise ConnectionError("The connection has been closed by the host") - return data_received - -class ConnectionPipe(ConnectionTypeBase): - # pipe is Windows and localhost only, localhost setting is not checked - handle = None - - def connect(self) -> bool: - if sys.platform != "win32": - raise NotImplementedError('ConnectionPipe class only on Windows') - self.close() - try: - self.handle = win32file.CreateFile( - r'\\.\pipe\livesplit', - win32file.GENERIC_READ | win32file.GENERIC_WRITE, - 0, - None, - win32file.OPEN_EXISTING, - 0, - None - ) - res = win32pipe.SetNamedPipeHandleState(self.handle, win32pipe.PIPE_READMODE_BYTE | win32pipe.PIPE_NOWAIT, None, None) - if res == 0: # errored - self.handle = None - return False - except pywintypes.error as e: - self.handle = None - if e.args[0] != 2: # 2 is unable to find the file -> don't spam the console with that - print('Pipe error: ' + str(e)) - return False - return True - - def close(self) -> None: - if sys.platform != "win32": - raise NotImplementedError('ConnectionPipe class only on Windows') - if self.handle: - win32file.CloseHandle(self.handle) - self.handle = None - - def send(self, msg: bytes) -> None: - if sys.platform != "win32": - raise NotImplementedError('ConnectionPipe class only on Windows') - try: - win32file.WriteFile(self.handle, msg + b"\r\n") - except Exception as e: - win32file.CloseHandle(self.handle) - self.handle = None - raise ConnectionError("Pipe sending error: " + str(e)) - - def receive(self) -> bytes: - if sys.platform != "win32": - raise NotImplementedError('ConnectionPipe class only on Windows') - try: - # wait a bit for data to arrive, the ReadFile would stall otherwise - time.sleep(0.05) - data_received = win32file.ReadFile(self.handle, BUFFER_SIZE) - # this is returned as tuple, only pass the data onwards - data_received = data_received[1] - except Exception as e: - win32file.CloseHandle(self.handle) - self.handle = None - raise ConnectionError("Pipe broken: " + str(e)) - return data_received CONNECTIONTYPE_PIPE=0 CONNECTIONTYPE_TCP=1 @@ -252,10 +69,10 @@ def _get_valid_list(self): self.list_connection_types = [CONNECTIONTYPE_PIPE, CONNECTIONTYPE_TCP, CONNECTIONTYPE_WS] else: self.list_connection_types = [CONNECTIONTYPE_TCP, CONNECTIONTYPE_WS] - + def is_connected(self) -> bool: return (bool)(self.connection_obj) - + def get_connection_friendly_name(self) -> str: if self.connection_obj: if self.stable_type == CONNECTIONTYPE_PIPE: @@ -285,7 +102,7 @@ def connect(self) -> bool: cur_type : int = self.stable_type else: cur_type : int = self.list_connection_types[self.next_attempt_idx] - + if cur_type == CONNECTIONTYPE_PIPE: self.connection_obj = ConnectionPipe() elif cur_type == CONNECTIONTYPE_TCP: @@ -294,7 +111,7 @@ def connect(self) -> bool: self.connection_obj = ConnectionWS(self.server, self.port) else: # out of range, logic error raise Exception('logic error') - + connection_successful = self.connection_obj.connect() if connection_successful: @@ -335,7 +152,7 @@ def send(self, msg: bytes) -> None: """ if not self.is_connected(): return - + self.connection_obj.send(msg) def receive(self) -> bytes: @@ -347,7 +164,7 @@ def receive(self) -> bytes: """ if not self.is_connected(): return b"" - + return self.connection_obj.receive() class LivesplitMessaging(Prefab): diff --git a/src/splitguides/livesplit_client/connection_shared.py b/src/splitguides/livesplit_client/connection_shared.py new file mode 100644 index 0000000..676d4e5 --- /dev/null +++ b/src/splitguides/livesplit_client/connection_shared.py @@ -0,0 +1,130 @@ +import socket +import websocket + +from ducktools.classbuilder.prefab import Prefab, attribute + + +BUFFER_SIZE = 4096 + + +class ConnectionTypeBase: + def connect(self) -> bool: + return False + + def close(self) -> None: + return + + def send(self, msg: bytes) -> None: + return + + def receive(self) -> bytes: + return b"" + +class ConnectionTCP(ConnectionTypeBase, Prefab): + server: str = "localhost" + port: int = 16834 + timeout: int = 1 + sock: socket.socket | None = attribute(default=None, init=False, repr=False) + + def connect(self) -> bool: + self.close() + self.sock = socket.socket() + try: + self.sock.connect((self.server, self.port)) + self.sock.settimeout(self.timeout) + # We need to ping the connection to make sure we are connected to a TCP server, + # the Websocket server also allows this socket connection + self.sock.send(b"ping\r\n") + ping_resp = self.sock.recv(BUFFER_SIZE).decode("UTF-8").strip("\r\n") + return (ping_resp == "pong") + except TimeoutError: + self.sock.close() + self.sock = None + return False + except ConnectionRefusedError: + self.sock.close() + self.sock = None + return False + except socket.gaierror: + # Could not resolve hostname + self.sock.close() + self.sock = None + return False + + def close(self) -> None: + if self.sock: + self.sock.close() + self.sock = None + + def send(self, msg: bytes) -> None: + try: + self.sock.send(msg + b"\r\n") + except: + self.sock.close() + self.sock = None + raise ConnectionError("The connection has been closed by the host") + + def receive(self) -> bytes: + data_received = b"" + try: + data_received = self.sock.recv(BUFFER_SIZE) + except socket.timeout: + raise TimeoutError( + "No response received from the server within " + f"the timeout period ({self.timeout}s)" + ) + except OSError: + self.sock.close() + self.sock = None + raise ConnectionError("The connection has been closed by the host") + if data_received == b"": + self.sock.close() + self.sock = None + raise ConnectionError("The connection has been closed by the host") + return data_received + +class ConnectionWS(ConnectionTypeBase, Prefab): + server: str = "localhost" + port: int = 16834 + timeout: int = 4 # 1 second not enough to establish a connection + ws: websocket.WebSocket | None = attribute(default=None, init=False, repr=False) + + def connect(self) -> bool: + self.close() + self.ws = websocket.WebSocket() + try: + self.ws.connect(f"ws://{self.server}:{self.port}/livesplit", origin="SplitGuides", timeout=self.timeout) + return True + except Exception as e: + self.ws.close() + self.ws = None + return False + + def close(self) -> None: + if self.ws: + self.ws.close() + self.ws = None + + def send(self, msg: bytes) -> None: + try: + self.ws.send(msg) # no CRLF on Websocket + except Exception as e: + self.ws.close() + self.ws = None + raise ConnectionError("The connection has been closed by the host") + + def receive(self) -> bytes: + try: + data_received : bytes = self.ws.recv() + except Exception as e: + self.ws.close() + self.ws = None + raise ConnectionError("The connection has been closed by the host") + if isinstance(data_received, str): + # should always be string, encode to bytes for unified handling + data_received = data_received.encode("UTF8") + if data_received == b"": + self.ws.close() + self.ws = None + raise ConnectionError("The connection has been closed by the host") + return data_received diff --git a/src/splitguides/livesplit_client/connection_windows.py b/src/splitguides/livesplit_client/connection_windows.py new file mode 100644 index 0000000..5afd71f --- /dev/null +++ b/src/splitguides/livesplit_client/connection_windows.py @@ -0,0 +1,75 @@ +import sys + +if sys.platform != "win32": + raise ImportError("'connection_windows.py' is not supported on platforms other than Windows") + +import time + +import pywintypes +import win32file +import win32pipe + + +from .connection_shared import ConnectionTypeBase + + +class ConnectionPipe(ConnectionTypeBase): + # pipe is Windows and localhost only, localhost setting is not checked + handle = None + + def connect(self) -> bool: + if sys.platform != "win32": + raise NotImplementedError('ConnectionPipe class only on Windows') + self.close() + try: + self.handle = win32file.CreateFile( + r'\\.\pipe\livesplit', + win32file.GENERIC_READ | win32file.GENERIC_WRITE, + 0, + None, + win32file.OPEN_EXISTING, + 0, + None + ) + res = win32pipe.SetNamedPipeHandleState(self.handle, win32pipe.PIPE_READMODE_BYTE | win32pipe.PIPE_NOWAIT, None, None) + if res == 0: # errored + self.handle = None + return False + except pywintypes.error as e: + self.handle = None + if e.args[0] != 2: # 2 is unable to find the file -> don't spam the console with that + print('Pipe error: ' + str(e)) + return False + return True + + def close(self) -> None: + if sys.platform != "win32": + raise NotImplementedError('ConnectionPipe class only on Windows') + if self.handle: + win32file.CloseHandle(self.handle) + self.handle = None + + def send(self, msg: bytes) -> None: + if sys.platform != "win32": + raise NotImplementedError('ConnectionPipe class only on Windows') + try: + win32file.WriteFile(self.handle, msg + b"\r\n") + except Exception as e: + win32file.CloseHandle(self.handle) + self.handle = None + raise ConnectionError("Pipe sending error: " + str(e)) + + def receive(self) -> bytes: + if sys.platform != "win32": + raise NotImplementedError('ConnectionPipe class only on Windows') + try: + # wait a bit for data to arrive, the ReadFile would stall otherwise + time.sleep(0.05) + data_received = win32file.ReadFile(self.handle, BUFFER_SIZE) + # this is returned as tuple, only pass the data onwards + data_received = data_received[1] + except Exception as e: + win32file.CloseHandle(self.handle) + self.handle = None + raise ConnectionError("Pipe broken: " + str(e)) + return data_received From 0dbfa9719e5432574f8ba0462e8aca7b1aeda6cd Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 13:30:31 +0100 Subject: [PATCH 11/28] Remove unnecessary platform checks --- src/splitguides/livesplit_client/connection_windows.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/splitguides/livesplit_client/connection_windows.py b/src/splitguides/livesplit_client/connection_windows.py index 5afd71f..096cabc 100644 --- a/src/splitguides/livesplit_client/connection_windows.py +++ b/src/splitguides/livesplit_client/connection_windows.py @@ -18,8 +18,6 @@ class ConnectionPipe(ConnectionTypeBase): handle = None def connect(self) -> bool: - if sys.platform != "win32": - raise NotImplementedError('ConnectionPipe class only on Windows') self.close() try: self.handle = win32file.CreateFile( @@ -43,15 +41,11 @@ def connect(self) -> bool: return True def close(self) -> None: - if sys.platform != "win32": - raise NotImplementedError('ConnectionPipe class only on Windows') if self.handle: win32file.CloseHandle(self.handle) self.handle = None def send(self, msg: bytes) -> None: - if sys.platform != "win32": - raise NotImplementedError('ConnectionPipe class only on Windows') try: win32file.WriteFile(self.handle, msg + b"\r\n") except Exception as e: @@ -60,8 +54,6 @@ def send(self, msg: bytes) -> None: raise ConnectionError("Pipe sending error: " + str(e)) def receive(self) -> bytes: - if sys.platform != "win32": - raise NotImplementedError('ConnectionPipe class only on Windows') try: # wait a bit for data to arrive, the ReadFile would stall otherwise time.sleep(0.05) From 8376f282b570d894d4d7efafb3e613b952085455 Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 15:30:39 +0100 Subject: [PATCH 12/28] Update uv.lock --- uv.lock | 1072 +++++++++++++++++++++++++++---------------------------- 1 file changed, 536 insertions(+), 536 deletions(-) diff --git a/uv.lock b/uv.lock index d1ba17d..2354522 100644 --- a/uv.lock +++ b/uv.lock @@ -192,8 +192,8 @@ name = "dmgbuild" version = "1.6.7" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ds-store", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "mac-alias", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "ds-store" }, + { name = "mac-alias" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a7/a5/f4dbd63c96902de8f2427a82518aaeedac0006587409294e55a14e45f367/dmgbuild-1.6.7.tar.gz", hash = "sha256:676b17acd448899f6d4a83b2184e0657480444ecb6ac9c4922889efad9e5dbfb", size = 36938, upload-time = "2026-01-15T23:13:43.779Z" } wheels = [ @@ -205,7 +205,7 @@ name = "ds-store" version = "1.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "mac-alias", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "mac-alias" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e9/11/971e423750b219ec3f3a7f27dfb9bd74aef3d3fdfee6cc7df10a0217b5cd/ds_store-1.3.2.tar.gz", hash = "sha256:e4da49df901123481a85b9250945f2aac054a0f0c29352cd2cc858c536cdd364", size = 26574, upload-time = "2025-12-04T00:52:46.178Z" } wheels = [ @@ -503,167 +503,167 @@ name = "pyobjc" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-accessibility", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-accounts", marker = "(python_full_version != '3.13.*' and platform_release >= '12.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '12.0' and sys_platform == 'linux') or (platform_release >= '12.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-addressbook", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-adservices", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-adsupport", marker = "(python_full_version != '3.13.*' and platform_release >= '18.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '18.0' and sys_platform == 'linux') or (platform_release >= '18.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-applescriptkit", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-applescriptobjc", marker = "(python_full_version != '3.13.*' and platform_release >= '10.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '10.0' and sys_platform == 'linux') or (platform_release >= '10.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-applicationservices", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-apptrackingtransparency", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-arkit", marker = "(python_full_version != '3.13.*' and platform_release >= '25.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '25.0' and sys_platform == 'linux') or (platform_release >= '25.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-audiovideobridging", marker = "(python_full_version != '3.13.*' and platform_release >= '12.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '12.0' and sys_platform == 'linux') or (platform_release >= '12.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-authenticationservices", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-automaticassessmentconfiguration", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-automator", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-avfoundation", marker = "(python_full_version != '3.13.*' and platform_release >= '11.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '11.0' and sys_platform == 'linux') or (platform_release >= '11.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-avkit", marker = "(python_full_version != '3.13.*' and platform_release >= '13.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '13.0' and sys_platform == 'linux') or (platform_release >= '13.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-avrouting", marker = "(python_full_version != '3.13.*' and platform_release >= '22.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '22.0' and sys_platform == 'linux') or (platform_release >= '22.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-backgroundassets", marker = "(python_full_version != '3.13.*' and platform_release >= '22.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '22.0' and sys_platform == 'linux') or (platform_release >= '22.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-browserenginekit", marker = "(python_full_version != '3.13.*' and platform_release >= '23.4' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '23.4' and sys_platform == 'linux') or (platform_release >= '23.4' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-businesschat", marker = "(python_full_version != '3.13.*' and platform_release >= '18.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '18.0' and sys_platform == 'linux') or (platform_release >= '18.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-calendarstore", marker = "(python_full_version != '3.13.*' and platform_release >= '9.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '9.0' and sys_platform == 'linux') or (platform_release >= '9.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-callkit", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-carbon", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cfnetwork", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cinematic", marker = "(python_full_version != '3.13.*' and platform_release >= '23.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '23.0' and sys_platform == 'linux') or (platform_release >= '23.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-classkit", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cloudkit", marker = "(python_full_version != '3.13.*' and platform_release >= '14.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '14.0' and sys_platform == 'linux') or (platform_release >= '14.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-collaboration", marker = "(python_full_version != '3.13.*' and platform_release >= '9.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '9.0' and sys_platform == 'linux') or (platform_release >= '9.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-colorsync", marker = "(python_full_version != '3.13.*' and platform_release >= '17.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '17.0' and sys_platform == 'linux') or (platform_release >= '17.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-compositorservices", marker = "(python_full_version != '3.13.*' and platform_release >= '25.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '25.0' and sys_platform == 'linux') or (platform_release >= '25.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-contacts", marker = "(python_full_version != '3.13.*' and platform_release >= '15.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '15.0' and sys_platform == 'linux') or (platform_release >= '15.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-contactsui", marker = "(python_full_version != '3.13.*' and platform_release >= '15.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '15.0' and sys_platform == 'linux') or (platform_release >= '15.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coreaudio", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coreaudiokit", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-corebluetooth", marker = "(python_full_version != '3.13.*' and platform_release >= '14.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '14.0' and sys_platform == 'linux') or (platform_release >= '14.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coredata", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-corehaptics", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-corelocation", marker = "(python_full_version != '3.13.*' and platform_release >= '10.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '10.0' and sys_platform == 'linux') or (platform_release >= '10.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coremedia", marker = "(python_full_version != '3.13.*' and platform_release >= '11.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '11.0' and sys_platform == 'linux') or (platform_release >= '11.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coremediaio", marker = "(python_full_version != '3.13.*' and platform_release >= '11.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '11.0' and sys_platform == 'linux') or (platform_release >= '11.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coremidi", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coreml", marker = "(python_full_version != '3.13.*' and platform_release >= '17.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '17.0' and sys_platform == 'linux') or (platform_release >= '17.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coremotion", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coreservices", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-corespotlight", marker = "(python_full_version != '3.13.*' and platform_release >= '17.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '17.0' and sys_platform == 'linux') or (platform_release >= '17.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coretext", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-corewlan", marker = "(python_full_version != '3.13.*' and platform_release >= '10.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '10.0' and sys_platform == 'linux') or (platform_release >= '10.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cryptotokenkit", marker = "(python_full_version != '3.13.*' and platform_release >= '14.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '14.0' and sys_platform == 'linux') or (platform_release >= '14.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-datadetection", marker = "(python_full_version != '3.13.*' and platform_release >= '21.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '21.0' and sys_platform == 'linux') or (platform_release >= '21.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-devicecheck", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-devicediscoveryextension", marker = "(python_full_version != '3.13.*' and platform_release >= '24.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '24.0' and sys_platform == 'linux') or (platform_release >= '24.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-dictionaryservices", marker = "(python_full_version != '3.13.*' and platform_release >= '9.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '9.0' and sys_platform == 'linux') or (platform_release >= '9.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-discrecording", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-discrecordingui", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-diskarbitration", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-dvdplayback", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-eventkit", marker = "(python_full_version != '3.13.*' and platform_release >= '12.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '12.0' and sys_platform == 'linux') or (platform_release >= '12.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-exceptionhandling", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-executionpolicy", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-extensionkit", marker = "(python_full_version != '3.13.*' and platform_release >= '22.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '22.0' and sys_platform == 'linux') or (platform_release >= '22.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-externalaccessory", marker = "(python_full_version != '3.13.*' and platform_release >= '17.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '17.0' and sys_platform == 'linux') or (platform_release >= '17.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-fileprovider", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-fileproviderui", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-findersync", marker = "(python_full_version != '3.13.*' and platform_release >= '14.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '14.0' and sys_platform == 'linux') or (platform_release >= '14.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-fsevents", marker = "(python_full_version != '3.13.*' and platform_release >= '9.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '9.0' and sys_platform == 'linux') or (platform_release >= '9.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-fskit", marker = "(python_full_version != '3.13.*' and platform_release >= '24.4' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '24.4' and sys_platform == 'linux') or (platform_release >= '24.4' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-gamecenter", marker = "(python_full_version != '3.13.*' and platform_release >= '12.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '12.0' and sys_platform == 'linux') or (platform_release >= '12.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-gamecontroller", marker = "(python_full_version != '3.13.*' and platform_release >= '13.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '13.0' and sys_platform == 'linux') or (platform_release >= '13.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-gamekit", marker = "(python_full_version != '3.13.*' and platform_release >= '12.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '12.0' and sys_platform == 'linux') or (platform_release >= '12.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-gameplaykit", marker = "(python_full_version != '3.13.*' and platform_release >= '15.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '15.0' and sys_platform == 'linux') or (platform_release >= '15.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-gamesave", marker = "(python_full_version != '3.13.*' and platform_release >= '25.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '25.0' and sys_platform == 'linux') or (platform_release >= '25.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-healthkit", marker = "(python_full_version != '3.13.*' and platform_release >= '22.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '22.0' and sys_platform == 'linux') or (platform_release >= '22.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-imagecapturecore", marker = "(python_full_version != '3.13.*' and platform_release >= '10.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '10.0' and sys_platform == 'linux') or (platform_release >= '10.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-inputmethodkit", marker = "(python_full_version != '3.13.*' and platform_release >= '9.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '9.0' and sys_platform == 'linux') or (platform_release >= '9.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-installerplugins", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-instantmessage", marker = "(python_full_version != '3.13.*' and platform_release >= '9.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '9.0' and sys_platform == 'linux') or (platform_release >= '9.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-intents", marker = "(python_full_version != '3.13.*' and platform_release >= '16.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '16.0' and sys_platform == 'linux') or (platform_release >= '16.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-intentsui", marker = "(python_full_version != '3.13.*' and platform_release >= '21.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '21.0' and sys_platform == 'linux') or (platform_release >= '21.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-iobluetooth", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-iobluetoothui", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-iosurface", marker = "(python_full_version != '3.13.*' and platform_release >= '10.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '10.0' and sys_platform == 'linux') or (platform_release >= '10.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-ituneslibrary", marker = "(python_full_version != '3.13.*' and platform_release >= '10.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '10.0' and sys_platform == 'linux') or (platform_release >= '10.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-kernelmanagement", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-latentsemanticmapping", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-launchservices", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-libdispatch", marker = "(python_full_version != '3.13.*' and platform_release >= '12.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '12.0' and sys_platform == 'linux') or (platform_release >= '12.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-libxpc", marker = "(python_full_version != '3.13.*' and platform_release >= '12.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '12.0' and sys_platform == 'linux') or (platform_release >= '12.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-linkpresentation", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-localauthentication", marker = "(python_full_version != '3.13.*' and platform_release >= '14.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '14.0' and sys_platform == 'linux') or (platform_release >= '14.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-localauthenticationembeddedui", marker = "(python_full_version != '3.13.*' and platform_release >= '21.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '21.0' and sys_platform == 'linux') or (platform_release >= '21.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-mailkit", marker = "(python_full_version != '3.13.*' and platform_release >= '21.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '21.0' and sys_platform == 'linux') or (platform_release >= '21.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-mapkit", marker = "(python_full_version != '3.13.*' and platform_release >= '13.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '13.0' and sys_platform == 'linux') or (platform_release >= '13.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-mediaaccessibility", marker = "(python_full_version != '3.13.*' and platform_release >= '13.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '13.0' and sys_platform == 'linux') or (platform_release >= '13.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-mediaextension", marker = "(python_full_version != '3.13.*' and platform_release >= '24.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '24.0' and sys_platform == 'linux') or (platform_release >= '24.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-medialibrary", marker = "(python_full_version != '3.13.*' and platform_release >= '13.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '13.0' and sys_platform == 'linux') or (platform_release >= '13.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-mediaplayer", marker = "(python_full_version != '3.13.*' and platform_release >= '16.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '16.0' and sys_platform == 'linux') or (platform_release >= '16.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-mediatoolbox", marker = "(python_full_version != '3.13.*' and platform_release >= '13.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '13.0' and sys_platform == 'linux') or (platform_release >= '13.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metal", marker = "(python_full_version != '3.13.*' and platform_release >= '15.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '15.0' and sys_platform == 'linux') or (platform_release >= '15.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metalfx", marker = "(python_full_version != '3.13.*' and platform_release >= '22.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '22.0' and sys_platform == 'linux') or (platform_release >= '22.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metalkit", marker = "(python_full_version != '3.13.*' and platform_release >= '15.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '15.0' and sys_platform == 'linux') or (platform_release >= '15.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metalperformanceshaders", marker = "(python_full_version != '3.13.*' and platform_release >= '17.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '17.0' and sys_platform == 'linux') or (platform_release >= '17.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metalperformanceshadersgraph", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metrickit", marker = "(python_full_version != '3.13.*' and platform_release >= '21.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '21.0' and sys_platform == 'linux') or (platform_release >= '21.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-mlcompute", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-modelio", marker = "(python_full_version != '3.13.*' and platform_release >= '15.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '15.0' and sys_platform == 'linux') or (platform_release >= '15.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-multipeerconnectivity", marker = "(python_full_version != '3.13.*' and platform_release >= '14.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '14.0' and sys_platform == 'linux') or (platform_release >= '14.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-naturallanguage", marker = "(python_full_version != '3.13.*' and platform_release >= '18.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '18.0' and sys_platform == 'linux') or (platform_release >= '18.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-netfs", marker = "(python_full_version != '3.13.*' and platform_release >= '10.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '10.0' and sys_platform == 'linux') or (platform_release >= '10.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-network", marker = "(python_full_version != '3.13.*' and platform_release >= '18.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '18.0' and sys_platform == 'linux') or (platform_release >= '18.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-networkextension", marker = "(python_full_version != '3.13.*' and platform_release >= '15.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '15.0' and sys_platform == 'linux') or (platform_release >= '15.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-notificationcenter", marker = "(python_full_version != '3.13.*' and platform_release >= '14.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '14.0' and sys_platform == 'linux') or (platform_release >= '14.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-opendirectory", marker = "(python_full_version != '3.13.*' and platform_release >= '10.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '10.0' and sys_platform == 'linux') or (platform_release >= '10.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-osakit", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-oslog", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-passkit", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-pencilkit", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-phase", marker = "(python_full_version != '3.13.*' and platform_release >= '21.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '21.0' and sys_platform == 'linux') or (platform_release >= '21.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-photos", marker = "(python_full_version != '3.13.*' and platform_release >= '15.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '15.0' and sys_platform == 'linux') or (platform_release >= '15.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-photosui", marker = "(python_full_version != '3.13.*' and platform_release >= '15.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '15.0' and sys_platform == 'linux') or (platform_release >= '15.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-preferencepanes", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-pushkit", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quicklookthumbnailing", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-replaykit", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-safariservices", marker = "(python_full_version != '3.13.*' and platform_release >= '16.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '16.0' and sys_platform == 'linux') or (platform_release >= '16.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-safetykit", marker = "(python_full_version != '3.13.*' and platform_release >= '22.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '22.0' and sys_platform == 'linux') or (platform_release >= '22.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-scenekit", marker = "(python_full_version != '3.13.*' and platform_release >= '11.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '11.0' and sys_platform == 'linux') or (platform_release >= '11.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-screencapturekit", marker = "(python_full_version != '3.13.*' and platform_release >= '21.4' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '21.4' and sys_platform == 'linux') or (platform_release >= '21.4' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-screensaver", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-screentime", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-scriptingbridge", marker = "(python_full_version != '3.13.*' and platform_release >= '9.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '9.0' and sys_platform == 'linux') or (platform_release >= '9.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-searchkit", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-security", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-securityfoundation", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-securityinterface", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-securityui", marker = "(python_full_version != '3.13.*' and platform_release >= '24.4' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '24.4' and sys_platform == 'linux') or (platform_release >= '24.4' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-sensitivecontentanalysis", marker = "(python_full_version != '3.13.*' and platform_release >= '23.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '23.0' and sys_platform == 'linux') or (platform_release >= '23.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-servicemanagement", marker = "(python_full_version != '3.13.*' and platform_release >= '10.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '10.0' and sys_platform == 'linux') or (platform_release >= '10.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-sharedwithyou", marker = "(python_full_version != '3.13.*' and platform_release >= '22.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '22.0' and sys_platform == 'linux') or (platform_release >= '22.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-sharedwithyoucore", marker = "(python_full_version != '3.13.*' and platform_release >= '22.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '22.0' and sys_platform == 'linux') or (platform_release >= '22.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-shazamkit", marker = "(python_full_version != '3.13.*' and platform_release >= '21.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '21.0' and sys_platform == 'linux') or (platform_release >= '21.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-social", marker = "(python_full_version != '3.13.*' and platform_release >= '12.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '12.0' and sys_platform == 'linux') or (platform_release >= '12.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-soundanalysis", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-speech", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-spritekit", marker = "(python_full_version != '3.13.*' and platform_release >= '13.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '13.0' and sys_platform == 'linux') or (platform_release >= '13.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-storekit", marker = "(python_full_version != '3.13.*' and platform_release >= '11.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '11.0' and sys_platform == 'linux') or (platform_release >= '11.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-symbols", marker = "(python_full_version != '3.13.*' and platform_release >= '23.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '23.0' and sys_platform == 'linux') or (platform_release >= '23.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-syncservices", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-systemconfiguration", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-systemextensions", marker = "(python_full_version != '3.13.*' and platform_release >= '19.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '19.0' and sys_platform == 'linux') or (platform_release >= '19.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-threadnetwork", marker = "(python_full_version != '3.13.*' and platform_release >= '22.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '22.0' and sys_platform == 'linux') or (platform_release >= '22.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-uniformtypeidentifiers", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-usernotifications", marker = "(python_full_version != '3.13.*' and platform_release >= '18.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '18.0' and sys_platform == 'linux') or (platform_release >= '18.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-usernotificationsui", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-videosubscriberaccount", marker = "(python_full_version != '3.13.*' and platform_release >= '18.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '18.0' and sys_platform == 'linux') or (platform_release >= '18.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-videotoolbox", marker = "(python_full_version != '3.13.*' and platform_release >= '12.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '12.0' and sys_platform == 'linux') or (platform_release >= '12.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-virtualization", marker = "(python_full_version != '3.13.*' and platform_release >= '20.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '20.0' and sys_platform == 'linux') or (platform_release >= '20.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-vision", marker = "(python_full_version != '3.13.*' and platform_release >= '17.0' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and platform_release >= '17.0' and sys_platform == 'linux') or (platform_release >= '17.0' and sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-webkit", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-accessibility", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-accounts", marker = "platform_release >= '12.0'" }, + { name = "pyobjc-framework-addressbook" }, + { name = "pyobjc-framework-adservices", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-adsupport", marker = "platform_release >= '18.0'" }, + { name = "pyobjc-framework-applescriptkit" }, + { name = "pyobjc-framework-applescriptobjc", marker = "platform_release >= '10.0'" }, + { name = "pyobjc-framework-applicationservices" }, + { name = "pyobjc-framework-apptrackingtransparency", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-arkit", marker = "platform_release >= '25.0'" }, + { name = "pyobjc-framework-audiovideobridging", marker = "platform_release >= '12.0'" }, + { name = "pyobjc-framework-authenticationservices", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-automaticassessmentconfiguration", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-automator" }, + { name = "pyobjc-framework-avfoundation", marker = "platform_release >= '11.0'" }, + { name = "pyobjc-framework-avkit", marker = "platform_release >= '13.0'" }, + { name = "pyobjc-framework-avrouting", marker = "platform_release >= '22.0'" }, + { name = "pyobjc-framework-backgroundassets", marker = "platform_release >= '22.0'" }, + { name = "pyobjc-framework-browserenginekit", marker = "platform_release >= '23.4'" }, + { name = "pyobjc-framework-businesschat", marker = "platform_release >= '18.0'" }, + { name = "pyobjc-framework-calendarstore", marker = "platform_release >= '9.0'" }, + { name = "pyobjc-framework-callkit", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-carbon" }, + { name = "pyobjc-framework-cfnetwork" }, + { name = "pyobjc-framework-cinematic", marker = "platform_release >= '23.0'" }, + { name = "pyobjc-framework-classkit", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-cloudkit", marker = "platform_release >= '14.0'" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-collaboration", marker = "platform_release >= '9.0'" }, + { name = "pyobjc-framework-colorsync", marker = "platform_release >= '17.0'" }, + { name = "pyobjc-framework-compositorservices", marker = "platform_release >= '25.0'" }, + { name = "pyobjc-framework-contacts", marker = "platform_release >= '15.0'" }, + { name = "pyobjc-framework-contactsui", marker = "platform_release >= '15.0'" }, + { name = "pyobjc-framework-coreaudio" }, + { name = "pyobjc-framework-coreaudiokit" }, + { name = "pyobjc-framework-corebluetooth", marker = "platform_release >= '14.0'" }, + { name = "pyobjc-framework-coredata" }, + { name = "pyobjc-framework-corehaptics", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-corelocation", marker = "platform_release >= '10.0'" }, + { name = "pyobjc-framework-coremedia", marker = "platform_release >= '11.0'" }, + { name = "pyobjc-framework-coremediaio", marker = "platform_release >= '11.0'" }, + { name = "pyobjc-framework-coremidi" }, + { name = "pyobjc-framework-coreml", marker = "platform_release >= '17.0'" }, + { name = "pyobjc-framework-coremotion", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-coreservices" }, + { name = "pyobjc-framework-corespotlight", marker = "platform_release >= '17.0'" }, + { name = "pyobjc-framework-coretext" }, + { name = "pyobjc-framework-corewlan", marker = "platform_release >= '10.0'" }, + { name = "pyobjc-framework-cryptotokenkit", marker = "platform_release >= '14.0'" }, + { name = "pyobjc-framework-datadetection", marker = "platform_release >= '21.0'" }, + { name = "pyobjc-framework-devicecheck", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-devicediscoveryextension", marker = "platform_release >= '24.0'" }, + { name = "pyobjc-framework-dictionaryservices", marker = "platform_release >= '9.0'" }, + { name = "pyobjc-framework-discrecording" }, + { name = "pyobjc-framework-discrecordingui" }, + { name = "pyobjc-framework-diskarbitration" }, + { name = "pyobjc-framework-dvdplayback" }, + { name = "pyobjc-framework-eventkit", marker = "platform_release >= '12.0'" }, + { name = "pyobjc-framework-exceptionhandling" }, + { name = "pyobjc-framework-executionpolicy", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-extensionkit", marker = "platform_release >= '22.0'" }, + { name = "pyobjc-framework-externalaccessory", marker = "platform_release >= '17.0'" }, + { name = "pyobjc-framework-fileprovider", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-fileproviderui", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-findersync", marker = "platform_release >= '14.0'" }, + { name = "pyobjc-framework-fsevents", marker = "platform_release >= '9.0'" }, + { name = "pyobjc-framework-fskit", marker = "platform_release >= '24.4'" }, + { name = "pyobjc-framework-gamecenter", marker = "platform_release >= '12.0'" }, + { name = "pyobjc-framework-gamecontroller", marker = "platform_release >= '13.0'" }, + { name = "pyobjc-framework-gamekit", marker = "platform_release >= '12.0'" }, + { name = "pyobjc-framework-gameplaykit", marker = "platform_release >= '15.0'" }, + { name = "pyobjc-framework-gamesave", marker = "platform_release >= '25.0'" }, + { name = "pyobjc-framework-healthkit", marker = "platform_release >= '22.0'" }, + { name = "pyobjc-framework-imagecapturecore", marker = "platform_release >= '10.0'" }, + { name = "pyobjc-framework-inputmethodkit", marker = "platform_release >= '9.0'" }, + { name = "pyobjc-framework-installerplugins" }, + { name = "pyobjc-framework-instantmessage", marker = "platform_release >= '9.0'" }, + { name = "pyobjc-framework-intents", marker = "platform_release >= '16.0'" }, + { name = "pyobjc-framework-intentsui", marker = "platform_release >= '21.0'" }, + { name = "pyobjc-framework-iobluetooth" }, + { name = "pyobjc-framework-iobluetoothui" }, + { name = "pyobjc-framework-iosurface", marker = "platform_release >= '10.0'" }, + { name = "pyobjc-framework-ituneslibrary", marker = "platform_release >= '10.0'" }, + { name = "pyobjc-framework-kernelmanagement", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-latentsemanticmapping" }, + { name = "pyobjc-framework-launchservices" }, + { name = "pyobjc-framework-libdispatch", marker = "platform_release >= '12.0'" }, + { name = "pyobjc-framework-libxpc", marker = "platform_release >= '12.0'" }, + { name = "pyobjc-framework-linkpresentation", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-localauthentication", marker = "platform_release >= '14.0'" }, + { name = "pyobjc-framework-localauthenticationembeddedui", marker = "platform_release >= '21.0'" }, + { name = "pyobjc-framework-mailkit", marker = "platform_release >= '21.0'" }, + { name = "pyobjc-framework-mapkit", marker = "platform_release >= '13.0'" }, + { name = "pyobjc-framework-mediaaccessibility", marker = "platform_release >= '13.0'" }, + { name = "pyobjc-framework-mediaextension", marker = "platform_release >= '24.0'" }, + { name = "pyobjc-framework-medialibrary", marker = "platform_release >= '13.0'" }, + { name = "pyobjc-framework-mediaplayer", marker = "platform_release >= '16.0'" }, + { name = "pyobjc-framework-mediatoolbox", marker = "platform_release >= '13.0'" }, + { name = "pyobjc-framework-metal", marker = "platform_release >= '15.0'" }, + { name = "pyobjc-framework-metalfx", marker = "platform_release >= '22.0'" }, + { name = "pyobjc-framework-metalkit", marker = "platform_release >= '15.0'" }, + { name = "pyobjc-framework-metalperformanceshaders", marker = "platform_release >= '17.0'" }, + { name = "pyobjc-framework-metalperformanceshadersgraph", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-metrickit", marker = "platform_release >= '21.0'" }, + { name = "pyobjc-framework-mlcompute", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-modelio", marker = "platform_release >= '15.0'" }, + { name = "pyobjc-framework-multipeerconnectivity", marker = "platform_release >= '14.0'" }, + { name = "pyobjc-framework-naturallanguage", marker = "platform_release >= '18.0'" }, + { name = "pyobjc-framework-netfs", marker = "platform_release >= '10.0'" }, + { name = "pyobjc-framework-network", marker = "platform_release >= '18.0'" }, + { name = "pyobjc-framework-networkextension", marker = "platform_release >= '15.0'" }, + { name = "pyobjc-framework-notificationcenter", marker = "platform_release >= '14.0'" }, + { name = "pyobjc-framework-opendirectory", marker = "platform_release >= '10.0'" }, + { name = "pyobjc-framework-osakit" }, + { name = "pyobjc-framework-oslog", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-passkit", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-pencilkit", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-phase", marker = "platform_release >= '21.0'" }, + { name = "pyobjc-framework-photos", marker = "platform_release >= '15.0'" }, + { name = "pyobjc-framework-photosui", marker = "platform_release >= '15.0'" }, + { name = "pyobjc-framework-preferencepanes" }, + { name = "pyobjc-framework-pushkit", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-quartz" }, + { name = "pyobjc-framework-quicklookthumbnailing", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-replaykit", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-safariservices", marker = "platform_release >= '16.0'" }, + { name = "pyobjc-framework-safetykit", marker = "platform_release >= '22.0'" }, + { name = "pyobjc-framework-scenekit", marker = "platform_release >= '11.0'" }, + { name = "pyobjc-framework-screencapturekit", marker = "platform_release >= '21.4'" }, + { name = "pyobjc-framework-screensaver" }, + { name = "pyobjc-framework-screentime", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-scriptingbridge", marker = "platform_release >= '9.0'" }, + { name = "pyobjc-framework-searchkit" }, + { name = "pyobjc-framework-security" }, + { name = "pyobjc-framework-securityfoundation" }, + { name = "pyobjc-framework-securityinterface" }, + { name = "pyobjc-framework-securityui", marker = "platform_release >= '24.4'" }, + { name = "pyobjc-framework-sensitivecontentanalysis", marker = "platform_release >= '23.0'" }, + { name = "pyobjc-framework-servicemanagement", marker = "platform_release >= '10.0'" }, + { name = "pyobjc-framework-sharedwithyou", marker = "platform_release >= '22.0'" }, + { name = "pyobjc-framework-sharedwithyoucore", marker = "platform_release >= '22.0'" }, + { name = "pyobjc-framework-shazamkit", marker = "platform_release >= '21.0'" }, + { name = "pyobjc-framework-social", marker = "platform_release >= '12.0'" }, + { name = "pyobjc-framework-soundanalysis", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-speech", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-spritekit", marker = "platform_release >= '13.0'" }, + { name = "pyobjc-framework-storekit", marker = "platform_release >= '11.0'" }, + { name = "pyobjc-framework-symbols", marker = "platform_release >= '23.0'" }, + { name = "pyobjc-framework-syncservices" }, + { name = "pyobjc-framework-systemconfiguration" }, + { name = "pyobjc-framework-systemextensions", marker = "platform_release >= '19.0'" }, + { name = "pyobjc-framework-threadnetwork", marker = "platform_release >= '22.0'" }, + { name = "pyobjc-framework-uniformtypeidentifiers", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-usernotifications", marker = "platform_release >= '18.0'" }, + { name = "pyobjc-framework-usernotificationsui", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-videosubscriberaccount", marker = "platform_release >= '18.0'" }, + { name = "pyobjc-framework-videotoolbox", marker = "platform_release >= '12.0'" }, + { name = "pyobjc-framework-virtualization", marker = "platform_release >= '20.0'" }, + { name = "pyobjc-framework-vision", marker = "platform_release >= '17.0'" }, + { name = "pyobjc-framework-webkit" }, ] sdist = { url = "https://files.pythonhosted.org/packages/17/06/d77639ba166cc09aed2d32ae204811b47bc5d40e035cdc9bff7fff72ec5f/pyobjc-12.1.tar.gz", hash = "sha256:686d6db3eb3182fac9846b8ce3eedf4c7d2680b21b8b8d6e6df054a17e92a12d", size = 11345, upload-time = "2025-11-14T10:07:28.155Z" } wheels = [ @@ -688,9 +688,9 @@ name = "pyobjc-framework-accessibility" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2d/87/8ca40428d05a668fecc638f2f47dba86054dbdc35351d247f039749de955/pyobjc_framework_accessibility-12.1.tar.gz", hash = "sha256:5ff362c3425edc242d49deec11f5f3e26e565cefb6a2872eda59ab7362149772", size = 29800, upload-time = "2025-11-14T10:08:31.949Z" } wheels = [ @@ -706,8 +706,8 @@ name = "pyobjc-framework-accounts" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/65/10/f6fe336c7624d6753c1f6edac102310ce4434d49b548c479e8e6420d4024/pyobjc_framework_accounts-12.1.tar.gz", hash = "sha256:76d62c5e7b831eb8f4c9ca6abaf79d9ed961dfffe24d89a041fb1de97fe56a3e", size = 15202, upload-time = "2025-11-14T10:08:33.995Z" } wheels = [ @@ -719,8 +719,8 @@ name = "pyobjc-framework-addressbook" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/18/28/0404af2a1c6fa8fd266df26fb6196a8f3fb500d6fe3dab94701949247bea/pyobjc_framework_addressbook-12.1.tar.gz", hash = "sha256:c48b740cf981103cef1743d0804a226d86481fcb839bd84b80e9a586187e8000", size = 44359, upload-time = "2025-11-14T10:08:37.687Z" } wheels = [ @@ -736,8 +736,8 @@ name = "pyobjc-framework-adservices" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/19/04/1c3d3e0a1ac981664f30b33407dcdf8956046ecde6abc88832cf2aa535f4/pyobjc_framework_adservices-12.1.tar.gz", hash = "sha256:7a31fc8d5c6fd58f012db87c89ba581361fc905114bfb912e0a3a87475c02183", size = 11793, upload-time = "2025-11-14T10:08:39.56Z" } wheels = [ @@ -749,8 +749,8 @@ name = "pyobjc-framework-adsupport" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/43/77/f26a2e9994d4df32e9b3680c8014e350b0f1c78d7673b3eba9de2e04816f/pyobjc_framework_adsupport-12.1.tar.gz", hash = "sha256:9a68480e76de567c339dca29a8c739d6d7b5cad30e1cd585ff6e49ec2fc283dd", size = 11645, upload-time = "2025-11-14T10:08:41.439Z" } wheels = [ @@ -762,8 +762,8 @@ name = "pyobjc-framework-applescriptkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/f1/e0c07b2a9eb98f1a2050f153d287a52a92f873eeddb41b74c52c144d8767/pyobjc_framework_applescriptkit-12.1.tar.gz", hash = "sha256:cb09f88cf0ad9753dedc02720065818f854b50e33eb4194f0ea34de6d7a3eb33", size = 11451, upload-time = "2025-11-14T10:08:43.328Z" } wheels = [ @@ -775,8 +775,8 @@ name = "pyobjc-framework-applescriptobjc" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c0/4b/e4d1592207cbe17355e01828bdd11dd58f31356108f6a49f5e0484a5df50/pyobjc_framework_applescriptobjc-12.1.tar.gz", hash = "sha256:dce080ed07409b0dda2fee75d559bd312ea1ef0243a4338606440f282a6a0f5f", size = 11588, upload-time = "2025-11-14T10:08:45.037Z" } wheels = [ @@ -788,10 +788,10 @@ name = "pyobjc-framework-applicationservices" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coretext", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coretext" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/be/6a/d4e613c8e926a5744fc47a9e9fea08384a510dc4f27d844f7ad7a2d793bd/pyobjc_framework_applicationservices-12.1.tar.gz", hash = "sha256:c06abb74f119bc27aeb41bf1aef8102c0ae1288aec1ac8665ea186a067a8945b", size = 103247, upload-time = "2025-11-14T10:08:52.18Z" } wheels = [ @@ -807,8 +807,8 @@ name = "pyobjc-framework-apptrackingtransparency" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0d/de/f24348982ecab0cb13067c348fc5fbc882c60d704ca290bada9a2b3e594b/pyobjc_framework_apptrackingtransparency-12.1.tar.gz", hash = "sha256:e25bf4e4dfa2d929993ee8e852b28fdf332fa6cde0a33328fdc3b2f502fa50ec", size = 12407, upload-time = "2025-11-14T10:08:54.118Z" } wheels = [ @@ -820,8 +820,8 @@ name = "pyobjc-framework-arkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c9/8b/843fe08e696bca8e7fc129344965ab6280f8336f64f01ba0a8862d219c3f/pyobjc_framework_arkit-12.1.tar.gz", hash = "sha256:0c5c6b702926179700b68ba29b8247464c3b609fd002a07a3308e72cfa953adf", size = 35814, upload-time = "2025-11-14T10:08:57.55Z" } wheels = [ @@ -833,8 +833,8 @@ name = "pyobjc-framework-audiovideobridging" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9f/51/f81581e7a3c5cb6c9254c6f1e1ee1d614930493761dec491b5b0d49544b9/pyobjc_framework_audiovideobridging-12.1.tar.gz", hash = "sha256:6230ace6bec1f38e8a727c35d054a7be54e039b3053f98e6dd8d08d6baee2625", size = 38457, upload-time = "2025-11-14T10:09:01.122Z" } wheels = [ @@ -850,8 +850,8 @@ name = "pyobjc-framework-authenticationservices" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6c/18/86218de3bf67fc1d810065f353d9df70c740de567ebee8550d476cb23862/pyobjc_framework_authenticationservices-12.1.tar.gz", hash = "sha256:cef71faeae2559f5c0ff9a81c9ceea1c81108e2f4ec7de52a98c269feff7a4b6", size = 58683, upload-time = "2025-11-14T10:09:06.003Z" } wheels = [ @@ -867,8 +867,8 @@ name = "pyobjc-framework-automaticassessmentconfiguration" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e4/24/080afe8189c47c4bb3daa191ccfd962400ca31a67c14b0f7c2d002c2e249/pyobjc_framework_automaticassessmentconfiguration-12.1.tar.gz", hash = "sha256:2b732c02d9097682ca16e48f5d3b10056b740bc091e217ee4d5715194c8970b1", size = 21895, upload-time = "2025-11-14T10:09:08.779Z" } wheels = [ @@ -884,8 +884,8 @@ name = "pyobjc-framework-automator" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7e/08/362bf6ac2bba393c46cf56078d4578b692b56857c385e47690637a72f0dd/pyobjc_framework_automator-12.1.tar.gz", hash = "sha256:7491a99347bb30da3a3f744052a03434ee29bee3e2ae520576f7e796740e4ba7", size = 186068, upload-time = "2025-11-14T10:09:20.82Z" } wheels = [ @@ -901,11 +901,11 @@ name = "pyobjc-framework-avfoundation" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coreaudio", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coremedia", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coreaudio" }, + { name = "pyobjc-framework-coremedia" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/42/c026ab308edc2ed5582d8b4b93da6b15d1b6557c0086914a4aabedd1f032/pyobjc_framework_avfoundation-12.1.tar.gz", hash = "sha256:eda0bb60be380f9ba2344600c4231dd58a3efafa99fdc65d3673ecfbb83f6fcb", size = 310047, upload-time = "2025-11-14T10:09:40.069Z" } wheels = [ @@ -921,9 +921,9 @@ name = "pyobjc-framework-avkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/34/a9/e44db1a1f26e2882c140f1d502d508b1f240af9048909dcf1e1a687375b4/pyobjc_framework_avkit-12.1.tar.gz", hash = "sha256:a5c0ddb0cb700f9b09c8afeca2c58952d554139e9bb078236d2355b1fddfb588", size = 28473, upload-time = "2025-11-14T10:09:43.105Z" } wheels = [ @@ -939,8 +939,8 @@ name = "pyobjc-framework-avrouting" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6e/83/15bf6c28ec100dae7f92d37c9e117b3b4ee6b4873db062833e16f1cfd6c4/pyobjc_framework_avrouting-12.1.tar.gz", hash = "sha256:6a6c5e583d14f6501df530a9d0559a32269a821fc8140e3646015f097155cd1c", size = 20031, upload-time = "2025-11-14T10:09:45.701Z" } wheels = [ @@ -956,8 +956,8 @@ name = "pyobjc-framework-backgroundassets" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/34/d1/e917fba82790495152fd3508c5053827658881cf7e9887ba60def5e3f221/pyobjc_framework_backgroundassets-12.1.tar.gz", hash = "sha256:8da34df9ae4519c360c429415477fdaf3fbba5addbc647b3340b8783454eb419", size = 26210, upload-time = "2025-11-14T10:09:48.792Z" } wheels = [ @@ -973,11 +973,11 @@ name = "pyobjc-framework-browserenginekit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coreaudio", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coremedia", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coreaudio" }, + { name = "pyobjc-framework-coremedia" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5d/b9/39f9de1730e6f8e73be0e4f0c6087cd9439cbe11645b8052d22e1fb8e69b/pyobjc_framework_browserenginekit-12.1.tar.gz", hash = "sha256:6a1a34a155778ab55ab5f463e885f2a3b4680231264e1fe078e62ddeccce49ed", size = 29120, upload-time = "2025-11-14T10:09:51.582Z" } wheels = [ @@ -993,8 +993,8 @@ name = "pyobjc-framework-businesschat" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4d/da/bc09b6ed19e9ea38ecca9387c291ca11fa680a8132d82b27030f82551c23/pyobjc_framework_businesschat-12.1.tar.gz", hash = "sha256:f6fa3a8369a1a51363e1757530128741d9d09ed90692a1d6777a4c0fbad25868", size = 12055, upload-time = "2025-11-14T10:09:53.436Z" } wheels = [ @@ -1006,8 +1006,8 @@ name = "pyobjc-framework-calendarstore" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/88/41/ae955d1c44dcc18b5b9df45c679e9a08311a0f853b9d981bca760cf1eef2/pyobjc_framework_calendarstore-12.1.tar.gz", hash = "sha256:f9a798d560a3c99ad4c0d2af68767bc5695d8b1aabef04d8377861cd1d6d1670", size = 52272, upload-time = "2025-11-14T10:09:58.48Z" } wheels = [ @@ -1019,8 +1019,8 @@ name = "pyobjc-framework-callkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1a/c0/1859d4532d39254df085309aff55b85323576f00a883626325af40da4653/pyobjc_framework_callkit-12.1.tar.gz", hash = "sha256:fd6dc9688b785aab360139d683be56f0844bf68bf5e45d0eb770cb68221083cc", size = 29171, upload-time = "2025-11-14T10:10:01.336Z" } wheels = [ @@ -1036,8 +1036,8 @@ name = "pyobjc-framework-carbon" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0c/0f/9ab8e518a4e5ac4a1e2fdde38a054c32aef82787ff7f30927345c18b7765/pyobjc_framework_carbon-12.1.tar.gz", hash = "sha256:57a72807db252d5746caccc46da4bd20ff8ea9e82109af9f72735579645ff4f0", size = 37293, upload-time = "2025-11-14T10:10:04.464Z" } wheels = [ @@ -1049,8 +1049,8 @@ name = "pyobjc-framework-cfnetwork" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d2/6a/f5f0f191956e187db85312cbffcc41bf863670d121b9190b4a35f0d36403/pyobjc_framework_cfnetwork-12.1.tar.gz", hash = "sha256:2d16e820f2d43522c793f55833fda89888139d7a84ca5758548ba1f3a325a88d", size = 44383, upload-time = "2025-11-14T10:10:08.428Z" } wheels = [ @@ -1066,11 +1066,11 @@ name = "pyobjc-framework-cinematic" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-avfoundation", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coremedia", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metal", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-avfoundation" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coremedia" }, + { name = "pyobjc-framework-metal" }, ] sdist = { url = "https://files.pythonhosted.org/packages/67/4e/f4cc7f9f7f66df0290c90fe445f1ff5aa514c6634f5203fe049161053716/pyobjc_framework_cinematic-12.1.tar.gz", hash = "sha256:795068c30447548c0e8614e9c432d4b288b13d5614622ef2f9e3246132329b06", size = 21215, upload-time = "2025-11-14T10:10:10.795Z" } wheels = [ @@ -1082,8 +1082,8 @@ name = "pyobjc-framework-classkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ac/ef/67815278023b344a79c7e95f748f647245d6f5305136fc80615254ad447c/pyobjc_framework_classkit-12.1.tar.gz", hash = "sha256:8d1e9dd75c3d14938ff533d88b72bca2d34918e4461f418ea323bfb2498473b4", size = 26298, upload-time = "2025-11-14T10:10:13.406Z" } wheels = [ @@ -1099,11 +1099,11 @@ name = "pyobjc-framework-cloudkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-accounts", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coredata", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-corelocation", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-accounts" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coredata" }, + { name = "pyobjc-framework-corelocation" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2d/09/762ee4f3ae8568b8e0e5392c705bc4aa1929aa454646c124ca470f1bf9fc/pyobjc_framework_cloudkit-12.1.tar.gz", hash = "sha256:1dddd38e60863f88adb3d1d37d3b4ccb9cbff48c4ef02ab50e36fa40c2379d2f", size = 53730, upload-time = "2025-11-14T10:10:17.831Z" } wheels = [ @@ -1115,7 +1115,7 @@ name = "pyobjc-framework-cocoa" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, ] sdist = { url = "https://files.pythonhosted.org/packages/02/a3/16ca9a15e77c061a9250afbae2eae26f2e1579eb8ca9462ae2d2c71e1169/pyobjc_framework_cocoa-12.1.tar.gz", hash = "sha256:5556c87db95711b985d5efdaaf01c917ddd41d148b1e52a0c66b1a2e2c5c1640", size = 2772191, upload-time = "2025-11-14T10:13:02.069Z" } wheels = [ @@ -1131,8 +1131,8 @@ name = "pyobjc-framework-collaboration" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/64/21/77fe64b39eae98412de1a0d33e9c735aa9949d53fff6b2d81403572b410b/pyobjc_framework_collaboration-12.1.tar.gz", hash = "sha256:2afa264d3233fc0a03a56789c6fefe655ffd81a2da4ba1dc79ea0c45931ad47b", size = 14299, upload-time = "2025-11-14T10:13:04.631Z" } wheels = [ @@ -1144,8 +1144,8 @@ name = "pyobjc-framework-colorsync" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c0/b4/706e4cc9db25b400201fc90f3edfaa1ab2d51b400b19437b043a68532078/pyobjc_framework_colorsync-12.1.tar.gz", hash = "sha256:d69dab7df01245a8c1bd536b9231c97993a5d1a2765d77692ce40ebbe6c1b8e9", size = 25269, upload-time = "2025-11-14T10:13:07.522Z" } wheels = [ @@ -1157,9 +1157,9 @@ name = "pyobjc-framework-compositorservices" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metal", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-metal" }, ] sdist = { url = "https://files.pythonhosted.org/packages/54/c5/0ba31d7af7e464b7f7ece8c2bd09112bdb0b7260848402e79ba6aacc622c/pyobjc_framework_compositorservices-12.1.tar.gz", hash = "sha256:028e357bbee7fbd3723339a321bbe14e6da5a772708a661a13eea5f17c89e4ab", size = 23292, upload-time = "2025-11-14T10:13:10.392Z" } wheels = [ @@ -1171,8 +1171,8 @@ name = "pyobjc-framework-contacts" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4b/a0/ce0542d211d4ea02f5cbcf72ee0a16b66b0d477a4ba5c32e00117703f2f0/pyobjc_framework_contacts-12.1.tar.gz", hash = "sha256:89bca3c5cf31404b714abaa1673577e1aaad6f2ef49d4141c6dbcc0643a789ad", size = 42378, upload-time = "2025-11-14T10:13:14.203Z" } wheels = [ @@ -1188,9 +1188,9 @@ name = "pyobjc-framework-contactsui" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-contacts", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-contacts" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/0c/7bb7f898456a81d88d06a1084a42e374519d2e40a668a872b69b11f8c1f9/pyobjc_framework_contactsui-12.1.tar.gz", hash = "sha256:aaeca7c9e0c9c4e224d73636f9a558f9368c2c7422155a41fd4d7a13613a77c1", size = 18769, upload-time = "2025-11-14T10:13:16.301Z" } wheels = [ @@ -1206,8 +1206,8 @@ name = "pyobjc-framework-coreaudio" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/84/d1/0b884c5564ab952ff5daa949128c64815300556019c1bba0cf2ca752a1a0/pyobjc_framework_coreaudio-12.1.tar.gz", hash = "sha256:a9e72925fcc1795430496ce0bffd4ddaa92c22460a10308a7283ade830089fe1", size = 75077, upload-time = "2025-11-14T10:13:22.345Z" } wheels = [ @@ -1223,9 +1223,9 @@ name = "pyobjc-framework-coreaudiokit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coreaudio", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coreaudio" }, ] sdist = { url = "https://files.pythonhosted.org/packages/41/1c/5c7e39b9361d4eec99b9115b593edd9825388acd594cb3b4519f8f1ac12c/pyobjc_framework_coreaudiokit-12.1.tar.gz", hash = "sha256:b83624f8de3068ab2ca279f786be0804da5cf904ff9979d96007b69ef4869e1e", size = 20137, upload-time = "2025-11-14T10:13:24.611Z" } wheels = [ @@ -1241,8 +1241,8 @@ name = "pyobjc-framework-corebluetooth" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4b/25/d21d6cb3fd249c2c2aa96ee54279f40876a0c93e7161b3304bf21cbd0bfe/pyobjc_framework_corebluetooth-12.1.tar.gz", hash = "sha256:8060c1466d90bbb9100741a1091bb79975d9ba43911c9841599879fc45c2bbe0", size = 33157, upload-time = "2025-11-14T10:13:28.064Z" } wheels = [ @@ -1258,8 +1258,8 @@ name = "pyobjc-framework-coredata" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3e/c5/8cd46cd4f1b7cf88bdeed3848f830ea9cdcc4e55cd0287a968a2838033fb/pyobjc_framework_coredata-12.1.tar.gz", hash = "sha256:1e47d3c5e51fdc87a90da62b97cae1bc49931a2bb064db1305827028e1fc0ffa", size = 124348, upload-time = "2025-11-14T10:13:36.435Z" } wheels = [ @@ -1275,8 +1275,8 @@ name = "pyobjc-framework-corehaptics" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3a/2f/74a3da79d9188b05dd4be4428a819ea6992d4dfaedf7d629027cf1f57bfc/pyobjc_framework_corehaptics-12.1.tar.gz", hash = "sha256:521dd2986c8a4266d583dd9ed9ae42053b11ae7d3aa89bf53fbee88307d8db10", size = 22164, upload-time = "2025-11-14T10:13:38.941Z" } wheels = [ @@ -1288,8 +1288,8 @@ name = "pyobjc-framework-corelocation" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cc/79/b75885e0d75397dc2fe1ed9ca80be2b64c18b817f5fb924277cb1bf7b163/pyobjc_framework_corelocation-12.1.tar.gz", hash = "sha256:3674e9353f949d91dde6230ad68f6d5748a7f0424751e08a2c09d06050d66231", size = 53511, upload-time = "2025-11-14T10:13:43.384Z" } wheels = [ @@ -1305,8 +1305,8 @@ name = "pyobjc-framework-coremedia" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/da/7d/5ad600ff7aedfef8ba8f51b11d9aaacdf247b870bd14045d6e6f232e3df9/pyobjc_framework_coremedia-12.1.tar.gz", hash = "sha256:166c66a9c01e7a70103f3ca44c571431d124b9070612ef63a1511a4e6d9d84a7", size = 89566, upload-time = "2025-11-14T10:13:49.788Z" } wheels = [ @@ -1322,8 +1322,8 @@ name = "pyobjc-framework-coremediaio" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/08/8e/23baee53ccd6c011c965cff62eb55638b4088c3df27d2bf05004105d6190/pyobjc_framework_coremediaio-12.1.tar.gz", hash = "sha256:880b313b28f00b27775d630174d09e0b53d1cdbadb74216618c9dd5b3eb6806a", size = 51100, upload-time = "2025-11-14T10:13:54.277Z" } wheels = [ @@ -1339,8 +1339,8 @@ name = "pyobjc-framework-coremidi" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/75/96/2d583060a71a73c8a7e6d92f2a02675621b63c1f489f2639e020fae34792/pyobjc_framework_coremidi-12.1.tar.gz", hash = "sha256:3c6f1fd03997c3b0f20ab8545126b1ce5f0cddcc1587dffacad876c161da8c54", size = 55587, upload-time = "2025-11-14T10:13:58.903Z" } wheels = [ @@ -1356,8 +1356,8 @@ name = "pyobjc-framework-coreml" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/30/2d/baa9ea02cbb1c200683cb7273b69b4bee5070e86f2060b77e6a27c2a9d7e/pyobjc_framework_coreml-12.1.tar.gz", hash = "sha256:0d1a4216891a18775c9e0170d908714c18e4f53f9dc79fb0f5263b2aa81609ba", size = 40465, upload-time = "2025-11-14T10:14:02.265Z" } wheels = [ @@ -1373,8 +1373,8 @@ name = "pyobjc-framework-coremotion" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2c/eb/abef7d405670cf9c844befc2330a46ee59f6ff7bac6f199bf249561a2ca6/pyobjc_framework_coremotion-12.1.tar.gz", hash = "sha256:8e1b094d34084cc8cf07bedc0630b4ee7f32b0215011f79c9e3cd09d205a27c7", size = 33851, upload-time = "2025-11-14T10:14:05.619Z" } wheels = [ @@ -1390,9 +1390,9 @@ name = "pyobjc-framework-coreservices" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-fsevents", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-fsevents" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4c/b3/52338a3ff41713f7d7bccaf63bef4ba4a8f2ce0c7eaff39a3629d022a79a/pyobjc_framework_coreservices-12.1.tar.gz", hash = "sha256:fc6a9f18fc6da64c166fe95f2defeb7ac8a9836b3b03bb6a891d36035260dbaa", size = 366150, upload-time = "2025-11-14T10:14:28.133Z" } wheels = [ @@ -1408,8 +1408,8 @@ name = "pyobjc-framework-corespotlight" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/99/d0/88ca73b0cf23847af463334989dd8f98e44f801b811e7e1d8a5627ec20b4/pyobjc_framework_corespotlight-12.1.tar.gz", hash = "sha256:57add47380cd0bbb9793f50a4a4b435a90d4ebd2a33698e058cb353ddfb0d068", size = 38002, upload-time = "2025-11-14T10:14:31.948Z" } wheels = [ @@ -1425,9 +1425,9 @@ name = "pyobjc-framework-coretext" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/29/da/682c9c92a39f713bd3c56e7375fa8f1b10ad558ecb075258ab6f1cdd4a6d/pyobjc_framework_coretext-12.1.tar.gz", hash = "sha256:e0adb717738fae395dc645c9e8a10bb5f6a4277e73cba8fa2a57f3b518e71da5", size = 90124, upload-time = "2025-11-14T10:14:38.596Z" } wheels = [ @@ -1443,8 +1443,8 @@ name = "pyobjc-framework-corewlan" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/88/71/739a5d023566b506b3fd3d2412983faa95a8c16226c0dcd0f67a9294a342/pyobjc_framework_corewlan-12.1.tar.gz", hash = "sha256:a9d82ec71ef61f37e1d611caf51a4203f3dbd8caf827e98128a1afaa0fd2feb5", size = 32417, upload-time = "2025-11-14T10:14:41.921Z" } wheels = [ @@ -1460,8 +1460,8 @@ name = "pyobjc-framework-cryptotokenkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6b/7c/d03ff4f74054578577296f33bc669fce16c7827eb1a553bb372b5aab30ca/pyobjc_framework_cryptotokenkit-12.1.tar.gz", hash = "sha256:c95116b4b7a41bf5b54aff823a4ef6f4d9da4d0441996d6d2c115026a42d82f5", size = 32716, upload-time = "2025-11-14T10:14:45.024Z" } wheels = [ @@ -1477,8 +1477,8 @@ name = "pyobjc-framework-datadetection" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/db/97/9b03832695ec4d3008e6150ddfdc581b0fda559d9709a98b62815581259a/pyobjc_framework_datadetection-12.1.tar.gz", hash = "sha256:95539e46d3bc970ce890aa4a97515db10b2690597c5dd362996794572e5d5de0", size = 12323, upload-time = "2025-11-14T10:14:46.769Z" } wheels = [ @@ -1490,8 +1490,8 @@ name = "pyobjc-framework-devicecheck" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/af/c676107c40d51f55d0a42043865d7246db821d01241b518ea1d3b3ef1394/pyobjc_framework_devicecheck-12.1.tar.gz", hash = "sha256:567e85fc1f567b3fe64ac1cdc323d989509331f64ee54fbcbde2001aec5adbdb", size = 12885, upload-time = "2025-11-14T10:14:48.804Z" } wheels = [ @@ -1503,8 +1503,8 @@ name = "pyobjc-framework-devicediscoveryextension" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/91/b0/e6e2ed6a7f4b689746818000a003ff7ab9c10945df66398ae8d323ae9579/pyobjc_framework_devicediscoveryextension-12.1.tar.gz", hash = "sha256:60e12445fad97ff1f83472255c943685a8f3a9d95b3126d887cfe769b7261044", size = 14718, upload-time = "2025-11-14T10:14:50.723Z" } wheels = [ @@ -1516,8 +1516,8 @@ name = "pyobjc-framework-dictionaryservices" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coreservices", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-coreservices" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7a/c0/daf03cdaf6d4e04e0cf164db358378c07facd21e4e3f8622505d72573e2c/pyobjc_framework_dictionaryservices-12.1.tar.gz", hash = "sha256:354158f3c55d66681fa903c7b3cb05a435b717fa78d0cef44d258d61156454a7", size = 10573, upload-time = "2025-11-14T10:14:53.961Z" } wheels = [ @@ -1529,8 +1529,8 @@ name = "pyobjc-framework-discrecording" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c4/87/8bd4544793bfcdf507174abddd02b1f077b48fab0004b3db9a63142ce7e9/pyobjc_framework_discrecording-12.1.tar.gz", hash = "sha256:6defc8ea97fb33b4d43870c673710c04c3dc48be30cdf78ba28191a922094990", size = 55607, upload-time = "2025-11-14T10:14:58.276Z" } wheels = [ @@ -1546,9 +1546,9 @@ name = "pyobjc-framework-discrecordingui" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-discrecording", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-discrecording" }, ] sdist = { url = "https://files.pythonhosted.org/packages/30/63/8667f5bb1ecb556add04e86b278cb358dc1f2f03862705cae6f09097464c/pyobjc_framework_discrecordingui-12.1.tar.gz", hash = "sha256:6793d4a1a7f3219d063f39d87f1d4ebbbb3347e35d09194a193cfe16cba718a8", size = 16450, upload-time = "2025-11-14T10:15:00.254Z" } wheels = [ @@ -1560,8 +1560,8 @@ name = "pyobjc-framework-diskarbitration" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3a/42/f75fcabec1a0033e4c5235cc8225773f610321d565b63bf982c10c6bbee4/pyobjc_framework_diskarbitration-12.1.tar.gz", hash = "sha256:6703bc5a09b38a720c9ffca356b58f7e99fa76fc988c9ec4d87112344e63dfc2", size = 17121, upload-time = "2025-11-14T10:15:02.223Z" } wheels = [ @@ -1573,8 +1573,8 @@ name = "pyobjc-framework-dvdplayback" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cf/dd/7859a58e8dd336c77f83feb76d502e9623c394ea09322e29a03f5bc04d32/pyobjc_framework_dvdplayback-12.1.tar.gz", hash = "sha256:279345d4b5fb2c47dd8e5c2fd289e644b6648b74f5c25079805eeb61bfc4a9cd", size = 32332, upload-time = "2025-11-14T10:15:05.257Z" } wheels = [ @@ -1586,8 +1586,8 @@ name = "pyobjc-framework-eventkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b6/42/4ec97e641fdcf30896fe76476181622954cb017117b1429f634d24816711/pyobjc_framework_eventkit-12.1.tar.gz", hash = "sha256:7c1882be2f444b1d0f71e9a0cd1e9c04ad98e0261292ab741fc9de0b8bbbbae9", size = 28538, upload-time = "2025-11-14T10:15:07.878Z" } wheels = [ @@ -1599,8 +1599,8 @@ name = "pyobjc-framework-exceptionhandling" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f1/17/5c9d4164f7ccf6b9100be0ad597a7857395dd58ea492cba4f0e9c0b77049/pyobjc_framework_exceptionhandling-12.1.tar.gz", hash = "sha256:7f0719eeea6695197fce0e7042342daa462683dc466eb6a442aad897032ab00d", size = 16694, upload-time = "2025-11-14T10:15:10.173Z" } wheels = [ @@ -1612,8 +1612,8 @@ name = "pyobjc-framework-executionpolicy" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/95/11/db765e76e7b00e1521d7bb3a61ae49b59e7573ac108da174720e5d96b61b/pyobjc_framework_executionpolicy-12.1.tar.gz", hash = "sha256:682866589365cd01d3a724d8a2781794b5cba1e152411a58825ea52d7b972941", size = 12594, upload-time = "2025-11-14T10:15:12.077Z" } wheels = [ @@ -1625,8 +1625,8 @@ name = "pyobjc-framework-extensionkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9a/d4/e9b1f74d29ad9dea3d60468d59b80e14ed3a19f9f7a25afcbc10d29c8a1e/pyobjc_framework_extensionkit-12.1.tar.gz", hash = "sha256:773987353e8aba04223dbba3149253db944abfb090c35318b3a770195b75da6d", size = 18694, upload-time = "2025-11-14T10:15:14.104Z" } wheels = [ @@ -1642,8 +1642,8 @@ name = "pyobjc-framework-externalaccessory" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8e/35/86c097ae2fdf912c61c1276e80f3e090a3fc898c75effdf51d86afec456b/pyobjc_framework_externalaccessory-12.1.tar.gz", hash = "sha256:079f770a115d517a6ab87db1b8a62ca6cdf6c35ae65f45eecc21b491e78776c0", size = 20958, upload-time = "2025-11-14T10:15:16.419Z" } wheels = [ @@ -1659,8 +1659,8 @@ name = "pyobjc-framework-fileprovider" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cc/9a/724b1fae5709f8860f06a6a2a46de568f9bb8bdb2e2aae45b4e010368f51/pyobjc_framework_fileprovider-12.1.tar.gz", hash = "sha256:45034e0d00ae153c991aa01cb1fd41874650a30093e77ba73401dcce5534c8ad", size = 43071, upload-time = "2025-11-14T10:15:19.989Z" } wheels = [ @@ -1676,8 +1676,8 @@ name = "pyobjc-framework-fileproviderui" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-fileprovider", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-fileprovider" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/00/234f9b93f75255845df81d9d5ea20cb83ecb5c0a4e59147168b622dd0b9d/pyobjc_framework_fileproviderui-12.1.tar.gz", hash = "sha256:15296429d9db0955abc3242b2920b7a810509a85118dbc185f3ac8234e5a6165", size = 12437, upload-time = "2025-11-14T10:15:22.044Z" } wheels = [ @@ -1689,8 +1689,8 @@ name = "pyobjc-framework-findersync" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e4/63/c8da472e0910238a905bc48620e005a1b8ae7921701408ca13e5fb0bfb4b/pyobjc_framework_findersync-12.1.tar.gz", hash = "sha256:c513104cef0013c233bf8655b527df665ce6f840c8bc0b3781e996933d4dcfa6", size = 13507, upload-time = "2025-11-14T10:15:24.161Z" } wheels = [ @@ -1702,8 +1702,8 @@ name = "pyobjc-framework-fsevents" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/43/17/21f45d2bca2efc72b975f2dfeae7a163dbeabb1236c1f188578403fd4f09/pyobjc_framework_fsevents-12.1.tar.gz", hash = "sha256:a22350e2aa789dec59b62da869c1b494a429f8c618854b1383d6473f4c065a02", size = 26487, upload-time = "2025-11-14T10:15:26.796Z" } wheels = [ @@ -1719,8 +1719,8 @@ name = "pyobjc-framework-fskit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a1/55/d00246d6e6d9756e129e1d94bc131c99eece2daa84b2696f6442b8a22177/pyobjc_framework_fskit-12.1.tar.gz", hash = "sha256:ec54e941cdb0b7d800616c06ca76a93685bd7119b8aa6eb4e7a3ee27658fc7ba", size = 42372, upload-time = "2025-11-14T10:15:30.411Z" } wheels = [ @@ -1736,8 +1736,8 @@ name = "pyobjc-framework-gamecenter" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d2/f8/b5fd86f6b722d4259228922e125b50e0a6975120a1c4d957e990fb84e42c/pyobjc_framework_gamecenter-12.1.tar.gz", hash = "sha256:de4118f14c9cf93eb0316d49da410faded3609ce9cd63425e9ef878cebb7ea72", size = 31473, upload-time = "2025-11-14T10:15:33.38Z" } wheels = [ @@ -1753,8 +1753,8 @@ name = "pyobjc-framework-gamecontroller" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/21/14/353bb1fe448cd833839fd199ab26426c0248088753e63c22fe19dc07530f/pyobjc_framework_gamecontroller-12.1.tar.gz", hash = "sha256:64ed3cc4844b67f1faeb540c7cc8d512c84f70b3a4bafdb33d4663a2b2a2b1d8", size = 54554, upload-time = "2025-11-14T10:15:37.591Z" } wheels = [ @@ -1770,9 +1770,9 @@ name = "pyobjc-framework-gamekit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/52/7b/d625c0937557f7e2e64200fdbeb867d2f6f86b2f148b8d6bfe085e32d872/pyobjc_framework_gamekit-12.1.tar.gz", hash = "sha256:014d032c3484093f1409f8f631ba8a0fd2ff7a3ae23fd9d14235340889854c16", size = 63833, upload-time = "2025-11-14T10:15:42.842Z" } wheels = [ @@ -1788,9 +1788,9 @@ name = "pyobjc-framework-gameplaykit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-spritekit", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-spritekit" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e2/11/c310bbc2526f95cce662cc1f1359bb11e2458eab0689737b4850d0f6acb7/pyobjc_framework_gameplaykit-12.1.tar.gz", hash = "sha256:935ebd806d802888969357946245d35a304c530c86f1ffe584e2cf21f0a608a8", size = 41511, upload-time = "2025-11-14T10:15:46.529Z" } wheels = [ @@ -1806,8 +1806,8 @@ name = "pyobjc-framework-gamesave" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1b/1f/8d05585c844535e75dbc242dd6bdfecfc613d074dcb700362d1c908fb403/pyobjc_framework_gamesave-12.1.tar.gz", hash = "sha256:eb731c97aa644e78a87838ed56d0e5bdbaae125bdc8854a7772394877312cc2e", size = 12654, upload-time = "2025-11-14T10:15:48.344Z" } wheels = [ @@ -1819,8 +1819,8 @@ name = "pyobjc-framework-healthkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/af/67/436630d00ba1028ea33cc9df2fc28e081481433e5075600f2ea1ff00f45e/pyobjc_framework_healthkit-12.1.tar.gz", hash = "sha256:29c5e5de54b41080b7a4b0207698ac6f600dcb9149becc9c6b3a69957e200e5c", size = 91802, upload-time = "2025-11-14T10:15:54.661Z" } wheels = [ @@ -1836,8 +1836,8 @@ name = "pyobjc-framework-imagecapturecore" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6d/a1/39347381fc7d3cd5ab942d86af347b25c73f0ddf6f5227d8b4d8f5328016/pyobjc_framework_imagecapturecore-12.1.tar.gz", hash = "sha256:c4776c59f4db57727389d17e1ffd9c567b854b8db52198b3ccc11281711074e5", size = 46397, upload-time = "2025-11-14T10:15:58.541Z" } wheels = [ @@ -1853,8 +1853,8 @@ name = "pyobjc-framework-inputmethodkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5d/b8/d33dd8b7306029bbbd80525bf833fc547e6a223c494bf69a534487283a28/pyobjc_framework_inputmethodkit-12.1.tar.gz", hash = "sha256:f63b6fe2fa7f1412eae63baea1e120e7865e3b68ccfb7d8b0a4aadb309f2b278", size = 23054, upload-time = "2025-11-14T10:16:01.464Z" } wheels = [ @@ -1870,8 +1870,8 @@ name = "pyobjc-framework-installerplugins" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e7/60/ca4ab04eafa388a97a521db7d60a812e2f81a3c21c2372587872e6b074f9/pyobjc_framework_installerplugins-12.1.tar.gz", hash = "sha256:1329a193bd2e92a2320a981a9a421a9b99749bade3e5914358923e94fe995795", size = 25277, upload-time = "2025-11-14T10:16:04.379Z" } wheels = [ @@ -1883,9 +1883,9 @@ name = "pyobjc-framework-instantmessage" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d4/67/66754e0d26320ba24a33608ca94d3f38e60ee6b2d2e094cb6269b346fdd4/pyobjc_framework_instantmessage-12.1.tar.gz", hash = "sha256:f453118d5693dc3c94554791bd2aaafe32a8b03b0e3d8ec3934b44b7fdd1f7e7", size = 31217, upload-time = "2025-11-14T10:16:07.693Z" } wheels = [ @@ -1897,8 +1897,8 @@ name = "pyobjc-framework-intents" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f1/a1/3bab6139e94b97eca098e1562f5d6840e3ff10ea1f7fd704a17111a97d5b/pyobjc_framework_intents-12.1.tar.gz", hash = "sha256:bd688c3ab34a18412f56e459e9dae29e1f4152d3c2048fcacdef5fc49dfb9765", size = 132262, upload-time = "2025-11-14T10:16:16.428Z" } wheels = [ @@ -1914,8 +1914,8 @@ name = "pyobjc-framework-intentsui" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-intents", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-intents" }, ] sdist = { url = "https://files.pythonhosted.org/packages/19/cf/f0e385b9cfbf153d68efe8d19e5ae672b59acbbfc1f9b58faaefc5ec8c9e/pyobjc_framework_intentsui-12.1.tar.gz", hash = "sha256:16bdf4b7b91c0d1ec9d5513a1182861f1b5b7af95d4f4218ff7cf03032d57f99", size = 19784, upload-time = "2025-11-14T10:16:18.716Z" } wheels = [ @@ -1931,8 +1931,8 @@ name = "pyobjc-framework-iobluetooth" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e4/aa/ca3944bbdfead4201b4ae6b51510942c5a7d8e5e2dc3139a071c74061fdf/pyobjc_framework_iobluetooth-12.1.tar.gz", hash = "sha256:8a434118812f4c01dfc64339d41fe8229516864a59d2803e9094ee4cbe2b7edd", size = 155241, upload-time = "2025-11-14T10:16:28.896Z" } wheels = [ @@ -1948,8 +1948,8 @@ name = "pyobjc-framework-iobluetoothui" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-iobluetooth", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-iobluetooth" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8f/39/31d9a4e8565a4b1ec0a9ad81480dc0879f3df28799eae3bc22d1dd53705d/pyobjc_framework_iobluetoothui-12.1.tar.gz", hash = "sha256:81f8158bdfb2966a574b6988eb346114d6a4c277300c8c0a978c272018184e6f", size = 16495, upload-time = "2025-11-14T10:16:31.212Z" } wheels = [ @@ -1961,8 +1961,8 @@ name = "pyobjc-framework-iosurface" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/07/61/0f12ad67a72d434e1c84b229ec760b5be71f53671ee9018593961c8bfeb7/pyobjc_framework_iosurface-12.1.tar.gz", hash = "sha256:4b9d0c66431aa296f3ca7c4f84c00dc5fc961194830ad7682fdbbc358fa0db55", size = 17690, upload-time = "2025-11-14T10:16:33.282Z" } wheels = [ @@ -1974,8 +1974,8 @@ name = "pyobjc-framework-ituneslibrary" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f5/46/d9bcec88675bf4ee887b9707bd245e2a793e7cb916cf310f286741d54b1f/pyobjc_framework_ituneslibrary-12.1.tar.gz", hash = "sha256:7f3aa76c4d05f6fa6015056b88986cacbda107c3f29520dd35ef0936c7367a6e", size = 23730, upload-time = "2025-11-14T10:16:36.127Z" } wheels = [ @@ -1987,8 +1987,8 @@ name = "pyobjc-framework-kernelmanagement" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0a/7e/ecbac119866e8ac2cce700d7a48a4297946412ac7cbc243a7084a6582fb1/pyobjc_framework_kernelmanagement-12.1.tar.gz", hash = "sha256:488062893ac2074e0c8178667bf864a21f7909c11111de2f6a10d9bc579df59d", size = 11773, upload-time = "2025-11-14T10:16:38.216Z" } wheels = [ @@ -2000,8 +2000,8 @@ name = "pyobjc-framework-latentsemanticmapping" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/88/3c/b621dac54ae8e77ac25ee75dd93e310e2d6e0faaf15b8da13513258d6657/pyobjc_framework_latentsemanticmapping-12.1.tar.gz", hash = "sha256:f0b1fa823313eefecbf1539b4ed4b32461534b7a35826c2cd9f6024411dc9284", size = 15526, upload-time = "2025-11-14T10:16:40.149Z" } wheels = [ @@ -2013,8 +2013,8 @@ name = "pyobjc-framework-launchservices" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coreservices", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-coreservices" }, ] sdist = { url = "https://files.pythonhosted.org/packages/37/d0/24673625922b0ad21546be5cf49e5ec1afaa4553ae92f222adacdc915907/pyobjc_framework_launchservices-12.1.tar.gz", hash = "sha256:4d2d34c9bd6fb7f77566155b539a2c70283d1f0326e1695da234a93ef48352dc", size = 20470, upload-time = "2025-11-14T10:16:42.499Z" } wheels = [ @@ -2026,8 +2026,8 @@ name = "pyobjc-framework-libdispatch" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/26/e8/75b6b9b3c88b37723c237e5a7600384ea2d84874548671139db02e76652b/pyobjc_framework_libdispatch-12.1.tar.gz", hash = "sha256:4035535b4fae1b5e976f3e0e38b6e3442ffea1b8aa178d0ca89faa9b8ecdea41", size = 38277, upload-time = "2025-11-14T10:16:46.235Z" } wheels = [ @@ -2043,8 +2043,8 @@ name = "pyobjc-framework-libxpc" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/16/e4/364db7dc26f235e3d7eaab2f92057f460b39800bffdec3128f113388ac9f/pyobjc_framework_libxpc-12.1.tar.gz", hash = "sha256:e46363a735f3ecc9a2f91637750623f90ee74f9938a4e7c833e01233174af44d", size = 35186, upload-time = "2025-11-14T10:16:49.503Z" } wheels = [ @@ -2060,9 +2060,9 @@ name = "pyobjc-framework-linkpresentation" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e3/58/c0c5919d883485ccdb6dccd8ecfe50271d2f6e6ab7c9b624789235ccec5a/pyobjc_framework_linkpresentation-12.1.tar.gz", hash = "sha256:84df6779591bb93217aa8bd82c10e16643441678547d2d73ba895475a02ade94", size = 13330, upload-time = "2025-11-14T10:16:52.169Z" } wheels = [ @@ -2074,9 +2074,9 @@ name = "pyobjc-framework-localauthentication" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-security", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-security" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8d/0e/7e5d9a58bb3d5b79a75d925557ef68084171526191b1c0929a887a553d4f/pyobjc_framework_localauthentication-12.1.tar.gz", hash = "sha256:2284f587d8e1206166e4495b33f420c1de486c36c28c4921d09eec858a699d05", size = 29947, upload-time = "2025-11-14T10:16:54.923Z" } wheels = [ @@ -2092,9 +2092,9 @@ name = "pyobjc-framework-localauthenticationembeddedui" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-localauthentication", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-localauthentication" }, ] sdist = { url = "https://files.pythonhosted.org/packages/31/20/83ab4180e29b9a4a44d735c7f88909296c6adbe6250e8e00a156aff753e1/pyobjc_framework_localauthenticationembeddedui-12.1.tar.gz", hash = "sha256:a15ec44bf2769c872e86c6b550b6dd4f58d4eda40ad9ff00272a67d279d1d4e9", size = 13611, upload-time = "2025-11-14T10:16:57.145Z" } wheels = [ @@ -2106,8 +2106,8 @@ name = "pyobjc-framework-mailkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2a/98/3d9028620c1cd32ff4fb031155aba3b5511e980cdd114dd51383be9cb51b/pyobjc_framework_mailkit-12.1.tar.gz", hash = "sha256:d5574b7259baec17096410efcaacf5d45c7bb5f893d4c25cbb7072369799b652", size = 20996, upload-time = "2025-11-14T10:16:59.449Z" } wheels = [ @@ -2119,10 +2119,10 @@ name = "pyobjc-framework-mapkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-corelocation", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-corelocation" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/36/bb/2a668203c20e509a648c35e803d79d0c7f7816dacba74eb5ad8acb186790/pyobjc_framework_mapkit-12.1.tar.gz", hash = "sha256:dbc32dc48e821aaa9b4294402c240adbc1c6834e658a07677b7c19b7990533c5", size = 63520, upload-time = "2025-11-14T10:17:04.221Z" } wheels = [ @@ -2138,8 +2138,8 @@ name = "pyobjc-framework-mediaaccessibility" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e0/10/dc1007e56944ed2e981e69e7b2fed2b2202c79b0d5b742b29b1081d1cbdd/pyobjc_framework_mediaaccessibility-12.1.tar.gz", hash = "sha256:cc4e3b1d45e84133d240318d53424eff55968f5c6873c2c53267598853445a3f", size = 16325, upload-time = "2025-11-14T10:17:07.454Z" } wheels = [ @@ -2151,10 +2151,10 @@ name = "pyobjc-framework-mediaextension" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-avfoundation", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coremedia", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-avfoundation" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coremedia" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d6/aa/1e8015711df1cdb5e4a0aa0ed4721409d39971ae6e1e71915e3ab72423a3/pyobjc_framework_mediaextension-12.1.tar.gz", hash = "sha256:44409d63cc7d74e5724a68e3f9252cb62fd0fd3ccf0ca94c6a33e5c990149953", size = 39425, upload-time = "2025-11-14T10:17:11.486Z" } wheels = [ @@ -2170,9 +2170,9 @@ name = "pyobjc-framework-medialibrary" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/34/e9/848ebd02456f8fdb41b42298ec585bfed5899dbd30306ea5b0a7e4c4b341/pyobjc_framework_medialibrary-12.1.tar.gz", hash = "sha256:690dcca09b62511df18f58e8566cb33d9652aae09fe63a83f594bd018b5edfcd", size = 15995, upload-time = "2025-11-14T10:17:15.45Z" } wheels = [ @@ -2184,8 +2184,8 @@ name = "pyobjc-framework-mediaplayer" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-avfoundation", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-avfoundation" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e9/f0/851f6f47e11acbd62d5f5dcb8274afc969135e30018591f75bf3cbf6417f/pyobjc_framework_mediaplayer-12.1.tar.gz", hash = "sha256:5ef3f669bdf837d87cdb5a486ec34831542360d14bcba099c7c2e0383380794c", size = 35402, upload-time = "2025-11-14T10:17:18.97Z" } wheels = [ @@ -2197,8 +2197,8 @@ name = "pyobjc-framework-mediatoolbox" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a3/71/be5879380a161f98212a336b432256f307d1dcbaaaeb8ec988aea2ada2cd/pyobjc_framework_mediatoolbox-12.1.tar.gz", hash = "sha256:385b48746a5f08756ee87afc14037e552954c427ed5745d7ece31a21a7bad5ab", size = 22305, upload-time = "2025-11-14T10:17:22.501Z" } wheels = [ @@ -2214,8 +2214,8 @@ name = "pyobjc-framework-metal" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e7/06/a84f7eb8561d5631954b9458cfca04b690b80b5b85ce70642bc89335f52a/pyobjc_framework_metal-12.1.tar.gz", hash = "sha256:bb554877d5ee2bf3f340ad88e8fe1b85baab7b5ec4bd6ae0f4f7604147e3eae7", size = 181847, upload-time = "2025-11-14T10:17:34.157Z" } wheels = [ @@ -2231,8 +2231,8 @@ name = "pyobjc-framework-metalfx" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metal", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-metal" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f1/09/ce5c74565677fde66de3b9d35389066b19e5d1bfef9d9a4ad80f0c858c0c/pyobjc_framework_metalfx-12.1.tar.gz", hash = "sha256:1551b686fb80083a97879ce0331bdb1d4c9b94557570b7ecc35ebf40ff65c90b", size = 29470, upload-time = "2025-11-14T10:17:37.16Z" } wheels = [ @@ -2248,9 +2248,9 @@ name = "pyobjc-framework-metalkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metal", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-metal" }, ] sdist = { url = "https://files.pythonhosted.org/packages/14/15/5091147aae12d4011a788b93971c3376aaaf9bf32aa935a2c9a06a71e18b/pyobjc_framework_metalkit-12.1.tar.gz", hash = "sha256:14cc5c256f0e3471b412a5b3582cb2a0d36d3d57401a8aa09e433252d1c34824", size = 25473, upload-time = "2025-11-14T10:17:39.721Z" } wheels = [ @@ -2266,8 +2266,8 @@ name = "pyobjc-framework-metalperformanceshaders" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metal", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-metal" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c5/68/58da38e54aa0d8c19f0d3084d8c84e92d54cc8c9254041f07119d86aa073/pyobjc_framework_metalperformanceshaders-12.1.tar.gz", hash = "sha256:b198e755b95a1de1525e63c3b14327ae93ef1d88359e6be1ce554a3493755b50", size = 137301, upload-time = "2025-11-14T10:17:49.554Z" } wheels = [ @@ -2283,8 +2283,8 @@ name = "pyobjc-framework-metalperformanceshadersgraph" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-metalperformanceshaders", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-metalperformanceshaders" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a7/56/7ad0cd085532f7bdea9a8d4e9a2dfde376d26dd21e5eabdf1a366040eff8/pyobjc_framework_metalperformanceshadersgraph-12.1.tar.gz", hash = "sha256:b8fd017b47698037d7b172d41bed7a4835f4c4f2a288235819d200005f89ee35", size = 42992, upload-time = "2025-11-14T10:17:53.502Z" } wheels = [ @@ -2296,8 +2296,8 @@ name = "pyobjc-framework-metrickit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ba/13/5576ddfbc0b174810a49171e2dbe610bdafd3b701011c6ecd9b3a461de8a/pyobjc_framework_metrickit-12.1.tar.gz", hash = "sha256:77841daf6b36ba0c19df88545fd910c0516acf279e6b7b4fa0a712a046eaa9f1", size = 27627, upload-time = "2025-11-14T10:17:56.353Z" } wheels = [ @@ -2313,8 +2313,8 @@ name = "pyobjc-framework-mlcompute" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/00/69/15f8ce96c14383aa783c8e4bc1e6d936a489343bb197b8e71abb3ddc1cb8/pyobjc_framework_mlcompute-12.1.tar.gz", hash = "sha256:3281db120273dcc56e97becffd5cedf9c62042788289f7be6ea067a863164f1e", size = 40698, upload-time = "2025-11-14T10:17:59.792Z" } wheels = [ @@ -2326,9 +2326,9 @@ name = "pyobjc-framework-modelio" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b4/11/32c358111b623b4a0af9e90470b198fffc068b45acac74e1ba711aee7199/pyobjc_framework_modelio-12.1.tar.gz", hash = "sha256:d041d7bca7c2a4526344d3e593347225b7a2e51a499b3aa548895ba516d1bdbb", size = 66482, upload-time = "2025-11-14T10:18:04.92Z" } wheels = [ @@ -2344,8 +2344,8 @@ name = "pyobjc-framework-multipeerconnectivity" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/87/35/0d0bb6881004cb238cfd7bf74f4b2e42601a1accdf27b2189ec61cf3a2dc/pyobjc_framework_multipeerconnectivity-12.1.tar.gz", hash = "sha256:7123f734b7174cacbe92a51a62b4645cc9033f6b462ff945b504b62e1b9e6c1c", size = 22816, upload-time = "2025-11-14T10:18:07.363Z" } wheels = [ @@ -2361,8 +2361,8 @@ name = "pyobjc-framework-naturallanguage" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8a/d1/c81c0cdbb198d498edc9bc5fbb17e79b796450c17bb7541adbf502f9ad65/pyobjc_framework_naturallanguage-12.1.tar.gz", hash = "sha256:cb27a1e1e5b2913d308c49fcd2fd04ab5ea87cb60cac4a576a91ebf6a50e52f6", size = 23524, upload-time = "2025-11-14T10:18:09.883Z" } wheels = [ @@ -2374,8 +2374,8 @@ name = "pyobjc-framework-netfs" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/46/68/4bf0e5b8cc0780cf7acf0aec54def58c8bcf8d733db0bd38f5a264d1af06/pyobjc_framework_netfs-12.1.tar.gz", hash = "sha256:e8d0c25f41d7d9ced1aa2483238d0a80536df21f4b588640a72e1bdb87e75c1e", size = 14799, upload-time = "2025-11-14T10:18:11.85Z" } wheels = [ @@ -2387,8 +2387,8 @@ name = "pyobjc-framework-network" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/13/a71270a1b0a9ec979e68b8ec84b0f960e908b17b51cb3cac246a74d52b6b/pyobjc_framework_network-12.1.tar.gz", hash = "sha256:dbf736ff84d1caa41224e86ff84d34b4e9eb6918ae4e373a44d3cb597648a16a", size = 56990, upload-time = "2025-11-14T10:18:16.714Z" } wheels = [ @@ -2404,8 +2404,8 @@ name = "pyobjc-framework-networkextension" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/bf/3e/ac51dbb2efa16903e6af01f3c1f5a854c558661a7a5375c3e8767ac668e8/pyobjc_framework_networkextension-12.1.tar.gz", hash = "sha256:36abc339a7f214ab6a05cb2384a9df912f247163710741e118662bd049acfa2e", size = 62796, upload-time = "2025-11-14T10:18:21.769Z" } wheels = [ @@ -2421,8 +2421,8 @@ name = "pyobjc-framework-notificationcenter" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c6/12/ae0fe82fb1e02365c9fe9531c9de46322f7af09e3659882212c6bf24d75e/pyobjc_framework_notificationcenter-12.1.tar.gz", hash = "sha256:2d09f5ab9dc39770bae4fa0c7cfe961e6c440c8fc465191d403633dccc941094", size = 21282, upload-time = "2025-11-14T10:18:24.51Z" } wheels = [ @@ -2438,8 +2438,8 @@ name = "pyobjc-framework-opendirectory" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5b/11/bc2f71d3077b3bd078dccad5c0c5c57ec807fefe3d90c97b97dd0ed3d04b/pyobjc_framework_opendirectory-12.1.tar.gz", hash = "sha256:2c63ce5dd179828ef2d8f9e3961da3bfa971a57db07a6c34eedc296548a928bb", size = 61049, upload-time = "2025-11-14T10:18:29.336Z" } wheels = [ @@ -2451,8 +2451,8 @@ name = "pyobjc-framework-osakit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cb/b9/bf52c555c75a83aa45782122432fa06066bb76469047f13d06fb31e585c4/pyobjc_framework_osakit-12.1.tar.gz", hash = "sha256:36ea6acf03483dc1e4344a0cce7250a9656f44277d12bc265fa86d4cbde01f23", size = 17102, upload-time = "2025-11-14T10:18:31.354Z" } wheels = [ @@ -2464,10 +2464,10 @@ name = "pyobjc-framework-oslog" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coremedia", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coremedia" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/12/42/805c9b4ac6ad25deb4215989d8fc41533d01e07ffd23f31b65620bade546/pyobjc_framework_oslog-12.1.tar.gz", hash = "sha256:d0ec6f4e3d1689d5e4341bc1130c6f24cb4ad619939f6c14d11a7e80c0ac4553", size = 21193, upload-time = "2025-11-14T10:18:33.645Z" } wheels = [ @@ -2483,8 +2483,8 @@ name = "pyobjc-framework-passkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6c/d4/2afb59fb0f99eb2f03888850887e536f1ef64b303fd756283679471a5189/pyobjc_framework_passkit-12.1.tar.gz", hash = "sha256:d8c27c352e86a3549bf696504e6b25af5f2134b173d9dd60d66c6d3da53bb078", size = 53835, upload-time = "2025-11-14T10:18:37.906Z" } wheels = [ @@ -2500,8 +2500,8 @@ name = "pyobjc-framework-pencilkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7e/43/859068016bcbe7d80597d5c579de0b84b0da62c5c55cdf9cc940e9f9c0f8/pyobjc_framework_pencilkit-12.1.tar.gz", hash = "sha256:d404982d1f7a474369f3e7fea3fbd6290326143fa4138d64b6753005a6263dc4", size = 17664, upload-time = "2025-11-14T10:18:40.045Z" } wheels = [ @@ -2513,8 +2513,8 @@ name = "pyobjc-framework-phase" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-avfoundation", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-avfoundation" }, ] sdist = { url = "https://files.pythonhosted.org/packages/96/51/3b25eaf7ca85f38ceef892fdf066b7faa0fec716f35ea928c6ffec6ae311/pyobjc_framework_phase-12.1.tar.gz", hash = "sha256:3a69005c572f6fd777276a835115eb8359a33673d4a87e754209f99583534475", size = 32730, upload-time = "2025-11-14T10:18:43.102Z" } wheels = [ @@ -2526,8 +2526,8 @@ name = "pyobjc-framework-photos" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b8/53/f8a3dc7f711034d2283e289cd966fb7486028ea132a24260290ff32d3525/pyobjc_framework_photos-12.1.tar.gz", hash = "sha256:adb68aaa29e186832d3c36a0b60b0592a834e24c5263e9d78c956b2b77dce563", size = 47034, upload-time = "2025-11-14T10:18:47.27Z" } wheels = [ @@ -2543,8 +2543,8 @@ name = "pyobjc-framework-photosui" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/40/a5/14c538828ed1a420e047388aedc4a2d7d9292030d81bf6b1ced2ec27b6e9/pyobjc_framework_photosui-12.1.tar.gz", hash = "sha256:9141234bb9d17687f1e8b66303158eccdd45132341fbe5e892174910035f029a", size = 29886, upload-time = "2025-11-14T10:18:50.238Z" } wheels = [ @@ -2560,8 +2560,8 @@ name = "pyobjc-framework-preferencepanes" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/90/bc/e87df041d4f7f6b7721bf7996fa02aa0255939fb0fac0ecb294229765f92/pyobjc_framework_preferencepanes-12.1.tar.gz", hash = "sha256:b2a02f9049f136bdeca7642b3307637b190850e5853b74b5c372bc7d88ef9744", size = 24543, upload-time = "2025-11-14T10:18:53.259Z" } wheels = [ @@ -2573,8 +2573,8 @@ name = "pyobjc-framework-pushkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a9/45/de756b62709add6d0615f86e48291ee2bee40223e7dde7bbe68a952593f0/pyobjc_framework_pushkit-12.1.tar.gz", hash = "sha256:829a2fc8f4780e75fc2a41217290ee0ff92d4ade43c42def4d7e5af436d8ae82", size = 19465, upload-time = "2025-11-14T10:18:57.727Z" } wheels = [ @@ -2590,8 +2590,8 @@ name = "pyobjc-framework-quartz" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/94/18/cc59f3d4355c9456fc945eae7fe8797003c4da99212dd531ad1b0de8a0c6/pyobjc_framework_quartz-12.1.tar.gz", hash = "sha256:27f782f3513ac88ec9b6c82d9767eef95a5cf4175ce88a1e5a65875fee799608", size = 3159099, upload-time = "2025-11-14T10:21:24.31Z" } wheels = [ @@ -2607,9 +2607,9 @@ name = "pyobjc-framework-quicklookthumbnailing" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/97/1a/b90539500e9a27c2049c388d85a824fc0704009b11e33b05009f52a6dc67/pyobjc_framework_quicklookthumbnailing-12.1.tar.gz", hash = "sha256:4f7e09e873e9bda236dce6e2f238cab571baeb75eca2e0bc0961d5fcd85f3c8f", size = 14790, upload-time = "2025-11-14T10:21:26.442Z" } wheels = [ @@ -2621,8 +2621,8 @@ name = "pyobjc-framework-replaykit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/35/f8/b92af879734d91c1726227e7a03b9e68ab8d9d2bb1716d1a5c29254087f2/pyobjc_framework_replaykit-12.1.tar.gz", hash = "sha256:95801fd35c329d7302b2541f2754e6574bf36547ab869fbbf41e408dfa07268a", size = 23312, upload-time = "2025-11-14T10:21:29.18Z" } wheels = [ @@ -2638,8 +2638,8 @@ name = "pyobjc-framework-safariservices" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3e/4b/8f896bafbdbfa180a5ba1e21a6f5dc63150c09cba69d85f68708e02866ae/pyobjc_framework_safariservices-12.1.tar.gz", hash = "sha256:6a56f71c1e692bca1f48fe7c40e4c5a41e148b4e3c6cfb185fd80a4d4a951897", size = 25165, upload-time = "2025-11-14T10:21:32.041Z" } wheels = [ @@ -2655,9 +2655,9 @@ name = "pyobjc-framework-safetykit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f4/bf/ad6bf60ceb61614c9c9f5758190971e9b90c45b1c7a244e45db64138b6c2/pyobjc_framework_safetykit-12.1.tar.gz", hash = "sha256:0cd4850659fb9b5632fd8ad21f2de6863e8303ff0d51c5cc9c0034aac5db08d8", size = 20086, upload-time = "2025-11-14T10:21:34.212Z" } wheels = [ @@ -2673,9 +2673,9 @@ name = "pyobjc-framework-scenekit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/94/8c/1f4005cf0cb68f84dd98b93bbc0974ee7851bb33d976791c85e042dc2278/pyobjc_framework_scenekit-12.1.tar.gz", hash = "sha256:1bd5b866f31fd829f26feac52e807ed942254fd248115c7c742cfad41d949426", size = 101212, upload-time = "2025-11-14T10:21:41.265Z" } wheels = [ @@ -2691,9 +2691,9 @@ name = "pyobjc-framework-screencapturekit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coremedia", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coremedia" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2d/7f/73458db1361d2cb408f43821a1e3819318a0f81885f833d78d93bdc698e0/pyobjc_framework_screencapturekit-12.1.tar.gz", hash = "sha256:50992c6128b35ab45d9e336f0993ddd112f58b8c8c8f0892a9cb42d61bd1f4c9", size = 32573, upload-time = "2025-11-14T10:21:44.497Z" } wheels = [ @@ -2709,8 +2709,8 @@ name = "pyobjc-framework-screensaver" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7d/99/7cfbce880cea61253a44eed594dce66c2b2fbf29e37eaedcd40cffa949e9/pyobjc_framework_screensaver-12.1.tar.gz", hash = "sha256:c4ca111317c5a3883b7eace0a9e7dd72bc6ffaa2ca954bdec918c3ab7c65c96f", size = 22229, upload-time = "2025-11-14T10:21:47.299Z" } wheels = [ @@ -2726,8 +2726,8 @@ name = "pyobjc-framework-screentime" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/10/11/ba18f905321895715dac3cae2071c2789745ae13605b283b8114b41e0459/pyobjc_framework_screentime-12.1.tar.gz", hash = "sha256:583de46b365543bbbcf27cd70eedd375d397441d64a2cf43c65286fd9c91af55", size = 13413, upload-time = "2025-11-14T10:21:49.17Z" } wheels = [ @@ -2739,8 +2739,8 @@ name = "pyobjc-framework-scriptingbridge" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0c/cb/adc0a09e8c4755c2281bd12803a87f36e0832a8fc853a2d663433dbb72ce/pyobjc_framework_scriptingbridge-12.1.tar.gz", hash = "sha256:0e90f866a7e6a8aeaf723d04c826657dd528c8c1b91e7a605f8bb947c74ad082", size = 20339, upload-time = "2025-11-14T10:21:51.769Z" } wheels = [ @@ -2756,8 +2756,8 @@ name = "pyobjc-framework-searchkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coreservices", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-coreservices" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6e/60/a38523198430e14fdef21ebe62a93c43aedd08f1f3a07ea3d96d9997db5d/pyobjc_framework_searchkit-12.1.tar.gz", hash = "sha256:ddd94131dabbbc2d7c3f17db3da87c1a712c431310eef16f07187771e7e85226", size = 30942, upload-time = "2025-11-14T10:21:55.483Z" } wheels = [ @@ -2769,8 +2769,8 @@ name = "pyobjc-framework-security" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/80/aa/796e09a3e3d5cee32ebeebb7dcf421b48ea86e28c387924608a05e3f668b/pyobjc_framework_security-12.1.tar.gz", hash = "sha256:7fecb982bd2f7c4354513faf90ba4c53c190b7e88167984c2d0da99741de6da9", size = 168044, upload-time = "2025-11-14T10:22:06.334Z" } wheels = [ @@ -2786,9 +2786,9 @@ name = "pyobjc-framework-securityfoundation" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-security", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-security" }, ] sdist = { url = "https://files.pythonhosted.org/packages/57/d5/c2b77e83c1585ba43e5f00c917273ba4bf7ed548c1b691f6766eb0418d52/pyobjc_framework_securityfoundation-12.1.tar.gz", hash = "sha256:1f39f4b3db6e3bd3a420aaf4923228b88e48c90692cf3612b0f6f1573302a75d", size = 12669, upload-time = "2025-11-14T10:22:09.256Z" } wheels = [ @@ -2800,9 +2800,9 @@ name = "pyobjc-framework-securityinterface" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-security", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-security" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f9/64/bf5b5d82655112a2314422ee649f1e1e73d4381afa87e1651ce7e8444694/pyobjc_framework_securityinterface-12.1.tar.gz", hash = "sha256:deef11ad03be8d9ff77db6e7ac40f6b641ee2d72eaafcf91040537942472e88b", size = 25552, upload-time = "2025-11-14T10:22:12.098Z" } wheels = [ @@ -2818,9 +2818,9 @@ name = "pyobjc-framework-securityui" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-security", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-security" }, ] sdist = { url = "https://files.pythonhosted.org/packages/83/3f/d870305f5dec58cd02966ca06ac29b69fb045d8b46dfb64e2da31f295345/pyobjc_framework_securityui-12.1.tar.gz", hash = "sha256:f1435fed85edc57533c334a4efc8032170424b759da184cb7a7a950ceea0e0b6", size = 12184, upload-time = "2025-11-14T10:22:14.323Z" } wheels = [ @@ -2832,9 +2832,9 @@ name = "pyobjc-framework-sensitivecontentanalysis" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e7/ce/17bf31753e14cb4d64fffaaba2377453c4977c2c5d3cf2ff0a3db30026c7/pyobjc_framework_sensitivecontentanalysis-12.1.tar.gz", hash = "sha256:2c615ac10e93eb547b32b214cd45092056bee0e79696426fd09978dc3e670f25", size = 13745, upload-time = "2025-11-14T10:22:16.447Z" } wheels = [ @@ -2846,8 +2846,8 @@ name = "pyobjc-framework-servicemanagement" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/31/d0/b26c83ae96ab55013df5fedf89337d4d62311b56ce3f520fc7597d223d82/pyobjc_framework_servicemanagement-12.1.tar.gz", hash = "sha256:08120981749a698033a1d7a6ab99dbbe412c5c0d40f2b4154014b52113511c1d", size = 14585, upload-time = "2025-11-14T10:22:18.735Z" } wheels = [ @@ -2859,8 +2859,8 @@ name = "pyobjc-framework-sharedwithyou" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-sharedwithyoucore", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-sharedwithyoucore" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0f/8b/8ab209a143c11575a857e2111acc5427fb4986b84708b21324cbcbf5591b/pyobjc_framework_sharedwithyou-12.1.tar.gz", hash = "sha256:167d84794a48f408ee51f885210c616fda1ec4bff3dd8617a4b5547f61b05caf", size = 24791, upload-time = "2025-11-14T10:22:21.248Z" } wheels = [ @@ -2876,8 +2876,8 @@ name = "pyobjc-framework-sharedwithyoucore" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/55/ef/84059c5774fd5435551ab7ab40b51271cfb9997b0d21f491c6b429fe57a8/pyobjc_framework_sharedwithyoucore-12.1.tar.gz", hash = "sha256:0813149eeb755d718b146ec9365eb4ca3262b6af9ff9ba7db2f7b6f4fd104518", size = 22350, upload-time = "2025-11-14T10:22:23.611Z" } wheels = [ @@ -2893,8 +2893,8 @@ name = "pyobjc-framework-shazamkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ed/2c/8d82c5066cc376de68ad8c1454b7c722c7a62215e5c2f9dac5b33a6c3d42/pyobjc_framework_shazamkit-12.1.tar.gz", hash = "sha256:71db2addd016874639a224ed32b2000b858802b0370c595a283cce27f76883fe", size = 22518, upload-time = "2025-11-14T10:22:25.996Z" } wheels = [ @@ -2910,8 +2910,8 @@ name = "pyobjc-framework-social" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/31/21/afc6f37dfdd2cafcba0227e15240b5b0f1f4ad57621aeefda2985ac9560e/pyobjc_framework_social-12.1.tar.gz", hash = "sha256:1963db6939e92ae40dd9d68852e8f88111cbfd37a83a9fdbc9a0c08993ca7e60", size = 13184, upload-time = "2025-11-14T10:22:28.048Z" } wheels = [ @@ -2923,8 +2923,8 @@ name = "pyobjc-framework-soundanalysis" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6b/d6/5039b61edc310083425f87ce2363304d3a87617e941c1d07968c63b5638d/pyobjc_framework_soundanalysis-12.1.tar.gz", hash = "sha256:e2deead8b9a1c4513dbdcf703b21650dcb234b60a32d08afcec4895582b040b1", size = 14804, upload-time = "2025-11-14T10:22:29.998Z" } wheels = [ @@ -2936,8 +2936,8 @@ name = "pyobjc-framework-speech" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8d/3d/194cf19fe7a56c2be5dfc28f42b3b597a62ebb1e1f52a7dd9c55b917ac6c/pyobjc_framework_speech-12.1.tar.gz", hash = "sha256:2a2a546ba6c52d5dd35ddcfee3fd9226a428043d1719597e8701851a6566afdd", size = 25218, upload-time = "2025-11-14T10:22:32.505Z" } wheels = [ @@ -2953,9 +2953,9 @@ name = "pyobjc-framework-spritekit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b6/78/d683ebe0afb49f46d2d21d38c870646e7cb3c2e83251f264e79d357b1b74/pyobjc_framework_spritekit-12.1.tar.gz", hash = "sha256:a851f4ef5aa65cc9e08008644a528e83cb31021a1c0f17ebfce4de343764d403", size = 64470, upload-time = "2025-11-14T10:22:37.569Z" } wheels = [ @@ -2971,8 +2971,8 @@ name = "pyobjc-framework-storekit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/00/87/8a66a145feb026819775d44975c71c1c64df4e5e9ea20338f01456a61208/pyobjc_framework_storekit-12.1.tar.gz", hash = "sha256:818452e67e937a10b5c8451758274faa44ad5d4329df0fa85735115fb0608da9", size = 34574, upload-time = "2025-11-14T10:22:40.73Z" } wheels = [ @@ -2988,8 +2988,8 @@ name = "pyobjc-framework-symbols" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9a/ce/a48819eb8524fa2dc11fb3dd40bb9c4dcad0596fe538f5004923396c2c6c/pyobjc_framework_symbols-12.1.tar.gz", hash = "sha256:7d8e999b8a59c97d38d1d343b6253b1b7d04bf50b665700957d89c8ac43b9110", size = 12782, upload-time = "2025-11-14T10:22:42.609Z" } wheels = [ @@ -3001,9 +3001,9 @@ name = "pyobjc-framework-syncservices" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coredata", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coredata" }, ] sdist = { url = "https://files.pythonhosted.org/packages/21/91/6d03a988831ddb0fb001b13573560e9a5bcccde575b99350f98fe56a2dd4/pyobjc_framework_syncservices-12.1.tar.gz", hash = "sha256:6a213e93d9ce15128810987e4c5de8c73cfab1564ac8d273e6b437a49965e976", size = 31032, upload-time = "2025-11-14T10:22:45.902Z" } wheels = [ @@ -3019,8 +3019,8 @@ name = "pyobjc-framework-systemconfiguration" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/90/7d/50848df8e1c6b5e13967dee9fb91d3391fe1f2399d2d0797d2fc5edb32ba/pyobjc_framework_systemconfiguration-12.1.tar.gz", hash = "sha256:90fe04aa059876a21626931c71eaff742a27c79798a46347fd053d7008ec496e", size = 59158, upload-time = "2025-11-14T10:22:53.056Z" } wheels = [ @@ -3036,8 +3036,8 @@ name = "pyobjc-framework-systemextensions" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/12/01/8a706cd3f7dfcb9a5017831f2e6f9e5538298e90052db3bb8163230cbc4f/pyobjc_framework_systemextensions-12.1.tar.gz", hash = "sha256:243e043e2daee4b5c46cd90af5fff46b34596aac25011bab8ba8a37099685eeb", size = 20701, upload-time = "2025-11-14T10:22:58.257Z" } wheels = [ @@ -3053,8 +3053,8 @@ name = "pyobjc-framework-threadnetwork" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/62/7e/f1816c3461e4121186f2f7750c58af083d1826bbd73f72728da3edcf4915/pyobjc_framework_threadnetwork-12.1.tar.gz", hash = "sha256:e071eedb41bfc1b205111deb54783ec5a035ccd6929e6e0076336107fdd046ee", size = 12788, upload-time = "2025-11-14T10:23:00.329Z" } wheels = [ @@ -3066,8 +3066,8 @@ name = "pyobjc-framework-uniformtypeidentifiers" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/65/b8/dd9d2a94509a6c16d965a7b0155e78edf520056313a80f0cd352413f0d0b/pyobjc_framework_uniformtypeidentifiers-12.1.tar.gz", hash = "sha256:64510a6df78336579e9c39b873cfcd03371c4b4be2cec8af75a8a3d07dff607d", size = 17030, upload-time = "2025-11-14T10:23:02.222Z" } wheels = [ @@ -3079,8 +3079,8 @@ name = "pyobjc-framework-usernotifications" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/90/cd/e0253072f221fa89a42fe53f1a2650cc9bf415eb94ae455235bd010ee12e/pyobjc_framework_usernotifications-12.1.tar.gz", hash = "sha256:019ccdf2d400f9a428769df7dba4ea97c02453372bc5f8b75ce7ae54dfe130f9", size = 29749, upload-time = "2025-11-14T10:23:05.364Z" } wheels = [ @@ -3096,9 +3096,9 @@ name = "pyobjc-framework-usernotificationsui" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-usernotifications", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-usernotifications" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0e/03/73e29fd5e5973cb3800c9d56107c1062547ef7524cbcc757c3cbbd5465c6/pyobjc_framework_usernotificationsui-12.1.tar.gz", hash = "sha256:51381c97c7344099377870e49ed0871fea85ba50efe50ab05ccffc06b43ec02e", size = 13125, upload-time = "2025-11-14T10:23:07.259Z" } wheels = [ @@ -3110,8 +3110,8 @@ name = "pyobjc-framework-videosubscriberaccount" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/10/f8/27927a9c125c622656ee5aada4596ccb8e5679da0260742360f193df6dcf/pyobjc_framework_videosubscriberaccount-12.1.tar.gz", hash = "sha256:750459fa88220ab83416f769f2d5d210a1f77b8938fa4d119aad0002fc32846b", size = 18793, upload-time = "2025-11-14T10:23:09.33Z" } wheels = [ @@ -3123,10 +3123,10 @@ name = "pyobjc-framework-videotoolbox" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coremedia", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coremedia" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b3/5f/6995ee40dc0d1a3460ee183f696e5254c0ad14a25b5bc5fd9bd7266c077b/pyobjc_framework_videotoolbox-12.1.tar.gz", hash = "sha256:7adc8670f3b94b086aed6e86c3199b388892edab4f02933c2e2d9b1657561bef", size = 57825, upload-time = "2025-11-14T10:23:13.825Z" } wheels = [ @@ -3142,8 +3142,8 @@ name = "pyobjc-framework-virtualization" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3b/6a/9d110b5521d9b898fad10928818c9f55d66a4af9ac097426c65a9878b095/pyobjc_framework_virtualization-12.1.tar.gz", hash = "sha256:e96afd8e801e92c6863da0921e40a3b68f724804f888bce43791330658abdb0f", size = 40682, upload-time = "2025-11-14T10:23:17.456Z" } wheels = [ @@ -3159,10 +3159,10 @@ name = "pyobjc-framework-vision" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-coreml", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-quartz", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coreml" }, + { name = "pyobjc-framework-quartz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c2/5a/08bb3e278f870443d226c141af14205ff41c0274da1e053b72b11dfc9fb2/pyobjc_framework_vision-12.1.tar.gz", hash = "sha256:a30959100e85dcede3a786c544e621ad6eb65ff6abf85721f805822b8c5fe9b0", size = 59538, upload-time = "2025-11-14T10:23:21.979Z" } wheels = [ @@ -3178,8 +3178,8 @@ name = "pyobjc-framework-webkit" version = "12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyobjc-core", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, - { name = "pyobjc-framework-cocoa", marker = "(python_full_version != '3.13.*' and sys_platform == 'win32') or (platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'i686' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_machine != 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and sys_platform != 'win32')" }, + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/14/10/110a50e8e6670765d25190ca7f7bfeecc47ec4a8c018cb928f4f82c56e04/pyobjc_framework_webkit-12.1.tar.gz", hash = "sha256:97a54dd05ab5266bd4f614e41add517ae62cdd5a30328eabb06792474b37d82a", size = 284531, upload-time = "2025-11-14T10:23:40.287Z" } wheels = [ @@ -3392,7 +3392,7 @@ requires-dist = [ { name = "markdown", specifier = "~=3.6" }, { name = "platformdirs", specifier = "~=4.3" }, { name = "pyside6", specifier = "~=6.11.0" }, - { name = "pywin32", specifier = ">=311" }, + { name = "pywin32", marker = "sys_platform == 'win32'", specifier = ">=311" }, { name = "waitress", specifier = "~=3.0" }, { name = "websocket-client", specifier = ">=1.9.0" }, ] From bf8c6048daaa055f9a7f6bcb36ea99ff90ca2026 Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 15:30:59 +0100 Subject: [PATCH 13/28] Make ConnectionPipe a prefab --- src/splitguides/livesplit_client/connection_windows.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/splitguides/livesplit_client/connection_windows.py b/src/splitguides/livesplit_client/connection_windows.py index 096cabc..f2ae271 100644 --- a/src/splitguides/livesplit_client/connection_windows.py +++ b/src/splitguides/livesplit_client/connection_windows.py @@ -4,18 +4,22 @@ raise ImportError("'connection_windows.py' is not supported on platforms other than Windows") import time +import typing import pywintypes import win32file import win32pipe +from ducktools.classbuilder.prefab import prefab, attribute + from .connection_shared import ConnectionTypeBase +@prefab class ConnectionPipe(ConnectionTypeBase): - # pipe is Windows and localhost only, localhost setting is not checked - handle = None + # Not sure if there's a good type for `handle` + handle: typing.Any | None = attribute(default=None, init=False, repr=False) def connect(self) -> bool: self.close() From 9eba25e2b82ce6f676081cdc55bf1bf753dd86fb Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 15:31:59 +0100 Subject: [PATCH 14/28] Convert slotted prefabs to decorator form to allow for a new ABC metaclass --- src/splitguides/livesplit_client/connection_shared.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/splitguides/livesplit_client/connection_shared.py b/src/splitguides/livesplit_client/connection_shared.py index 676d4e5..6f3297b 100644 --- a/src/splitguides/livesplit_client/connection_shared.py +++ b/src/splitguides/livesplit_client/connection_shared.py @@ -1,7 +1,7 @@ import socket import websocket -from ducktools.classbuilder.prefab import Prefab, attribute +from ducktools.classbuilder.prefab import prefab, attribute BUFFER_SIZE = 4096 @@ -20,7 +20,8 @@ def send(self, msg: bytes) -> None: def receive(self) -> bytes: return b"" -class ConnectionTCP(ConnectionTypeBase, Prefab): +@prefab +class ConnectionTCP(ConnectionTypeBase): server: str = "localhost" port: int = 16834 timeout: int = 1 @@ -83,7 +84,8 @@ def receive(self) -> bytes: raise ConnectionError("The connection has been closed by the host") return data_received -class ConnectionWS(ConnectionTypeBase, Prefab): +@prefab +class ConnectionWS(ConnectionTypeBase): server: str = "localhost" port: int = 16834 timeout: int = 4 # 1 second not enough to establish a connection From b17e1ae90a1e25822a76759a42a1732b67d9a3bf Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 15:50:27 +0100 Subject: [PATCH 15/28] Make `ConnectionTypeBase` an ABC and define the methods as abstract. Check self.sock isn't None before trying to use it. (get rid of nasty red squiggles!) Move the `ping` logic into a separate static method. Close and set sock back to None if `ping` fails. --- .../livesplit_client/connection_shared.py | 59 ++++++++++++------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/src/splitguides/livesplit_client/connection_shared.py b/src/splitguides/livesplit_client/connection_shared.py index 6f3297b..d7756dd 100644 --- a/src/splitguides/livesplit_client/connection_shared.py +++ b/src/splitguides/livesplit_client/connection_shared.py @@ -1,3 +1,4 @@ +import abc import socket import websocket @@ -7,18 +8,23 @@ BUFFER_SIZE = 4096 -class ConnectionTypeBase: +class ConnectionTypeBase(abc.ABC): + @abc.abstractmethod def connect(self) -> bool: - return False + ... + @abc.abstractmethod def close(self) -> None: - return + ... + @abc.abstractmethod def send(self, msg: bytes) -> None: - return + ... + @abc.abstractmethod def receive(self) -> bytes: - return b"" + ... + @prefab class ConnectionTCP(ConnectionTypeBase): @@ -32,25 +38,29 @@ def connect(self) -> bool: self.sock = socket.socket() try: self.sock.connect((self.server, self.port)) - self.sock.settimeout(self.timeout) - # We need to ping the connection to make sure we are connected to a TCP server, - # the Websocket server also allows this socket connection - self.sock.send(b"ping\r\n") - ping_resp = self.sock.recv(BUFFER_SIZE).decode("UTF-8").strip("\r\n") - return (ping_resp == "pong") - except TimeoutError: - self.sock.close() - self.sock = None - return False - except ConnectionRefusedError: + except (ConnectionRefusedError, socket.gaierror): + # gaierror is raised if it could not resolve hostname self.sock.close() self.sock = None return False - except socket.gaierror: - # Could not resolve hostname - self.sock.close() - self.sock = None + else: + self.sock.settimeout(self.timeout) + if self._ping(self.sock): + return True + else: + self.sock.close() + self.sock = None + return False + + @staticmethod + def _ping(sock) -> bool: + try: + sock.send(b"ping\r\n") + ping_resp = sock.recv(BUFFER_SIZE).decode("UTF-8").strip("\r\n") + except (TimeoutError, ConnectionError): return False + else: + return ping_resp == "pong" def close(self) -> None: if self.sock: @@ -58,14 +68,21 @@ def close(self) -> None: self.sock = None def send(self, msg: bytes) -> None: + if not self.sock: + raise ConnectionError("The connection has not yet been established") + try: self.sock.send(msg + b"\r\n") - except: + except ConnectionAbortedError: self.sock.close() self.sock = None raise ConnectionError("The connection has been closed by the host") + def receive(self) -> bytes: + if not self.sock: + raise ConnectionError("The connection has not yet been established") + data_received = b"" try: data_received = self.sock.recv(BUFFER_SIZE) From 9e6837dd99814f1d7fd2b28d5d5d7e7295db103f Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 16:07:17 +0100 Subject: [PATCH 16/28] de-duplication of errors --- .../livesplit_client/connection_shared.py | 70 ++++++++++--------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/src/splitguides/livesplit_client/connection_shared.py b/src/splitguides/livesplit_client/connection_shared.py index d7756dd..76448e8 100644 --- a/src/splitguides/livesplit_client/connection_shared.py +++ b/src/splitguides/livesplit_client/connection_shared.py @@ -1,5 +1,6 @@ import abc import socket +import typing import websocket from ducktools.classbuilder.prefab import prefab, attribute @@ -17,6 +18,10 @@ def connect(self) -> bool: def close(self) -> None: ... + def closed_by_host(self) -> typing.NoReturn: + self.close() + raise ConnectionError("The connection has been closed by the host") + @abc.abstractmethod def send(self, msg: bytes) -> None: ... @@ -40,17 +45,15 @@ def connect(self) -> bool: self.sock.connect((self.server, self.port)) except (ConnectionRefusedError, socket.gaierror): # gaierror is raised if it could not resolve hostname - self.sock.close() - self.sock = None + self.close() return False + + self.sock.settimeout(self.timeout) + if self._ping(self.sock): + return True else: - self.sock.settimeout(self.timeout) - if self._ping(self.sock): - return True - else: - self.sock.close() - self.sock = None - return False + self.close() + return False @staticmethod def _ping(sock) -> bool: @@ -74,10 +77,7 @@ def send(self, msg: bytes) -> None: try: self.sock.send(msg + b"\r\n") except ConnectionAbortedError: - self.sock.close() - self.sock = None - raise ConnectionError("The connection has been closed by the host") - + self.closed_by_host() def receive(self) -> bytes: if not self.sock: @@ -92,13 +92,11 @@ def receive(self) -> bytes: f"the timeout period ({self.timeout}s)" ) except OSError: - self.sock.close() - self.sock = None - raise ConnectionError("The connection has been closed by the host") + self.closed_by_host() + if data_received == b"": - self.sock.close() - self.sock = None - raise ConnectionError("The connection has been closed by the host") + self.closed_by_host() + return data_received @prefab @@ -114,9 +112,9 @@ def connect(self) -> bool: try: self.ws.connect(f"ws://{self.server}:{self.port}/livesplit", origin="SplitGuides", timeout=self.timeout) return True - except Exception as e: - self.ws.close() - self.ws = None + except Exception: + # TODO: More precise exception here - like for ConnectionTCP + self.close() return False def close(self) -> None: @@ -125,25 +123,29 @@ def close(self) -> None: self.ws = None def send(self, msg: bytes) -> None: + if not self.ws: + raise ConnectionError("The connection has not yet been established") try: self.ws.send(msg) # no CRLF on Websocket - except Exception as e: - self.ws.close() - self.ws = None - raise ConnectionError("The connection has been closed by the host") + except Exception: + # TODO: More precise exception here + self.closed_by_host() def receive(self) -> bytes: + if not self.ws: + raise ConnectionError("The connection has not yet been established") + try: - data_received : bytes = self.ws.recv() - except Exception as e: - self.ws.close() - self.ws = None - raise ConnectionError("The connection has been closed by the host") + data_received = self.ws.recv() + except Exception: + # TODO: More precise exception here + self.closed_by_host() + if isinstance(data_received, str): # should always be string, encode to bytes for unified handling data_received = data_received.encode("UTF8") + if data_received == b"": - self.ws.close() - self.ws = None - raise ConnectionError("The connection has been closed by the host") + self.closed_by_host() + return data_received From 54dd1680b71e01999d01cde6a8c353afca11c9ec Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 16:14:46 +0100 Subject: [PATCH 17/28] Start putting logic in place to simplify `LivesplitConnection` --- .../livesplit_client/connection_shared.py | 6 ++++++ .../livesplit_client/connection_windows.py | 21 +++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/splitguides/livesplit_client/connection_shared.py b/src/splitguides/livesplit_client/connection_shared.py index 76448e8..d185453 100644 --- a/src/splitguides/livesplit_client/connection_shared.py +++ b/src/splitguides/livesplit_client/connection_shared.py @@ -10,6 +10,8 @@ class ConnectionTypeBase(abc.ABC): + NAME: typing.ClassVar[str] = "" + @abc.abstractmethod def connect(self) -> bool: ... @@ -33,6 +35,8 @@ def receive(self) -> bytes: @prefab class ConnectionTCP(ConnectionTypeBase): + NAME: typing.ClassVar[str] = "TCP" + server: str = "localhost" port: int = 16834 timeout: int = 1 @@ -101,6 +105,8 @@ def receive(self) -> bytes: @prefab class ConnectionWS(ConnectionTypeBase): + NAME: typing.ClassVar[str] = "WebSocket" + server: str = "localhost" port: int = 16834 timeout: int = 4 # 1 second not enough to establish a connection diff --git a/src/splitguides/livesplit_client/connection_windows.py b/src/splitguides/livesplit_client/connection_windows.py index f2ae271..2b65e8e 100644 --- a/src/splitguides/livesplit_client/connection_windows.py +++ b/src/splitguides/livesplit_client/connection_windows.py @@ -13,16 +13,26 @@ from ducktools.classbuilder.prefab import prefab, attribute -from .connection_shared import ConnectionTypeBase +from .connection_shared import BUFFER_SIZE, ConnectionTypeBase +# These all refer to the local machine and are used to decide if named pipes should be checked +LOOPBACK_HOSTS = {"localhost", "127.0.0.1", "::1"} @prefab class ConnectionPipe(ConnectionTypeBase): + NAME: typing.ClassVar[str] = "Named Pipe" + + hostname: str = "localhost" # Used to check if this should be ignored. + # Not sure if there's a good type for `handle` handle: typing.Any | None = attribute(default=None, init=False, repr=False) def connect(self) -> bool: self.close() + + if self.hostname not in LOOPBACK_HOSTS: + return False + try: self.handle = win32file.CreateFile( r'\\.\pipe\livesplit', @@ -50,6 +60,9 @@ def close(self) -> None: self.handle = None def send(self, msg: bytes) -> None: + if not self.handle: + raise ConnectionError("The connection has not yet been established") + try: win32file.WriteFile(self.handle, msg + b"\r\n") except Exception as e: @@ -58,6 +71,9 @@ def send(self, msg: bytes) -> None: raise ConnectionError("Pipe sending error: " + str(e)) def receive(self) -> bytes: + if not self.handle: + raise ConnectionError("The connection has not yet been established") + try: # wait a bit for data to arrive, the ReadFile would stall otherwise time.sleep(0.05) @@ -68,4 +84,5 @@ def receive(self) -> bytes: win32file.CloseHandle(self.handle) self.handle = None raise ConnectionError("Pipe broken: " + str(e)) - return data_received + + return data_received.encode("UTF8") From bc3c68b6b589a1a2a2f782c8168f9023bf66e5b8 Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 16:15:49 +0100 Subject: [PATCH 18/28] Create a CONNECTION_TYPES list of appropriate connection types. --- src/splitguides/livesplit_client/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/splitguides/livesplit_client/__init__.py b/src/splitguides/livesplit_client/__init__.py index 315ac92..2cf436b 100644 --- a/src/splitguides/livesplit_client/__init__.py +++ b/src/splitguides/livesplit_client/__init__.py @@ -10,7 +10,9 @@ if sys.platform == "win32": from .connection_windows import ConnectionPipe - + CONNECTION_TYPES = [ConnectionPipe, ConnectionTCP, ConnectionWS] +else: + CONNECTION_TYPES = [ConnectionTCP, ConnectionWS] pattern = re.compile( r"^(?:(?P\d*):)?(?P\d{1,2}):(?P\d{2}).(?P\d*)" From c526a0482e7a5f68617b9fdb8a0a0af8f6cfab2b Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 16:17:55 +0100 Subject: [PATCH 19/28] Make connection_obj visible and replaceable on `__init__` This will make it easy to force a specific connection for testing. --- src/splitguides/livesplit_client/__init__.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/splitguides/livesplit_client/__init__.py b/src/splitguides/livesplit_client/__init__.py index 2cf436b..af65b5a 100644 --- a/src/splitguides/livesplit_client/__init__.py +++ b/src/splitguides/livesplit_client/__init__.py @@ -55,11 +55,12 @@ class LivesplitConnection(Prefab): server: str = "localhost" port: int = 16834 - stable_type : int = attribute(default=-1, init=False, repr=False) - stable_retry : int = attribute(default=0, init=False, repr=False) - next_attempt_idx : int = attribute(default=0, init=False, repr=False) - connection_obj : ConnectionTypeBase | None = attribute(default=None, init=False, repr=False) - list_connection_types : list = attribute(default=[], init=False, repr=False) + connection_obj: ConnectionTypeBase | None = None + + stable_type: int = attribute(default=-1, init=False, repr=False) + stable_retry: int = attribute(default=0, init=False, repr=False) + next_attempt_idx: int = attribute(default=0, init=False, repr=False) + list_connection_types: list = attribute(default=[], init=False, repr=False) def _get_valid_list(self): if sys.platform != "win32": From 4b59aaf81ec2721c7fa3fe14529162767f0c235d Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 16:45:13 +0100 Subject: [PATCH 20/28] Only test TCP in the networking tests - for some reason the websocket connection hangs with the mocks in place. --- ...t_networking.py => test_connection_tcp.py} | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) rename tests/test_livesplit_client/{test_networking.py => test_connection_tcp.py} (87%) diff --git a/tests/test_livesplit_client/test_networking.py b/tests/test_livesplit_client/test_connection_tcp.py similarity index 87% rename from tests/test_livesplit_client/test_networking.py rename to tests/test_livesplit_client/test_connection_tcp.py index 4f24a71..1c2b56d 100644 --- a/tests/test_livesplit_client/test_networking.py +++ b/tests/test_livesplit_client/test_connection_tcp.py @@ -3,11 +3,12 @@ import pytest -from splitguides.livesplit_client import LivesplitConnection, BUFFER_SIZE +from splitguides.livesplit_client import ConnectionTCP +from splitguides.livesplit_client.connection_shared import BUFFER_SIZE def test_init(): - connection = LivesplitConnection(server="hostname", port=12, timeout=2) + connection = ConnectionTCP(server="hostname", port=12, timeout=2) assert connection.server == "hostname" assert connection.port == 12 assert connection.timeout == 2 @@ -19,7 +20,7 @@ def test_connect(): mock_sock = MagicMock() mock_socket.return_value = mock_sock - connection = LivesplitConnection(server="host", port=12, timeout=2) + connection = ConnectionTCP(server="host", port=12, timeout=2) response = connection.connect() mock_socket.assert_called_once() @@ -35,7 +36,7 @@ def test_failed_connect(): mock_socket.return_value = mock_sock mock_sock.connect.side_effect = ConnectionRefusedError("Should be handled") - connection = LivesplitConnection() + connection = ConnectionTCP() response = connection.connect() @@ -47,7 +48,7 @@ def test_close(): mock_sock = MagicMock() mock_socket.return_value = mock_sock - connection = LivesplitConnection() + connection = ConnectionTCP() connection.connect() connection.close() @@ -66,7 +67,7 @@ def test_send(connect_first): mock_sock = MagicMock() mock_socket.return_value = mock_sock - connection = LivesplitConnection() + connection = ConnectionTCP() if connect_first: connection.connect() @@ -84,7 +85,7 @@ def test_send_fail(): mock_socket.return_value = mock_sock mock_sock.send.side_effect = ConnectionAbortedError("Should be caught") - connection = LivesplitConnection() + connection = ConnectionTCP() with pytest.raises(ConnectionAbortedError): connection.send(b"test message") @@ -103,7 +104,7 @@ def test_receive(connect_first): mock_sock.recv.return_value = b"returned data" - connection = LivesplitConnection() + connection = ConnectionTCP() if connect_first: connection.connect() @@ -122,7 +123,7 @@ def test_receive_empty(): mock_sock.recv.return_value = b"" - connection = LivesplitConnection() + connection = ConnectionTCP() with pytest.raises(ConnectionError): connection.receive() @@ -138,7 +139,7 @@ def test_receive_timeout(): mock_sock.recv.side_effect = socket.timeout() - connection = LivesplitConnection() + connection = ConnectionTCP() with pytest.raises(TimeoutError): connection.receive() @@ -154,7 +155,7 @@ def test_receive_oserror(): mock_sock.recv.side_effect = OSError("Confusing windows message.") - connection = LivesplitConnection() + connection = ConnectionTCP() with pytest.raises(ConnectionError): connection.receive() From 93bd5cd469d82233b5a9798c10e7f9384664779c Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 16:54:03 +0100 Subject: [PATCH 21/28] Major simplification of connect logic for LivesplitConnection.connect All connection types now have hostname and port even if port isn't used for the pipe connection. Instead of trying a different connection type on each call to `.connect`, this tries them all in order and stops on the first successful one. --- src/splitguides/livesplit_client/__init__.py | 104 +++++------------- .../livesplit_client/connection_shared.py | 11 +- .../livesplit_client/connection_windows.py | 5 +- 3 files changed, 31 insertions(+), 89 deletions(-) diff --git a/src/splitguides/livesplit_client/__init__.py b/src/splitguides/livesplit_client/__init__.py index af65b5a..a907a3a 100644 --- a/src/splitguides/livesplit_client/__init__.py +++ b/src/splitguides/livesplit_client/__init__.py @@ -4,9 +4,15 @@ from datetime import timedelta import typing -from ducktools.classbuilder.prefab import Prefab, attribute +from ducktools.classbuilder.prefab import Prefab -from .connection_shared import ConnectionTypeBase, ConnectionTCP, ConnectionWS +from .connection_shared import ( + ConnectionTypeBase, + ConnectionTCP, + ConnectionWS +) + +CONNECTION_TYPES: list[type[ConnectionTypeBase]] if sys.platform == "win32": from .connection_windows import ConnectionPipe @@ -42,12 +48,6 @@ def parse_time(time_str: str) -> timedelta: return result -CONNECTIONTYPE_PIPE=0 -CONNECTIONTYPE_TCP=1 -CONNECTIONTYPE_WS=2 - -STABLE_RETRY=10 - class LivesplitConnection(Prefab): """ Livesplit connection model supporting Named Pipe (Windows-only), TCP and Websocket connections @@ -57,35 +57,12 @@ class LivesplitConnection(Prefab): connection_obj: ConnectionTypeBase | None = None - stable_type: int = attribute(default=-1, init=False, repr=False) - stable_retry: int = attribute(default=0, init=False, repr=False) - next_attempt_idx: int = attribute(default=0, init=False, repr=False) - list_connection_types: list = attribute(default=[], init=False, repr=False) - - def _get_valid_list(self): - if sys.platform != "win32": - self.list_connection_types = [CONNECTIONTYPE_TCP, CONNECTIONTYPE_WS] - return - # these hostnames will try the Named Pipe on Windows along with the other types - loopback_hosts = ["localhost", "127.0.0.1", "::1"] - if self.server.lower() in loopback_hosts: - self.list_connection_types = [CONNECTIONTYPE_PIPE, CONNECTIONTYPE_TCP, CONNECTIONTYPE_WS] - else: - self.list_connection_types = [CONNECTIONTYPE_TCP, CONNECTIONTYPE_WS] - def is_connected(self) -> bool: return (bool)(self.connection_obj) def get_connection_friendly_name(self) -> str: if self.connection_obj: - if self.stable_type == CONNECTIONTYPE_PIPE: - status = "Named Pipe" - elif self.stable_type == CONNECTIONTYPE_TCP: - status = "TCP" - elif self.stable_type == CONNECTIONTYPE_WS: - status = "Websocket" - else: - status = "" + status = self.connection_obj.NAME else: status = "" return status @@ -95,49 +72,19 @@ def connect(self) -> bool: Attempt to connect to the livesplit server :return: True if connected, otherwise False """ - if len(self.list_connection_types) == 0: - # post init to fill the valid connections once - self._get_valid_list() - self.close() - if self.stable_type >= 0: - cur_type : int = self.stable_type + for connection_type in CONNECTION_TYPES: + # Try each connection type in succession, accept the first successful connection type + connection = connection_type(self.server, self.port) + connection_success = connection.connect() + if connection_success: + self.connection_obj = connection + break else: - cur_type : int = self.list_connection_types[self.next_attempt_idx] - - if cur_type == CONNECTIONTYPE_PIPE: - self.connection_obj = ConnectionPipe() - elif cur_type == CONNECTIONTYPE_TCP: - self.connection_obj = ConnectionTCP(self.server, self.port) - elif cur_type == CONNECTIONTYPE_WS: - self.connection_obj = ConnectionWS(self.server, self.port) - else: # out of range, logic error - raise Exception('logic error') - - connection_successful = self.connection_obj.connect() - - if connection_successful: - if self.stable_type >= 0: - # restablished after connection drop - self.stable_retry = 0 - else: - # connected after searching - self.stable_type = cur_type - self.stable_retry = 0 - else: - self.connection_obj = None - if self.stable_type >= 0: - # try to reconnect on that method - self.stable_retry += 1 - if self.stable_retry >= STABLE_RETRY: - # give up on the stable index - self.stable_type = -1 - self.next_attempt_idx = 0 - else: - # try next method - self.next_attempt_idx = (self.next_attempt_idx + 1) % len(self.list_connection_types) - return connection_successful + connection_success = False + + return connection_success def close(self) -> None: if self.connection_obj: @@ -153,10 +100,8 @@ def send(self, msg: bytes) -> None: :param msg: bytes message to send :return: """ - if not self.is_connected(): - return - - self.connection_obj.send(msg) + if self.connection_obj: + self.connection_obj.send(msg) def receive(self) -> bytes: """ @@ -165,10 +110,11 @@ def receive(self) -> bytes: :return: bytes or string received from the server """ - if not self.is_connected(): + if self.connection_obj: + return self.connection_obj.receive() + else: return b"" - return self.connection_obj.receive() class LivesplitMessaging(Prefab): connection: LivesplitConnection @@ -294,7 +240,7 @@ def get_delta(self, comparison=None) -> str: if comparison: self.send(f"getdelta {comparison}") else: - self.send(f"getdelta") + self.send("getdelta") return self.receive() diff --git a/src/splitguides/livesplit_client/connection_shared.py b/src/splitguides/livesplit_client/connection_shared.py index d185453..bc3d8cf 100644 --- a/src/splitguides/livesplit_client/connection_shared.py +++ b/src/splitguides/livesplit_client/connection_shared.py @@ -9,8 +9,11 @@ BUFFER_SIZE = 4096 +@prefab class ConnectionTypeBase(abc.ABC): NAME: typing.ClassVar[str] = "" + server: str = "localhost" + port: int = 16834 @abc.abstractmethod def connect(self) -> bool: @@ -36,9 +39,6 @@ def receive(self) -> bytes: @prefab class ConnectionTCP(ConnectionTypeBase): NAME: typing.ClassVar[str] = "TCP" - - server: str = "localhost" - port: int = 16834 timeout: int = 1 sock: socket.socket | None = attribute(default=None, init=False, repr=False) @@ -107,8 +107,6 @@ def receive(self) -> bytes: class ConnectionWS(ConnectionTypeBase): NAME: typing.ClassVar[str] = "WebSocket" - server: str = "localhost" - port: int = 16834 timeout: int = 4 # 1 second not enough to establish a connection ws: websocket.WebSocket | None = attribute(default=None, init=False, repr=False) @@ -118,8 +116,7 @@ def connect(self) -> bool: try: self.ws.connect(f"ws://{self.server}:{self.port}/livesplit", origin="SplitGuides", timeout=self.timeout) return True - except Exception: - # TODO: More precise exception here - like for ConnectionTCP + except ConnectionRefusedError: self.close() return False diff --git a/src/splitguides/livesplit_client/connection_windows.py b/src/splitguides/livesplit_client/connection_windows.py index 2b65e8e..baf3a21 100644 --- a/src/splitguides/livesplit_client/connection_windows.py +++ b/src/splitguides/livesplit_client/connection_windows.py @@ -17,13 +17,12 @@ # These all refer to the local machine and are used to decide if named pipes should be checked LOOPBACK_HOSTS = {"localhost", "127.0.0.1", "::1"} +LIVESPLIT_PIPE = r'\\.\pipe\livesplit' @prefab class ConnectionPipe(ConnectionTypeBase): NAME: typing.ClassVar[str] = "Named Pipe" - hostname: str = "localhost" # Used to check if this should be ignored. - # Not sure if there's a good type for `handle` handle: typing.Any | None = attribute(default=None, init=False, repr=False) @@ -35,7 +34,7 @@ def connect(self) -> bool: try: self.handle = win32file.CreateFile( - r'\\.\pipe\livesplit', + LIVESPLIT_PIPE, win32file.GENERIC_READ | win32file.GENERIC_WRITE, 0, None, From ea552c5da826812f17d46e85f8931fd2e91b53af Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 17:22:50 +0100 Subject: [PATCH 22/28] The attribute is called 'server' not 'hostname' *headdesk* --- src/splitguides/livesplit_client/connection_windows.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/splitguides/livesplit_client/connection_windows.py b/src/splitguides/livesplit_client/connection_windows.py index baf3a21..610d08a 100644 --- a/src/splitguides/livesplit_client/connection_windows.py +++ b/src/splitguides/livesplit_client/connection_windows.py @@ -29,7 +29,7 @@ class ConnectionPipe(ConnectionTypeBase): def connect(self) -> bool: self.close() - if self.hostname not in LOOPBACK_HOSTS: + if self.server not in LOOPBACK_HOSTS: return False try: From 7024708b4eea0706d0530c38d6ead85572013125 Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 17:36:30 +0100 Subject: [PATCH 23/28] type checking leading me astray? --- src/splitguides/livesplit_client/connection_windows.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/splitguides/livesplit_client/connection_windows.py b/src/splitguides/livesplit_client/connection_windows.py index 610d08a..abff4c4 100644 --- a/src/splitguides/livesplit_client/connection_windows.py +++ b/src/splitguides/livesplit_client/connection_windows.py @@ -84,4 +84,7 @@ def receive(self) -> bytes: self.handle = None raise ConnectionError("Pipe broken: " + str(e)) - return data_received.encode("UTF8") + # Type checkers report it as str, but it does appear to be bytes + assert isinstance(data_received, bytes) + + return data_received From 53d4c85d77b3bfa123ba3918aa439747433bab01 Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 17:49:51 +0100 Subject: [PATCH 24/28] Remove unnecessary parentheses around bool --- src/splitguides/livesplit_client/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/splitguides/livesplit_client/__init__.py b/src/splitguides/livesplit_client/__init__.py index a907a3a..f86887a 100644 --- a/src/splitguides/livesplit_client/__init__.py +++ b/src/splitguides/livesplit_client/__init__.py @@ -58,7 +58,7 @@ class LivesplitConnection(Prefab): connection_obj: ConnectionTypeBase | None = None def is_connected(self) -> bool: - return (bool)(self.connection_obj) + return bool(self.connection_obj) def get_connection_friendly_name(self) -> str: if self.connection_obj: From 471a8f661e9d8ba051167134b2fc001984c51483 Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 17:59:34 +0100 Subject: [PATCH 25/28] Make it possible to narrow the connection types on the connection. --- src/splitguides/livesplit_client/__init__.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/splitguides/livesplit_client/__init__.py b/src/splitguides/livesplit_client/__init__.py index f86887a..55c54ac 100644 --- a/src/splitguides/livesplit_client/__init__.py +++ b/src/splitguides/livesplit_client/__init__.py @@ -4,7 +4,7 @@ from datetime import timedelta import typing -from ducktools.classbuilder.prefab import Prefab +from ducktools.classbuilder.prefab import Prefab, attribute from .connection_shared import ( ConnectionTypeBase, @@ -12,13 +12,13 @@ ConnectionWS ) -CONNECTION_TYPES: list[type[ConnectionTypeBase]] +CONNECTION_TYPES: tuple[type[ConnectionTypeBase], ...] if sys.platform == "win32": from .connection_windows import ConnectionPipe - CONNECTION_TYPES = [ConnectionPipe, ConnectionTCP, ConnectionWS] + CONNECTION_TYPES = (ConnectionPipe, ConnectionTCP, ConnectionWS) else: - CONNECTION_TYPES = [ConnectionTCP, ConnectionWS] + CONNECTION_TYPES = (ConnectionTCP, ConnectionWS) pattern = re.compile( r"^(?:(?P\d*):)?(?P\d{1,2}):(?P\d{2}).(?P\d*)" @@ -55,7 +55,9 @@ class LivesplitConnection(Prefab): server: str = "localhost" port: int = 16834 - connection_obj: ConnectionTypeBase | None = None + # Make it possible to replace the possible connection types for testing, but see the actual type for debugging + connection_obj: ConnectionTypeBase | None = attribute(default=None, init=False) + connection_types: tuple[type[ConnectionTypeBase], ...] = attribute(default=CONNECTION_TYPES, repr=False) def is_connected(self) -> bool: return bool(self.connection_obj) @@ -74,7 +76,7 @@ def connect(self) -> bool: """ self.close() - for connection_type in CONNECTION_TYPES: + for connection_type in self.connection_types: # Try each connection type in succession, accept the first successful connection type connection = connection_type(self.server, self.port) connection_success = connection.connect() From f56770674aa70a38e6ada7f2f18b49aa5e7a5b3e Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Wed, 1 Jul 2026 18:03:35 +0100 Subject: [PATCH 26/28] Use a cast instead of an assert. --- src/splitguides/livesplit_client/connection_windows.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/splitguides/livesplit_client/connection_windows.py b/src/splitguides/livesplit_client/connection_windows.py index abff4c4..f11e259 100644 --- a/src/splitguides/livesplit_client/connection_windows.py +++ b/src/splitguides/livesplit_client/connection_windows.py @@ -85,6 +85,6 @@ def receive(self) -> bytes: raise ConnectionError("Pipe broken: " + str(e)) # Type checkers report it as str, but it does appear to be bytes - assert isinstance(data_received, bytes) + data_received = typing.cast(bytes, data_received) return data_received From c23519ee4e132ca99543f10d526b4dca267c83ee Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Wed, 8 Jul 2026 23:10:19 +0200 Subject: [PATCH 27/28] Adapt tests --- .../test_connection_tcp.py | 98 ++++++++++++++----- tests/test_livesplit_client/test_messaging.py | 56 +++++------ 2 files changed, 99 insertions(+), 55 deletions(-) diff --git a/tests/test_livesplit_client/test_connection_tcp.py b/tests/test_livesplit_client/test_connection_tcp.py index 1c2b56d..57946eb 100644 --- a/tests/test_livesplit_client/test_connection_tcp.py +++ b/tests/test_livesplit_client/test_connection_tcp.py @@ -3,8 +3,7 @@ import pytest -from splitguides.livesplit_client import ConnectionTCP -from splitguides.livesplit_client.connection_shared import BUFFER_SIZE +from splitguides.livesplit_client.connection_shared import ConnectionTCP, BUFFER_SIZE def test_init(): @@ -16,10 +15,12 @@ def test_init(): def test_connect(): - with patch("socket.socket") as mock_socket: + with patch("socket.socket") as mock_socket, patch("splitguides.livesplit_client.connection_shared.ConnectionTCP._ping") as mock_ping: mock_sock = MagicMock() mock_socket.return_value = mock_sock + mock_ping.return_value = True + connection = ConnectionTCP(server="host", port=12, timeout=2) response = connection.connect() @@ -27,14 +28,18 @@ def test_connect(): mock_sock.connect.assert_called_with(("host", 12)) mock_sock.settimeout.assert_called_with(2) - assert response is True + mock_ping.assert_called_once() + mock_ping.assert_called_with(mock_sock) + assert response is True def test_failed_connect(): - with patch("socket.socket") as mock_socket: + with patch("socket.socket") as mock_socket, patch("splitguides.livesplit_client.connection_shared.ConnectionTCP._ping") as mock_ping: mock_sock = MagicMock() mock_socket.return_value = mock_sock + mock_ping.return_value = True + mock_sock.connect.side_effect = ConnectionRefusedError("Should be handled") connection = ConnectionTCP() @@ -42,12 +47,27 @@ def test_failed_connect(): assert response is False +def test_connected_to_websocket(): + with patch("socket.socket") as mock_socket: + mock_sock = MagicMock() + mock_socket.return_value = mock_sock + mock_sock.recv.side_effect = TimeoutError("Timeout on TCP connection to Websocket") + + connection = ConnectionTCP(server="host", port=12, timeout=2) + response = connection.connect() + + mock_socket.assert_called_once() + mock_sock.connect.assert_called_with(("host", 12)) + + assert response is False def test_close(): - with patch("socket.socket") as mock_socket: + with patch("socket.socket") as mock_socket, patch("splitguides.livesplit_client.connection_shared.ConnectionTCP._ping") as mock_ping: mock_sock = MagicMock() mock_socket.return_value = mock_sock + mock_ping.return_value = True + connection = ConnectionTCP() connection.connect() @@ -61,53 +81,52 @@ def test_close(): mock_sock.close.assert_not_called() -@pytest.mark.parametrize("connect_first", [True, False]) -def test_send(connect_first): - with patch("socket.socket") as mock_socket: +def test_send(): + with patch("socket.socket") as mock_socket, patch("splitguides.livesplit_client.connection_shared.ConnectionTCP._ping") as mock_ping: mock_sock = MagicMock() mock_socket.return_value = mock_sock + mock_ping.return_value = True + connection = ConnectionTCP() - if connect_first: - connection.connect() + connection.connect() connection.send(b"test message") mock_socket.assert_called_once() mock_sock.connect.assert_called_with(("localhost", 16834)) - mock_sock.send.assert_called_with(b"test message") + mock_sock.send.assert_called_with(b"test message\r\n") def test_send_fail(): - with patch("socket.socket") as mock_socket: + with patch("socket.socket") as mock_socket, patch("splitguides.livesplit_client.connection_shared.ConnectionTCP._ping") as mock_ping: mock_sock = MagicMock() mock_socket.return_value = mock_sock - mock_sock.send.side_effect = ConnectionAbortedError("Should be caught") + mock_sock.send.side_effect = ConnectionError("Should be caught") + + mock_ping.return_value = True connection = ConnectionTCP() - with pytest.raises(ConnectionAbortedError): + with pytest.raises(ConnectionError): connection.send(b"test message") - mock_sock.send.assert_called_with(b"test message") - - mock_sock.close.assert_called_once() assert connection.sock is None -@pytest.mark.parametrize("connect_first", [True, False]) -def test_receive(connect_first): - with patch("socket.socket") as mock_socket: +def test_receive(): + with patch("socket.socket") as mock_socket, patch("splitguides.livesplit_client.connection_shared.ConnectionTCP._ping") as mock_ping: mock_sock = MagicMock() mock_socket.return_value = mock_sock + mock_ping.return_value = True + mock_sock.recv.return_value = b"returned data" connection = ConnectionTCP() - if connect_first: - connection.connect() + connection.connect() result = connection.receive() @@ -117,10 +136,12 @@ def test_receive(connect_first): def test_receive_empty(): - with patch("socket.socket") as mock_socket: + with patch("socket.socket") as mock_socket, patch("splitguides.livesplit_client.connection_shared.ConnectionTCP._ping") as mock_ping: mock_sock = MagicMock() mock_socket.return_value = mock_sock + mock_ping.return_value = True + mock_sock.recv.return_value = b"" connection = ConnectionTCP() @@ -128,18 +149,20 @@ def test_receive_empty(): with pytest.raises(ConnectionError): connection.receive() - mock_sock.close.assert_called_once() assert connection.sock is None def test_receive_timeout(): - with patch("socket.socket") as mock_socket: + with patch("socket.socket") as mock_socket, patch("splitguides.livesplit_client.connection_shared.ConnectionTCP._ping") as mock_ping: mock_sock = MagicMock() mock_socket.return_value = mock_sock + mock_ping.return_value = True + mock_sock.recv.side_effect = socket.timeout() connection = ConnectionTCP() + connection.connect() with pytest.raises(TimeoutError): connection.receive() @@ -149,13 +172,34 @@ def test_receive_timeout(): def test_receive_oserror(): - with patch("socket.socket") as mock_socket: + with patch("socket.socket") as mock_socket, patch("splitguides.livesplit_client.connection_shared.ConnectionTCP._ping") as mock_ping: mock_sock = MagicMock() mock_socket.return_value = mock_sock + mock_ping.return_value = True + mock_sock.recv.side_effect = OSError("Confusing windows message.") connection = ConnectionTCP() + connection.connect() + + with pytest.raises(ConnectionError): + connection.receive() + + mock_sock.close.assert_called_once() + assert connection.sock is None + +def test_receive_server_closed(): + with patch("socket.socket") as mock_socket, patch("splitguides.livesplit_client.connection_shared.ConnectionTCP._ping") as mock_ping: + mock_sock = MagicMock() + mock_socket.return_value = mock_sock + + mock_ping.return_value = True + + mock_sock.recv.return_value = b"" + + connection = ConnectionTCP() + connection.connect() with pytest.raises(ConnectionError): connection.receive() diff --git a/tests/test_livesplit_client/test_messaging.py b/tests/test_livesplit_client/test_messaging.py index 4560fbf..5f7dd05 100644 --- a/tests/test_livesplit_client/test_messaging.py +++ b/tests/test_livesplit_client/test_messaging.py @@ -41,7 +41,7 @@ def test_send(): messager = LivesplitMessaging(fake_connection) messager.send("Test message") - fake_connection.send.assert_called_with(b"Test message\r\n") + fake_connection.send.assert_called_with(b"Test message") def test_send_only_messages(): @@ -52,20 +52,20 @@ def test_send_only_messages(): messager = LivesplitMessaging(fake_connection) expected = [ - call(b"starttimer\r\n"), - call(b"startorsplit\r\n"), - call(b"split\r\n"), - call(b"unsplit\r\n"), - call(b"skipsplit\r\n"), - call(b"pause\r\n"), - call(b"resume\r\n"), - call(b"reset\r\n"), - call(b"initgametime\r\n"), - call(b"setgametime 2\r\n"), - call(b"setloadingtimes 12\r\n"), - call(b"pausegametime\r\n"), - call(b"unpausegametime\r\n"), - call(b"setcomparison Personal Best\r\n"), + call(b"starttimer"), + call(b"startorsplit"), + call(b"split"), + call(b"unsplit"), + call(b"skipsplit"), + call(b"pause"), + call(b"resume"), + call(b"reset"), + call(b"initgametime"), + call(b"setgametime 2"), + call(b"setloadingtimes 12"), + call(b"pausegametime"), + call(b"unpausegametime"), + call(b"setcomparison Personal Best"), ] messager.start_timer() @@ -124,7 +124,7 @@ def test_get_delta(): fake_connection.receive.return_value = b"+2\r\n" delta = messager.get_delta() - fake_connection.send.assert_called_with(b"getdelta\r\n") + fake_connection.send.assert_called_with(b"getdelta") fake_connection.receive.assert_called_once() assert delta == "+2" @@ -133,7 +133,7 @@ def test_get_delta(): fake_connection.receive.return_value = b"-12\r\n" delta = messager.get_delta("Personal Best") - fake_connection.send.assert_called_with(b"getdelta Personal Best\r\n") + fake_connection.send.assert_called_with(b"getdelta Personal Best") fake_connection.receive.assert_called_once() assert delta == "-12" @@ -141,11 +141,11 @@ def test_get_delta(): @pytest.mark.parametrize( "funcname, message", [ - ("get_last_split_time", b"getlastsplittime\r\n"), - ("get_comparison_split_time", b"getcomparisonsplittime\r\n"), - ("get_current_time", b"getcurrenttime\r\n"), - ("get_best_possible_time", b"getbestpossibletime\r\n"), - ("get_final_time", b"getfinaltime\r\n"), + ("get_last_split_time", b"getlastsplittime"), + ("get_comparison_split_time", b"getcomparisonsplittime"), + ("get_current_time", b"getcurrenttime"), + ("get_best_possible_time", b"getbestpossibletime"), + ("get_final_time", b"getfinaltime"), ], ) def test_get_times(funcname, message): @@ -165,8 +165,8 @@ def test_get_times(funcname, message): @pytest.mark.parametrize( "funcname, message", [ - ("get_final_time", b"getfinaltime Personal Best\r\n"), - ("get_predicted_time", b"getpredictedtime Personal Best\r\n"), + ("get_final_time", b"getfinaltime Personal Best"), + ("get_predicted_time", b"getpredictedtime Personal Best"), ], ) def test_get_times_pb(funcname, message): @@ -191,16 +191,16 @@ def test_get_split_index(): result = messager.get_split_index() assert result == 2 - fake_connection.send.assert_called_with(b"getsplitindex\r\n") + fake_connection.send.assert_called_with(b"getsplitindex") fake_connection.receive.assert_called_once() @pytest.mark.parametrize( "funcname, message", [ - ("get_current_split_name", b"getcurrentsplitname\r\n"), - ("get_previous_split_name", b"getprevioussplitname\r\n"), - ("get_current_timer_phase", b"getcurrenttimerphase\r\n"), + ("get_current_split_name", b"getcurrentsplitname"), + ("get_previous_split_name", b"getprevioussplitname"), + ("get_current_timer_phase", b"getcurrenttimerphase"), ], ) def test_get_names(funcname, message): From c1cca1577ae1511381042c053368e31b38000b7f Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Wed, 8 Jul 2026 23:42:19 +0200 Subject: [PATCH 28/28] Adapt exceptions --- .../livesplit_client/connection_shared.py | 23 +++++++++++-------- .../livesplit_client/connection_windows.py | 7 ++++-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/splitguides/livesplit_client/connection_shared.py b/src/splitguides/livesplit_client/connection_shared.py index bc3d8cf..22b7f1a 100644 --- a/src/splitguides/livesplit_client/connection_shared.py +++ b/src/splitguides/livesplit_client/connection_shared.py @@ -107,7 +107,7 @@ def receive(self) -> bytes: class ConnectionWS(ConnectionTypeBase): NAME: typing.ClassVar[str] = "WebSocket" - timeout: int = 4 # 1 second not enough to establish a connection + timeout: int = 3 # 1 second not enough to establish a connection ws: websocket.WebSocket | None = attribute(default=None, init=False, repr=False) def connect(self) -> bool: @@ -116,7 +116,9 @@ def connect(self) -> bool: try: self.ws.connect(f"ws://{self.server}:{self.port}/livesplit", origin="SplitGuides", timeout=self.timeout) return True - except ConnectionRefusedError: + except ConnectionRefusedError, websocket._exceptions.WebSocketTimeoutException: + # ConnectionRefusedError -> target port not in use + # WebSocketTimeoutException -> TCP server running self.close() return False @@ -130,8 +132,8 @@ def send(self, msg: bytes) -> None: raise ConnectionError("The connection has not yet been established") try: self.ws.send(msg) # no CRLF on Websocket - except Exception: - # TODO: More precise exception here + except ConnectionAbortedError: + # server-side closed, only on second (send) invocation self.closed_by_host() def receive(self) -> bytes: @@ -140,15 +142,18 @@ def receive(self) -> bytes: try: data_received = self.ws.recv() - except Exception: - # TODO: More precise exception here + except websocket._exceptions.WebSocketTimeoutException: + # no data available + data_received = b"" + except ConnectionAbortedError: self.closed_by_host() + else: + if data_received == "": + # server-side closed + self.closed_by_host() if isinstance(data_received, str): # should always be string, encode to bytes for unified handling data_received = data_received.encode("UTF8") - if data_received == b"": - self.closed_by_host() - return data_received diff --git a/src/splitguides/livesplit_client/connection_windows.py b/src/splitguides/livesplit_client/connection_windows.py index f11e259..0a34e4f 100644 --- a/src/splitguides/livesplit_client/connection_windows.py +++ b/src/splitguides/livesplit_client/connection_windows.py @@ -64,7 +64,7 @@ def send(self, msg: bytes) -> None: try: win32file.WriteFile(self.handle, msg + b"\r\n") - except Exception as e: + except pywintypes.error as e: win32file.CloseHandle(self.handle) self.handle = None raise ConnectionError("Pipe sending error: " + str(e)) @@ -79,7 +79,10 @@ def receive(self) -> bytes: data_received = win32file.ReadFile(self.handle, BUFFER_SIZE) # this is returned as tuple, only pass the data onwards data_received = data_received[1] - except Exception as e: + except pywintypes.error as e: + if e.args[0]==232 and e.args[2]=='The pipe is being closed.': + # no data to gather + return b"" win32file.CloseHandle(self.handle) self.handle = None raise ConnectionError("Pipe broken: " + str(e))