Skip to content

PYTHON-5454 Add python 3.14 and drop python 3.9 #8

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

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
779bbcd
PYTHON-5454 Add python 3.14 and drop python 3.9
blink1073 Jul 28, 2025
7a53ba0
more updates
blink1073 Jul 28, 2025
5ac4969
fix wheel check
blink1073 Jul 28, 2025
cd33798
address failures
blink1073 Jul 28, 2025
5bffd3e
address failure
blink1073 Jul 28, 2025
64416b5
fix handling of doctest
blink1073 Jul 28, 2025
2d7913b
fix handling of collection
blink1073 Jul 28, 2025
dc3ddbf
fix ecs test
blink1073 Jul 28, 2025
5ee95c3
update green framework tests
blink1073 Jul 28, 2025
53c85d0
update green framework tests
blink1073 Jul 28, 2025
07fd9af
support gevent up to python 3.13
blink1073 Jul 28, 2025
aac0250
clean up gevent
blink1073 Jul 29, 2025
fe14126
clean up gevent
blink1073 Jul 29, 2025
b7418a6
fix cffi handling
blink1073 Jul 29, 2025
73d5e96
fix cffi handling
blink1073 Jul 29, 2025
c6a5a7f
remove drop database
blink1073 Jul 29, 2025
21a99c8
reinstate warning filters
blink1073 Jul 29, 2025
7198e5f
test with noauth and nossl
blink1073 Jul 29, 2025
fb88259
test with noauth and nossl
blink1073 Jul 29, 2025
f0bb646
fix greenlet support
blink1073 Jul 30, 2025
e84aea3
fix greenlet support
blink1073 Jul 30, 2025
bce2e49
add test workaround
blink1073 Jul 30, 2025
7cb07d6
add test workaround
blink1073 Jul 30, 2025
b4967b8
fix pymongocrypt
blink1073 Jul 30, 2025
1556e92
remove eventlet and dnspython 1.0 support
blink1073 Jul 30, 2025
84714e0
update changelog
blink1073 Jul 30, 2025
ad2401c
fix ecs and kms
blink1073 Jul 30, 2025
dec25d7
use debian12
blink1073 Jul 30, 2025
16a8657
update images
blink1073 Jul 30, 2025
0682586
update host
blink1073 Jul 30, 2025
bf9b197
fix vm handling
blink1073 Jul 30, 2025
aa0ba26
update azure image
blink1073 Jul 30, 2025
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,206 changes: 597 additions & 609 deletions .evergreen/generated_configs/tasks.yml

Large diffs are not rendered by default.

54 changes: 21 additions & 33 deletions .evergreen/generated_configs/variants.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
buildvariants:
# Alternative hosts tests
- name: openssl-1.0.2-rhel7-v5.0-python3.9
- name: openssl-1.0.2-rhel7-v5.0-python3.10
tasks:
- name: .test-no-toolchain
display_name: OpenSSL 1.0.2 RHEL7 v5.0 Python3.9
display_name: OpenSSL 1.0.2 RHEL7 v5.0 Python3.10
run_on:
- rhel79-small
batchtime: 10080
expansions:
VERSION: "5.0"
PYTHON_VERSION: "3.9"
PYTHON_BINARY: /opt/python/3.9/bin/python3
PYTHON_VERSION: "3.10"
PYTHON_BINARY: /opt/python/3.10/bin/python3
- name: other-hosts-rhel9-fips-latest
tasks:
- name: .test-no-toolchain
Expand Down Expand Up @@ -164,17 +164,17 @@ buildvariants:
- rhel87-small

# Disable test commands tests
- name: disable-test-commands-rhel8-python3.9
- name: disable-test-commands-rhel8-python3.10
tasks:
- name: .test-standard .server-latest
display_name: Disable test commands RHEL8 Python3.9
display_name: Disable test commands RHEL8 Python3.10
run_on:
- rhel87-small
expansions:
AUTH: auth
SSL: ssl
DISABLE_TEST_COMMANDS: "1"
PYTHON_BINARY: /opt/python/3.9/bin/python3
PYTHON_BINARY: /opt/python/3.10/bin/python3

