From 4d352ae6133428ebe11c6a993fb908811698932d Mon Sep 17 00:00:00 2001 From: Russell Martin Date: Wed, 7 Aug 2024 12:01:58 -0400 Subject: [PATCH] Support Python 3.14 and remove event loop's support for child watchers --- .github/workflows/ci.yml | 4 +++- changes/498.feature.rst | 1 + changes/498.removal.rst | 1 + pyproject.toml | 1 + src/rubicon/objc/ctypes_patch.py | 4 ++-- src/rubicon/objc/eventloop.py | 38 ++++++++++++++++++++------------ tox.ini | 4 ++-- 7 files changed, 34 insertions(+), 19 deletions(-) create mode 100644 changes/498.feature.rst create mode 100644 changes/498.removal.rst diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4a7bbad..0207868d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,11 +64,13 @@ jobs: # M1 runners "macos-14" ] - python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12", "3.13-dev" ] + python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12", "3.13-dev", "3.14-dev" ] include: - experimental: false - python-version: "3.13-dev" experimental: true + - python-version: "3.14-dev" + experimental: true exclude: # actions/setup-python doesn't provide Python3.8 or 3.9 for M1. diff --git a/changes/498.feature.rst b/changes/498.feature.rst new file mode 100644 index 00000000..9e939324 --- /dev/null +++ b/changes/498.feature.rst @@ -0,0 +1 @@ +Support for Python 3.14 was added. diff --git a/changes/498.removal.rst b/changes/498.removal.rst new file mode 100644 index 00000000..191da7af --- /dev/null +++ b/changes/498.removal.rst @@ -0,0 +1 @@ +For Python 3.14 and beyond, the event loop's support for child watchers was removed. diff --git a/pyproject.toml b/pyproject.toml index 51f85426..063ca2ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: 3 :: Only", "Topic :: Software Development", ] diff --git a/src/rubicon/objc/ctypes_patch.py b/src/rubicon/objc/ctypes_patch.py index 2444a2a2..1d04b547 100644 --- a/src/rubicon/objc/ctypes_patch.py +++ b/src/rubicon/objc/ctypes_patch.py @@ -21,10 +21,10 @@ # This module relies on the layout of a few internal Python and ctypes # structures. Because of this, it's possible (but not all that likely) that # things will break on newer/older Python versions. -if sys.version_info < (3, 6) or sys.version_info >= (3, 14): +if sys.version_info < (3, 6) or sys.version_info >= (3, 15): v = sys.version_info warnings.warn( - "rubicon.objc.ctypes_patch has only been tested with Python 3.6 through 3.13. " + "rubicon.objc.ctypes_patch has only been tested with Python 3.6 through 3.14. " f"You are using Python {v.major}.{v.minor}.{v.micro}. Most likely things will " "work properly, but you may experience crashes if Python's internals have " "changed significantly." diff --git a/src/rubicon/objc/eventloop.py b/src/rubicon/objc/eventloop.py index 86136a30..547a739d 100644 --- a/src/rubicon/objc/eventloop.py +++ b/src/rubicon/objc/eventloop.py @@ -1,10 +1,10 @@ """PEP 3156 event loop based on CoreFoundation.""" import contextvars +import sys import threading from asyncio import ( DefaultEventLoopPolicy, - SafeChildWatcher, coroutines, events, tasks, @@ -16,6 +16,9 @@ from .runtime import load_library, objc_id from .types import CFIndex +if sys.version_info < (3, 14): + from asyncio import SafeChildWatcher + __all__ = [ "EventLoopPolicy", "CocoaLifecycle", @@ -702,23 +705,30 @@ def _init_watcher(self): if threading.current_thread() == threading.main_thread(): self._watcher.attach_loop(self._default_loop) - def get_child_watcher(self): - """Get the watcher for child processes. + if sys.version_info < (3, 14): - If not yet set, a :class:`~asyncio.SafeChildWatcher` object is - automatically created. - """ - if self._watcher is None: - self._init_watcher() + def get_child_watcher(self): + """Get the watcher for child processes. + + If not yet set, a :class:`~asyncio.SafeChildWatcher` object is + automatically created. + + REMOVED: Child watcher support was obsoleted in Python 3.14. + """ + if self._watcher is None: + self._init_watcher() + + return self._watcher - return self._watcher + def set_child_watcher(self, watcher): + """Set the watcher for child processes. - def set_child_watcher(self, watcher): - """Set the watcher for child processes.""" - if self._watcher is not None: - self._watcher.close() + REMOVED: Child watcher support was obsoleted in Python 3.14. + """ + if self._watcher is not None: + self._watcher.close() - self._watcher = watcher + self._watcher = watcher class CFLifecycle: diff --git a/tox.ini b/tox.ini index c9f60d91..b72a2d16 100644 --- a/tox.ini +++ b/tox.ini @@ -12,7 +12,7 @@ extend-ignore = E203, [tox] -envlist = towncrier-check,pre-commit,docs{,-lint,-all},py{38,39,310,311,312,313} +envlist = towncrier-check,pre-commit,docs{,-lint,-all},py{38,39,310,311,312,313,314} skip_missing_interpreters = true [testenv:pre-commit] @@ -21,7 +21,7 @@ wheel_build_env = .pkg extras = dev commands = pre-commit run --all-files --show-diff-on-failure --color=always -[testenv:py{,38,39,310,311,312,313}] +[testenv:py{,38,39,310,311,312,313,314}] package = wheel wheel_build_env = .pkg depends = pre-commit