Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,117 changes: 695 additions & 422 deletions .evergreen/generated_configs/tasks.yml

Large diffs are not rendered by default.

26 changes: 11 additions & 15 deletions .evergreen/generated_configs/variants.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down
30 changes: 11 additions & 19 deletions .evergreen/scripts/generate_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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":
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
):
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 = 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
):
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",
Expand Down
2 changes: 1 addition & 1 deletion .evergreen/scripts/generate_config_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
##############

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]]
Expand Down
3 changes: 3 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ 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 subinterpreters in Python 3.14.
We do not yet support free-theading with Encryption. Full support will be added in a future release.
- 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
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
7 changes: 6 additions & 1 deletion test/asynchronous/test_cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,12 @@ async def test_explain_csot(self):
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):
Expand Down
7 changes: 6 additions & 1 deletion test/test_cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,12 @@ def test_explain_csot(self):
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):
Expand Down
Loading
Loading