# Doctests tests
- name: doctests-rhel8
Expand Down 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 @@ -330,26 +330,14 @@ buildvariants:
tags: []

# Green framework tests
- name: green-eventlet-rhel8
tasks:
- name: .test-standard .standalone-noauth-nossl .python-3.9
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 .sync !.python-3.14
display_name: Green Gevent RHEL8
run_on:
- rhel87-small
expansions:
GREEN_FRAMEWORK: gevent
AUTH: auth
SSL: ssl

# Import time tests
- name: import-time
Expand All @@ -370,7 +358,7 @@ buildvariants:
- name: test-azurekms-fail
display_name: KMS
run_on:
- debian11-small
- debian12-small

# Load balancer tests
- name: load-balancer
Expand Down Expand Up @@ -523,14 +511,14 @@ buildvariants:
SUB_TEST_NAME: pyopenssl

# Search index tests
- name: search-index-helpers-rhel8-python3.9
- name: search-index-helpers-rhel8-python3.10
tasks:
- name: .search_index
display_name: Search Index Helpers RHEL8 Python3.9
display_name: Search Index Helpers RHEL8 Python3.10
run_on:
- rhel87-small
expansions:
PYTHON_BINARY: /opt/python/3.9/bin/python3
PYTHON_BINARY: /opt/python/3.10/bin/python3

# Server version tests
- name: mongodb-v4.2
Expand Down
7 changes: 6 additions & 1 deletion .evergreen/run-mongodb-aws-ecs-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ fi
set -o xtrace

# Install python with pip.
PYTHON_VER="python3.9"
PYTHON_VER="python3.10"
apt-get -qq update < /dev/null > /dev/null
apt-get -q install -y software-properties-common
# Use openpgp to avoid gpg key timeout.
mkdir -p $HOME/.gnupg
echo "keyserver keys.openpgp.org" >> $HOME/.gnupg/gpg.conf
add-apt-repository -y 'ppa:deadsnakes/ppa'
apt-get -qq install $PYTHON_VER $PYTHON_VER-venv build-essential $PYTHON_VER-dev -y < /dev/null > /dev/null

export PYTHON_BINARY=$PYTHON_VER
Expand Down
2 changes: 2 additions & 0 deletions .evergreen/scripts/configure-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ EOT
rm -rf $DRIVERS_TOOLS
BRANCH=master
ORG=mongodb-labs
BRANCH=use-python-310
ORG=blink1073
git clone --branch $BRANCH https://github.com/$ORG/drivers-evergreen-tools.git $DRIVERS_TOOLS

cat <<EOT > ${DRIVERS_TOOLS}/.env
Expand Down
21 changes: 9 additions & 12 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 @@ -299,13 +296,10 @@ def create_stable_api_variants():
def create_green_framework_variants():
variants = []
host = DEFAULT_HOST
for framework in ["eventlet", "gevent"]:
tasks = [".test-standard .standalone-noauth-nossl"]
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")
for framework in ["gevent"]:
# TODO: Add Python 3.14 support (PYTHON-5464)
tasks = [".test-standard .sync !.python-3.14"]
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 @@ -440,7 +434,7 @@ def create_kms_variants():
tasks.append("test-gcpkms-fail")
tasks.append(EvgTaskRef(name="test-azurekms", batchtime=BATCHTIME_WEEK))
tasks.append("test-azurekms-fail")
return [create_variant(tasks, "KMS", host=HOSTS["debian11"])]
return [create_variant(tasks, "KMS", host=HOSTS["debian12"])]


