Skip to content

PYTHON-5454 & PYTHON-5455 Add python 3.14 and drop python 3.9 support #2448

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 44 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 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
8dff234
debug
blink1073 Jul 30, 2025
7abfd6f
try kms again
blink1073 Jul 30, 2025
5313eeb
try kms again
blink1073 Jul 30, 2025
e540383
fix oidc azure and gcp
blink1073 Jul 30, 2025
f49bb78
update image
blink1073 Jul 30, 2025
5a34548
fix var usage
blink1073 Jul 30, 2025
3b549d5
disable extension
blink1073 Jul 30, 2025
3be149a
handle no_ext
blink1073 Jul 30, 2025
984a115
handle no_ext
blink1073 Jul 30, 2025
ad3bb2e
update lock file and lowest dependencies test
blink1073 Jul 31, 2025
fdcfa2d
update mimimum test
blink1073 Jul 31, 2025
0501118
Merge branch 'master' of github.com:mongodb/mongo-python-driver into …
blink1073 Jul 31, 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
- ubuntu2204-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["ubuntu22"])]


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
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.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
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
8 changes: 7 additions & 1 deletion .evergreen/scripts/oidc_tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@ def setup_oidc(sub_test_name: str) -> dict[str, str] | None:
if sub_test_name == "azure":
env["AZUREOIDC_VMNAME_PREFIX"] = "PYTHON_DRIVER"
if "-remote" not in sub_test_name:
if sub_test_name == "azure":
# Found using "az vm image list --output table"
env["AZUREOIDC_IMAGE"] = "Canonical:0001-com-ubuntu-server-jammy:22_04-lts-gen2:latest"
else:
env["GCPKMS_IMAGEFAMILY"] = "debian-12"
run_command(f"bash {target_dir}/setup.sh", env=env)

if sub_test_name in K8S_NAMES:
run_command(f"bash {target_dir}/setup-pod.sh {sub_test_name}")
run_command(f"bash {target_dir}/run-self-test.sh")
Expand Down Expand Up @@ -77,7 +83,7 @@ def test_oidc_send_to_remote(sub_test_name: str) -> None:
env[f"{upper_name}OIDC_DRIVERS_TAR_FILE"] = TMP_DRIVER_FILE
env[
f"{upper_name}OIDC_TEST_CMD"
] = f"OIDC_ENV={sub_test_name} ./.evergreen/run-mongodb-oidc-test.sh"
] = f"NO_EXT=1 OIDC_ENV={sub_test_name} ./.evergreen/run-mongodb-oidc-test.sh"
elif sub_test_name in K8S_NAMES:
env["K8S_DRIVERS_TAR_FILE"] = TMP_DRIVER_FILE
env["K8S_TEST_CMD"] = "OIDC_ENV=k8s ./.evergreen/run-mongodb-oidc-test.sh"
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
11 changes: 9 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 @@ -90,6 +90,13 @@ def setup_libmongocrypt():
distro = get_distro()
if distro.name.startswith("Debian"):
target = f"debian{distro.version_id}"
elif distro.name.startswith("Ubuntu"):
if distro.version_id == "20.04":
target = "debian11"
elif distro.version_id == "22.04":
target = "debian12"
elif distro.version_id == "24.04":
target = "debian13"
elif distro.name.startswith("Red Hat"):
if distro.version_id.startswith("7"):
target = "rhel-70-64-bit"
Expand Down Expand Up @@ -274,7 +281,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
Loading
Loading