Skip to content

Commit

Permalink
Merge pull request #529 from beeware/py3.14
Browse files Browse the repository at this point in the history
Add support for Python 3.14; drop support for 3.8
  • Loading branch information
mhsmith authored Oct 17, 2024
2 parents e186ab5 + 35404b7 commit c44540e
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 42 deletions.
20 changes: 8 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,28 +54,23 @@ jobs:
name: Unit tests
needs: [ pre-commit, towncrier, package ]
runs-on: ${{ matrix.platform }}
continue-on-error: ${{ matrix.experimental }}
continue-on-error: false
strategy:
fail-fast: false
matrix:
platform: [
# X86-64 runners
"macos-12", "macos-13",
"macos-13",
# M1 runners
"macos-14"
"macos-14", "macos-15"
]
python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12", "3.13-dev" ]
include:
- experimental: false
- python-version: "3.13-dev"
experimental: true

python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13", "3.14" ]
exclude:
# actions/setup-python doesn't provide Python3.8 or 3.9 for M1.
# actions/setup-python doesn't provide Python 3.9 for M1.
- platform: "macos-14"
python-version : "3.8"
python-version : "3.9"

- platform: "macos-14"
- platform: "macos-15"
python-version : "3.9"

steps:
Expand All @@ -88,6 +83,7 @@ jobs:
uses: actions/[email protected]
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Get packages
uses: actions/[email protected]
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ repos:
rev: v3.18.0
hooks:
- id: pyupgrade
args: [--py38-plus]
args: [--py39-plus]
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 24.10.0
hooks:
Expand Down
1 change: 1 addition & 0 deletions changes/529.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support for Python 3.14 was added.
1 change: 1 addition & 0 deletions changes/529.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Python 3.8 is no longer a supported platform.
8 changes: 3 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dynamic = ["version"]
name = "rubicon-objc"
description = "A bridge between an Objective C runtime environment and Python."
readme = "README.rst"
requires-python = ">= 3.8"
requires-python = ">= 3.9"
license.text = "New BSD"
authors = [
{name="Russell Keith-Magee", email="[email protected]"},
Expand All @@ -29,12 +29,12 @@ classifiers = [
"License :: OSI Approved :: BSD License",
"Programming Language :: Objective C",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"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",
]
Expand All @@ -48,9 +48,7 @@ Source = "https://github.com/beeware/rubicon-objc"

[project.optional-dependencies]
dev = [
# Pre-commit 3.6.0 deprecated support for Python 3.8
"pre-commit == 3.5.0 ; python_version < '3.9'",
"pre-commit == 4.0.1 ; python_version >= '3.9'",
"pre-commit == 4.0.1",
"pytest == 8.3.3",
"setuptools_scm == 8.1.0",
"tox == 4.21.2",
Expand Down
4 changes: 2 additions & 2 deletions src/rubicon/objc/ctypes_patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.15. "
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."
Expand Down
52 changes: 32 additions & 20 deletions src/rubicon/objc/eventloop.py
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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",
Expand Down Expand Up @@ -695,30 +698,39 @@ def _new_default_loop(self):
loop._policy = self
return loop

def _init_watcher(self):
with events._lock:
if self._watcher is None: # pragma: no branch
self._watcher = SafeChildWatcher()
if threading.current_thread() == threading.main_thread():
self._watcher.attach_loop(self._default_loop)
if sys.version_info < (3, 14):

def get_child_watcher(self):
"""Get the watcher for child processes.
def _init_watcher(self):
with events._lock:
if self._watcher is None: # pragma: no branch
self._watcher = SafeChildWatcher()
if threading.current_thread() == threading.main_thread():
self._watcher.attach_loop(self._default_loop)

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.
.. note::
Child watcher support was removed 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()
.. note::
Child watcher support was removed in Python 3.14
"""
if self._watcher is not None:
self._watcher.close()

self._watcher = watcher
self._watcher = watcher


class CFLifecycle:
Expand Down
4 changes: 2 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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{39,310,311,312,313,314}
skip_missing_interpreters = true

[testenv:pre-commit]
Expand All @@ -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{,39,310,311,312,313,314}]
package = wheel
wheel_build_env = .pkg
depends = pre-commit
Expand Down

0 comments on commit c44540e

Please sign in to comment.