def create_import_time_variants():
Expand Down Expand Up @@ -769,6 +763,9 @@ def create_mod_wsgi_tasks():
for (test, topology), python in zip_cycle(
product(["standalone", "embedded-mode"], ["standalone", "replica_set"]), CPYTHONS
):
if python == "3.14":
# TODO: Add Python 3.14 support (PYTHON-5462)
continue
if test == "standalone":
task_name = "mod-wsgi-"
else:
Expand Down
3 changes: 2 additions & 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.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 Expand Up @@ -64,6 +64,7 @@ class Host:
HOSTS["rhel7"] = Host("rhel7", "rhel79-small", "RHEL7", dict())
HOSTS["perf"] = Host("perf", "rhel90-dbx-perf-large", "", dict())
HOSTS["debian11"] = Host("debian11", "debian11-small", "Debian11", dict())
HOSTS["debian12"] = Host("debian12", "debian12-small", "Debian12", dict())
DEFAULT_HOST = HOSTS["rhel8"]

# Other hosts
Expand Down
11 changes: 8 additions & 3 deletions .evergreen/scripts/kms_tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def _setup_azure_vm(base_env: dict[str, str]) -> None:
env["AZUREKMS_CMD"] = "tar xf mongo-python-driver.tgz"
run_command(f"{azure_dir}/run-command.sh", env=env)

env["AZUREKMS_CMD"] = "bash .evergreen/just.sh setup-tests kms azure-remote"
env["AZUREKMS_CMD"] = "NO_EXT=1 bash .evergreen/just.sh setup-tests kms azure-remote"
run_command(f"{azure_dir}/run-command.sh", env=env)
LOGGER.info("Setting up Azure VM... done.")

Expand All @@ -47,7 +47,7 @@ def _setup_gcp_vm(base_env: dict[str, str]) -> None:
env["GCPKMS_CMD"] = "tar xf mongo-python-driver.tgz"
run_command(f"{gcp_dir}/run-command.sh", env=env)

env["GCPKMS_CMD"] = "bash ./.evergreen/just.sh setup-tests kms gcp-remote"
env["GCPKMS_CMD"] = "NO_EXT=1 bash ./.evergreen/just.sh setup-tests kms gcp-remote"
run_command(f"{gcp_dir}/run-command.sh", env=env)
LOGGER.info("Setting up GCP VM...")

Expand Down Expand Up @@ -91,7 +91,12 @@ def setup_kms(sub_test_name: str) -> None:
create_archive()
if sub_test_target == "azure":
os.environ["AZUREKMS_VMNAME_PREFIX"] = "PYTHON_DRIVER"

# Found using "az vm image list --output table"
os.environ[
"AZUREKMS_IMAGE"
] = "Canonical:0001-com-ubuntu-server-jammy:22_04-lts-gen2:latest"
else:
os.environ["GCPKMS_IMAGEFAMILY"] = "debian-12"
run_command("./setup.sh", cwd=kms_dir)
base_env = _load_kms_config(sub_test_target)

Expand Down
10 changes: 3 additions & 7 deletions .evergreen/scripts/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,12 @@ def handle_perf(start_time: datetime):


def handle_green_framework() -> None:
if GREEN_FRAMEWORK == "eventlet":
import eventlet

# https://github.com/eventlet/eventlet/issues/401
eventlet.sleep()
eventlet.monkey_patch()
elif GREEN_FRAMEWORK == "gevent":
if GREEN_FRAMEWORK == "gevent":
from gevent import monkey

monkey.patch_all()
else:
raise ValueError(f"Unsupported green framework type: {GREEN_FRAMEWORK}")

# Never run async tests with a framework.
if len(TEST_ARGS) <= 1:
Expand Down
4 changes: 2 additions & 2 deletions .evergreen/scripts/setup_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
GROUP_MAP = dict(mockupdb="mockupdb", perf="perf")

# The python version used for perf tests.
PERF_PYTHON_VERSION = "3.9.13"
PERF_PYTHON_VERSION = "3.10.14"


