PYTHON-5454 & PYTHON-5455 Add preliminary python 3.14 support (#2451)

This commit is contained in:
Steven Silvester 2025-08-05 13:01:30 -05:00 committed by GitHub
parent d11cf20452
commit d7074ba9ee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 2559 additions and 1977 deletions

File diff suppressed because it is too large Load Diff

View File

@ -292,32 +292,32 @@ buildvariants:
AUTH: auth
# Free threaded tests
- name: free-threaded-rhel8-python3.13t
- name: free-threaded-rhel8-python3.14t
tasks:
- name: .free-threading
display_name: Free-threaded RHEL8 Python3.13t
display_name: Free-threaded RHEL8 Python3.14t
run_on:
- rhel87-small
expansions:
PYTHON_BINARY: /opt/python/3.13t/bin/python3
PYTHON_BINARY: /opt/python/3.14t/bin/python3
tags: [pr]
- name: free-threaded-macos-python3.13t
- name: free-threaded-macos-python3.14t
tasks:
- name: .free-threading
display_name: Free-threaded macOS Python3.13t
display_name: Free-threaded macOS Python3.14t
run_on:
- macos-14
expansions:
PYTHON_BINARY: /Library/Frameworks/PythonT.Framework/Versions/3.13/bin/python3t
PYTHON_BINARY: /Library/Frameworks/PythonT.Framework/Versions/3.14/bin/python3t
tags: []
- name: free-threaded-macos-arm64-python3.13t
- name: free-threaded-macos-arm64-python3.14t
tasks:
- name: .free-threading
display_name: Free-threaded macOS Arm64 Python3.13t
display_name: Free-threaded macOS Arm64 Python3.14t
run_on:
- macos-14-arm64
expansions:
PYTHON_BINARY: /Library/Frameworks/PythonT.Framework/Versions/3.13/bin/python3t
PYTHON_BINARY: /Library/Frameworks/PythonT.Framework/Versions/3.14/bin/python3t
tags: []
- name: free-threaded-win64-python3.14t
tasks:
@ -332,24 +332,20 @@ buildvariants:
# Green framework tests
- name: green-eventlet-rhel8
tasks:
- name: .test-standard .standalone-noauth-nossl .python-3.9
- name: .test-standard .standalone-noauth-nossl .python-3.9 .sync
display_name: Green Eventlet RHEL8
run_on:
- rhel87-small
expansions:
GREEN_FRAMEWORK: eventlet
AUTH: auth
SSL: ssl
- name: green-gevent-rhel8
tasks:
- name: .test-standard .standalone-noauth-nossl
- name: .test-standard .standalone-noauth-nossl .sync
display_name: Green Gevent RHEL8
run_on:
- rhel87-small
expansions:
GREEN_FRAMEWORK: gevent
AUTH: auth
SSL: ssl
# Import time tests
- name: import-time

View File

@ -107,10 +107,7 @@ def create_standard_nonlinux_variants() -> list[BuildVariant]:
def create_free_threaded_variants() -> list[BuildVariant]:
variants = []
for host_name in ("rhel8", "macos", "macos-arm64", "win64"):
if host_name == "win64":
python = "3.14t"
else:
python = "3.13t"
python = "3.14t"
tasks = [".free-threading"]
tags = []
if host_name == "rhel8":
@ -300,12 +297,12 @@ def create_green_framework_variants():
variants = []
host = DEFAULT_HOST
for framework in ["eventlet", "gevent"]:
tasks = [".test-standard .standalone-noauth-nossl"]
tasks = [".test-standard .standalone-noauth-nossl .sync"]
if framework == "eventlet":
# Eventlet has issues with dnspython > 2.0 and newer versions of CPython
# https://jira.mongodb.org/browse/PYTHON-5284
tasks = [".test-standard .standalone-noauth-nossl .python-3.9"]
expansions = dict(GREEN_FRAMEWORK=framework, AUTH="auth", SSL="ssl")
tasks = [".test-standard .standalone-noauth-nossl .python-3.9 .sync"]
expansions = dict(GREEN_FRAMEWORK=framework)
display_name = get_variant_name(f"Green {framework.capitalize()}", host)
variant = create_variant(tasks, display_name, host=host, expansions=expansions)
variants.append(variant)
@ -636,20 +633,15 @@ def create_test_non_standard_tasks():
def create_standard_tasks():
"""For variants that do not set a TEST_NAME."""
tasks = []
task_combos = []
# For each version and topology, rotate through the CPythons and sync/async.
for (version, topology), python, sync in zip_cycle(
list(product(ALL_VERSIONS, TOPOLOGIES)), CPYTHONS, SYNCS
task_combos = set()
# For each python and topology and sync/async, rotate through the the versions.
for (python, topology, sync), version in zip_cycle(
list(product(CPYTHONS + PYPYS, TOPOLOGIES, SYNCS)), ALL_VERSIONS
):
pr = version == "latest"
task_combos.append((version, topology, python, sync, pr))
# For each PyPy and topology, rotate through the the versions and sync/async.
for (python, topology), version, sync in zip_cycle(
list(product(PYPYS, TOPOLOGIES)), ALL_VERSIONS, SYNCS
):
task_combos.append((version, topology, python, sync, False))
pr = version == "latest" and python not in PYPYS
task_combos.add((version, topology, python, sync, pr))
for version, topology, python, sync, pr in task_combos:
for version, topology, python, sync, pr in sorted(task_combos):
auth, ssl = get_standard_auth_ssl(topology)
tags = [
"test-standard",

View File

@ -22,7 +22,7 @@ from shrub.v3.shrub_service import ShrubService
##############
ALL_VERSIONS = ["4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "rapid", "latest"]
CPYTHONS = ["3.9", "3.10", "3.11", "3.12", "3.13"]
CPYTHONS = ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
PYPYS = ["pypy3.10"]
ALL_PYTHONS = CPYTHONS + PYPYS
MIN_MAX_PYTHON = [CPYTHONS[0], CPYTHONS[-1]]

View File

@ -5,6 +5,11 @@ Changes in Version 4.14.0 (XXXX/XX/XX)
--------------------------------------
PyMongo 4.14 brings a number of changes including:
- Added preliminary support for Python 3.14 and 3.14 with free-threading. We do not yet support the following with Python 3.14:
- Subinterpreters (``concurrent.interpreters``)
- Free-threading with Encryption
- mod_wsgi
- Removed experimental support for free-threading support in Python 3.13.
- Added :attr:`bson.codec_options.TypeRegistry.codecs` and :attr:`bson.codec_options.TypeRegistry.fallback_encoder` properties
to allow users to directly access the type codecs and fallback encoder for a given :class:`bson.codec_options.TypeRegistry`.
- Added :meth:`pymongo.asynchronous.mongo_client.AsyncMongoClient.append_metadata` and

View File

@ -50,7 +50,8 @@ dev = [
"pre-commit>=4.0"
]
pip = ["pip"]
gevent = ["gevent"]
# TODO: PYTHON-5464
gevent = ["gevent", "cffi>=2.0.0b1;python_version=='3.14'"]
eventlet = ["eventlet"]
coverage = [
"pytest-cov",

View File

@ -369,7 +369,12 @@ class TestCursor(AsyncIntegrationTest):
client = await self.async_rs_or_single_client(event_listeners=[listener])
# Create a collection, referred to as collection, with the namespace explain-test.collection.
collection = client["explain-test"]["collection"]
# Workaround for SERVER-108463
names = await client["explain-test"].list_collection_names()
if "collection" not in names:
collection = await client["explain-test"].create_collection("collection")
else:
collection = client["explain-test"]["collection"]
# Run an explained find on collection. The find will have the query predicate { name: 'john doe' }. Specify a maxTimeMS value of 2000ms for the explain.
with pymongo.timeout(2.0):

View File

@ -361,7 +361,12 @@ class TestCursor(IntegrationTest):
client = self.rs_or_single_client(event_listeners=[listener])
# Create a collection, referred to as collection, with the namespace explain-test.collection.
collection = client["explain-test"]["collection"]
# Workaround for SERVER-108463
names = client["explain-test"].list_collection_names()
if "collection" not in names:
collection = client["explain-test"].create_collection("collection")
else:
collection = client["explain-test"]["collection"]
# Run an explained find on collection. The find will have the query predicate { name: 'john doe' }. Specify a maxTimeMS value of 2000ms for the explain.
with pymongo.timeout(2.0):

2545
uv.lock generated

File diff suppressed because it is too large Load Diff