def is_set(var: str) -> bool:
Expand Down Expand Up @@ -274,7 +274,7 @@ def handle_test_env() -> None:
write_env("GSSAPI_PRINCIPAL", config["PRINCIPAL"])

if test_name == "doctest":
UV_ARGS.append("--extra docs")
UV_ARGS.append("--group doctest")

if test_name == "load_balancer":
SINGLE_MONGOS_LB_URI = os.environ.get(
Expand Down
2 changes: 1 addition & 1 deletion .evergreen/scripts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def get_test_options(
parser.add_argument(
"--green-framework",
nargs=1,
choices=["eventlet", "gevent"],
choices=["gevent"],
help="Optional green framework to test against.",
)
parser.add_argument(
Expand Down
28 changes: 14 additions & 14 deletions .evergreen/utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ find_python3() {
PYTHON=""
# Find a suitable toolchain version, if available.
if [ "$(uname -s)" = "Darwin" ]; then
PYTHON="/Library/Frameworks/Python.Framework/Versions/3.9/bin/python3"
PYTHON="/Library/Frameworks/Python.Framework/Versions/3.10/bin/python3"
elif [ "Windows_NT" = "${OS:-}" ]; then # Magic variable in cygwin
PYTHON="C:/python/Python39/python.exe"
PYTHON="C:/python/Python310/python.exe"
else
# Prefer our own toolchain, fall back to mongodb toolchain if it has Python 3.9+.
if [ -f "/opt/python/3.9/bin/python3" ]; then
# Prefer our own toolchain, fall back to mongodb toolchain if it has Python 3.10+.
if [ -f "/opt/python/3.10/bin/python3" ]; then
PYTHON="/opt/python/Current/bin/python3"
elif is_python_39 "$(command -v /opt/mongodbtoolchain/v5/bin/python3)"; then
elif is_python_310 "$(command -v /opt/mongodbtoolchain/v5/bin/python3)"; then
PYTHON="/opt/mongodbtoolchain/v5/bin/python3"
elif is_python_39 "$(command -v /opt/mongodbtoolchain/v4/bin/python3)"; then
elif is_python_310 "$(command -v /opt/mongodbtoolchain/v4/bin/python3)"; then
PYTHON="/opt/mongodbtoolchain/v4/bin/python3"
elif is_python_39 "$(command -v /opt/mongodbtoolchain/v3/bin/python3)"; then
elif is_python_310 "$(command -v /opt/mongodbtoolchain/v3/bin/python3)"; then
PYTHON="/opt/mongodbtoolchain/v3/bin/python3"
fi
fi
# Add a fallback system python3 if it is available and Python 3.9+.
# Add a fallback system python3 if it is available and Python 3.10+.
if [ -z "$PYTHON" ]; then
if is_python_39 "$(command -v python3)"; then
if is_python_310 "$(command -v python3)"; then
PYTHON="$(command -v python3)"
fi
fi
if [ -z "$PYTHON" ]; then
echo "Cannot test without python3.9+ installed!"
echo "Cannot test without python3.10+ installed!"
exit 1
fi
echo "$PYTHON"
Expand Down Expand Up @@ -99,11 +99,11 @@ testinstall () {
fi
}

# Function that returns success if the provided Python binary is version 3.9 or later
# Function that returns success if the provided Python binary is version 3.10 or later
# Usage:
# is_python_39 /path/to/python
# is_python_310 /path/to/python
# * param1: Python binary
is_python_39() {
is_python_310() {
if [ -z "$1" ]; then
return 1
elif $1 -c "import sys; exit(sys.version_info[:2] < (3, 9))"; then
Expand Down Expand Up @@ -131,7 +131,7 @@ get_python_binary() {
else
PYTHON="/opt/python/$version/bin/python3"
fi
if is_python_39 "$(command -v $PYTHON)"; then
if is_python_310 "$(command -v $PYTHON)"; then
echo "$PYTHON"
else
echo "Could not find suitable python binary for '$version'" >&2
Expand Down
Loading
Loading