From 1be135d40846d7b3726dce7b88d452df49854caa Mon Sep 17 00:00:00 2001 From: Iris Date: Tue, 13 Oct 2026 14:47:14 -0700 Subject: [PATCH 1/5] PYTHON-6138 followup --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 661c4d01e6..17e4ecda4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,7 +67,7 @@ unasync = [ pip = ["pip>=20.2"] gevent = ["gevent>=21.12"] coverage = [ - "coverage[toml]>=5,<=7.15.0" + "coverage[toml]>=6.4,<=7.15.0" ] mockupdb = [ "mockupdb>=1.8.1" diff --git a/uv.lock b/uv.lock index 577a943912..f6e2f67961 100644 --- a/uv.lock +++ b/uv.lock @@ -1412,7 +1412,7 @@ requires-dist = [ provides-extras = ["aws", "docs", "encryption", "gssapi", "ocsp", "snappy", "test", "zstd"] [package.metadata.requires-dev] -coverage = [{ name = "coverage", extras = ["toml"], specifier = ">=5,<=7.15.0" }] +coverage = [{ name = "coverage", extras = ["toml"], specifier = ">=6.4,<=7.15.0" }] dev = [] gevent = [{ name = "gevent", specifier = ">=21.12" }] lint = [{ name = "ruff", specifier = "==0.15.20" }] From d3c901a146ee3513614713bc4fd282e87d1c7ea8 Mon Sep 17 00:00:00 2001 From: Iris Date: Tue, 13 Oct 2026 15:01:54 -0700 Subject: [PATCH 2/5] remove pypy from testing and docs --- .evergreen/generated_configs/tasks.yml | 638 ++------------------ .evergreen/generated_configs/variants.yml | 48 +- .evergreen/scripts/generate_config.py | 49 +- .evergreen/scripts/generate_config_utils.py | 8 +- CONTRIBUTING.md | 3 +- README.md | 2 +- doc/changelog.rst | 7 +- pyproject.toml | 1 - 8 files changed, 99 insertions(+), 657 deletions(-) diff --git a/.evergreen/generated_configs/tasks.yml b/.evergreen/generated_configs/tasks.yml index 550902cd54..aeb5782901 100644 --- a/.evergreen/generated_configs/tasks.yml +++ b/.evergreen/generated_configs/tasks.yml @@ -273,13 +273,6 @@ tasks: vars: UV_PYTHON: "3.15" tags: [test-no-orchestration, python-3.15] - - name: test-no-orchestration-pypy3.11 - commands: - - func: assume ec2 role - - func: run tests - vars: - UV_PYTHON: pypy3.11 - tags: [test-no-orchestration, python-pypy3.11] # No toolchain tests - name: test-no-toolchain-sync-noauth-nossl-standalone @@ -2802,7 +2795,7 @@ tasks: tags: [search_index] # Server version tests - - name: test-server-version-python3.14t-async-auth-nossl-replica-set + - name: test-server-version-python3.14-async-auth-nossl-replica-set commands: - func: run server vars: @@ -2814,15 +2807,14 @@ tasks: AUTH: auth SSL: nossl TOPOLOGY: replica_set - UV_PYTHON: 3.14t + UV_PYTHON: "3.14" TEST_NAME: default_async tags: - server-version - - python-3.14t + - python-3.14 - replica_set-auth-nossl - async - - free-threaded - - name: test-server-version-python3.13-sync-auth-nossl-replica-set + - name: test-server-version-python3.14t-sync-auth-nossl-replica-set commands: - func: run server vars: @@ -2834,14 +2826,15 @@ tasks: AUTH: auth SSL: nossl TOPOLOGY: replica_set - UV_PYTHON: "3.13" + UV_PYTHON: 3.14t TEST_NAME: default_sync tags: - server-version - - python-3.13 + - python-3.14t - replica_set-auth-nossl - sync - - name: test-server-version-python3.12-async-auth-ssl-replica-set + - free-threaded + - name: test-server-version-python3.13-async-auth-ssl-replica-set commands: - func: run server vars: @@ -2853,35 +2846,33 @@ tasks: AUTH: auth SSL: ssl TOPOLOGY: replica_set - UV_PYTHON: "3.12" + UV_PYTHON: "3.13" TEST_NAME: default_async tags: - server-version - - python-3.12 + - python-3.13 - replica_set-auth-ssl - async - - name: test-server-version-python3.11-sync-auth-ssl-replica-set-min-deps + - name: test-server-version-python3.12-sync-auth-ssl-replica-set commands: - func: run server vars: AUTH: auth SSL: ssl TOPOLOGY: replica_set - TEST_MIN_DEPS: "1" - func: run tests vars: AUTH: auth SSL: ssl TOPOLOGY: replica_set - TEST_MIN_DEPS: "1" - UV_PYTHON: "3.11" + UV_PYTHON: "3.12" TEST_NAME: default_sync tags: - server-version - - python-3.11 + - python-3.12 - replica_set-auth-ssl - sync - - name: test-server-version-pypy3.11-async-noauth-nossl-replica-set-cov + - name: test-server-version-python3.12-async-noauth-nossl-replica-set-cov commands: - func: run server vars: @@ -2895,37 +2886,39 @@ tasks: SSL: nossl TOPOLOGY: replica_set COVERAGE: "1" - UV_PYTHON: pypy3.11 + UV_PYTHON: "3.12" TEST_NAME: default_async tags: - server-version - - python-pypy3.11 + - python-3.12 - replica_set-noauth-nossl - async - pr - - name: test-server-version-python3.15-sync-noauth-nossl-replica-set-cov + - name: test-server-version-python3.11-sync-noauth-nossl-replica-set-min-deps-cov commands: - func: run server vars: AUTH: noauth SSL: nossl TOPOLOGY: replica_set + TEST_MIN_DEPS: "1" COVERAGE: "1" - func: run tests vars: AUTH: noauth SSL: nossl TOPOLOGY: replica_set + TEST_MIN_DEPS: "1" COVERAGE: "1" - UV_PYTHON: "3.15" + UV_PYTHON: "3.11" TEST_NAME: default_sync tags: - server-version - - python-3.15 + - python-3.11 - replica_set-noauth-nossl - sync - pr - - name: test-server-version-python3.15t-async-noauth-ssl-replica-set + - name: test-server-version-python3.15-async-noauth-ssl-replica-set commands: - func: run server vars: @@ -2937,15 +2930,14 @@ tasks: AUTH: noauth SSL: ssl TOPOLOGY: replica_set - UV_PYTHON: 3.15t + UV_PYTHON: "3.15" TEST_NAME: default_async tags: - server-version - - python-3.15t + - python-3.15 - replica_set-noauth-ssl - async - - free-threaded - - name: test-server-version-python3.14-sync-noauth-ssl-replica-set + - name: test-server-version-python3.15t-sync-noauth-ssl-replica-set commands: - func: run server vars: @@ -2957,14 +2949,15 @@ tasks: AUTH: noauth SSL: ssl TOPOLOGY: replica_set - UV_PYTHON: "3.14" + UV_PYTHON: 3.15t TEST_NAME: default_sync tags: - server-version - - python-3.14 + - python-3.15t - replica_set-noauth-ssl - sync - - name: test-server-version-python3.14t-async-auth-nossl-sharded-cluster + - free-threaded + - name: test-server-version-python3.15t-async-auth-nossl-sharded-cluster commands: - func: run server vars: @@ -2976,15 +2969,15 @@ tasks: AUTH: auth SSL: nossl TOPOLOGY: sharded_cluster - UV_PYTHON: 3.14t + UV_PYTHON: 3.15t TEST_NAME: default_async tags: - server-version - - python-3.14t + - python-3.15t - sharded_cluster-auth-nossl - async - free-threaded - - name: test-server-version-python3.13-sync-auth-nossl-sharded-cluster + - name: test-server-version-python3.14-sync-auth-nossl-sharded-cluster commands: - func: run server vars: @@ -2996,11 +2989,11 @@ tasks: AUTH: auth SSL: nossl TOPOLOGY: sharded_cluster - UV_PYTHON: "3.13" + UV_PYTHON: "3.14" TEST_NAME: default_sync tags: - server-version - - python-3.13 + - python-3.14 - sharded_cluster-auth-nossl - sync - name: test-server-version-python3.11-async-auth-ssl-sharded-cluster-min-deps-cov @@ -3143,25 +3136,6 @@ tasks: - sharded_cluster-auth-ssl - async - free-threaded - - name: test-server-version-pypy3.11-async-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - UV_PYTHON: pypy3.11 - TEST_NAME: default_async - tags: - - server-version - - python-pypy3.11 - - sharded_cluster-auth-ssl - - async - name: test-server-version-python3.11-sync-auth-ssl-sharded-cluster-min-deps-cov commands: - func: run server @@ -3302,26 +3276,7 @@ tasks: - sharded_cluster-auth-ssl - sync - free-threaded - - name: test-server-version-pypy3.11-sync-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - UV_PYTHON: pypy3.11 - TEST_NAME: default_sync - tags: - - server-version - - python-pypy3.11 - - sharded_cluster-auth-ssl - - sync - - name: test-server-version-pypy3.11-async-noauth-nossl-sharded-cluster + - name: test-server-version-python3.13-async-noauth-nossl-sharded-cluster commands: - func: run server vars: @@ -3333,14 +3288,14 @@ tasks: AUTH: noauth SSL: nossl TOPOLOGY: sharded_cluster - UV_PYTHON: pypy3.11 + UV_PYTHON: "3.13" TEST_NAME: default_async tags: - server-version - - python-pypy3.11 + - python-3.13 - sharded_cluster-noauth-nossl - async - - name: test-server-version-python3.15-sync-noauth-nossl-sharded-cluster + - name: test-server-version-python3.12-sync-noauth-nossl-sharded-cluster commands: - func: run server vars: @@ -3352,34 +3307,35 @@ tasks: AUTH: noauth SSL: nossl TOPOLOGY: sharded_cluster - UV_PYTHON: "3.15" + UV_PYTHON: "3.12" TEST_NAME: default_sync tags: - server-version - - python-3.15 + - python-3.12 - sharded_cluster-noauth-nossl - sync - - name: test-server-version-python3.15t-async-noauth-ssl-sharded-cluster + - name: test-server-version-python3.11-async-noauth-ssl-sharded-cluster-min-deps commands: - func: run server vars: AUTH: noauth SSL: ssl TOPOLOGY: sharded_cluster + TEST_MIN_DEPS: "1" - func: run tests vars: AUTH: noauth SSL: ssl TOPOLOGY: sharded_cluster - UV_PYTHON: 3.15t + TEST_MIN_DEPS: "1" + UV_PYTHON: "3.11" TEST_NAME: default_async tags: - server-version - - python-3.15t + - python-3.11 - sharded_cluster-noauth-ssl - async - - free-threaded - - name: test-server-version-python3.14-sync-noauth-ssl-sharded-cluster + - name: test-server-version-python3.15-sync-noauth-ssl-sharded-cluster commands: - func: run server vars: @@ -3391,11 +3347,11 @@ tasks: AUTH: noauth SSL: ssl TOPOLOGY: sharded_cluster - UV_PYTHON: "3.14" + UV_PYTHON: "3.15" TEST_NAME: default_sync tags: - server-version - - python-3.14 + - python-3.15 - sharded_cluster-noauth-ssl - sync - name: test-server-version-python3.14t-async-auth-nossl-standalone @@ -3477,25 +3433,27 @@ tasks: - python-3.11 - standalone-auth-ssl - sync - - name: test-server-version-pypy3.11-async-noauth-nossl-standalone-cov + - name: test-server-version-python3.11-async-noauth-nossl-standalone-min-deps-cov commands: - func: run server vars: AUTH: noauth SSL: nossl TOPOLOGY: standalone + TEST_MIN_DEPS: "1" COVERAGE: "1" - func: run tests vars: AUTH: noauth SSL: nossl TOPOLOGY: standalone + TEST_MIN_DEPS: "1" COVERAGE: "1" - UV_PYTHON: pypy3.11 + UV_PYTHON: "3.11" TEST_NAME: default_async tags: - server-version - - python-pypy3.11 + - python-3.11 - standalone-noauth-nossl - async - pr @@ -3946,29 +3904,6 @@ tasks: - standalone-noauth-nossl - sync - free-threaded - - name: test-standard-v6.0-pypy3.11-sync-noauth-nossl-standalone - commands: - - func: run server - vars: - AUTH: noauth - SSL: nossl - TOPOLOGY: standalone - VERSION: "6.0" - - func: run tests - vars: - AUTH: noauth - SSL: nossl - TOPOLOGY: standalone - VERSION: "6.0" - UV_PYTHON: pypy3.11 - TEST_NAME: default_sync - tags: - - test-standard - - server-6.0 - - python-pypy3.11 - - standalone-noauth-nossl - - sync - - pypy - name: test-standard-v7.0-python3.11-async-noauth-ssl-replica-set-min-deps commands: - func: run server @@ -4083,29 +4018,6 @@ tasks: - standalone-noauth-nossl - async - free-threaded - - name: test-standard-v7.0-pypy3.11-async-noauth-nossl-standalone - commands: - - func: run server - vars: - AUTH: noauth - SSL: nossl - TOPOLOGY: standalone - VERSION: "7.0" - - func: run tests - vars: - AUTH: noauth - SSL: nossl - TOPOLOGY: standalone - VERSION: "7.0" - UV_PYTHON: pypy3.11 - TEST_NAME: default_async - tags: - - test-standard - - server-7.0 - - python-pypy3.11 - - standalone-noauth-nossl - - async - - pypy - name: test-standard-v8.0-python3.14t-sync-noauth-ssl-replica-set commands: - func: run server @@ -4129,29 +4041,6 @@ tasks: - replica_set-noauth-ssl - sync - free-threaded - - name: test-standard-v8.0-pypy3.11-sync-noauth-ssl-replica-set - commands: - - func: run server - vars: - AUTH: noauth - SSL: ssl - TOPOLOGY: replica_set - VERSION: "8.0" - - func: run tests - vars: - AUTH: noauth - SSL: ssl - TOPOLOGY: replica_set - VERSION: "8.0" - UV_PYTHON: pypy3.11 - TEST_NAME: default_sync - tags: - - test-standard - - server-8.0 - - python-pypy3.11 - - replica_set-noauth-ssl - - sync - - pypy - name: test-standard-v8.0-python3.11-sync-auth-ssl-sharded-cluster-min-deps commands: - func: run server @@ -4265,29 +4154,6 @@ tasks: - replica_set-noauth-ssl - async - free-threaded - - name: test-standard-v9.0-pypy3.11-async-noauth-ssl-replica-set - commands: - - func: run server - vars: - AUTH: noauth - SSL: ssl - TOPOLOGY: replica_set - VERSION: "9.0" - - func: run tests - vars: - AUTH: noauth - SSL: ssl - TOPOLOGY: replica_set - VERSION: "9.0" - UV_PYTHON: pypy3.11 - TEST_NAME: default_async - tags: - - test-standard - - server-9.0 - - python-pypy3.11 - - replica_set-noauth-ssl - - async - - pypy - name: test-standard-v9.0-python3.11-async-auth-ssl-sharded-cluster-min-deps commands: - func: run server @@ -4454,29 +4320,6 @@ tasks: - async - free-threaded - pr - - name: test-standard-latest-pypy3.11-async-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: latest - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: latest - UV_PYTHON: pypy3.11 - TEST_NAME: default_async - tags: - - test-standard - - server-latest - - python-pypy3.11 - - sharded_cluster-auth-ssl - - async - - pypy - name: test-standard-latest-python3.12-async-noauth-nossl-standalone-cov commands: - func: run server @@ -4595,29 +4438,6 @@ tasks: - sharded_cluster-auth-ssl - sync - free-threaded - - name: test-standard-rapid-pypy3.11-sync-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: rapid - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: rapid - UV_PYTHON: pypy3.11 - TEST_NAME: default_sync - tags: - - test-standard - - server-rapid - - python-pypy3.11 - - sharded_cluster-auth-ssl - - sync - - pypy - name: test-standard-rapid-python3.12-sync-noauth-nossl-standalone commands: - func: run server @@ -4753,28 +4573,6 @@ tasks: - python-3.11 - standalone-noauth-nossl - noauth - - name: test-non-standard-v4.4-pypy3.11-noauth-nossl-standalone - commands: - - func: run server - vars: - AUTH: noauth - SSL: nossl - TOPOLOGY: standalone - VERSION: "4.4" - - func: run tests - vars: - AUTH: noauth - SSL: nossl - TOPOLOGY: standalone - VERSION: "4.4" - UV_PYTHON: pypy3.11 - tags: - - test-non-standard - - server-4.4 - - python-pypy3.11 - - standalone-noauth-nossl - - noauth - - pypy - name: test-non-standard-v5.0-python3.14-noauth-ssl-replica-set commands: - func: run server @@ -4796,28 +4594,6 @@ tasks: - python-3.14 - replica_set-noauth-ssl - noauth - - name: test-non-standard-v5.0-pypy3.11-noauth-ssl-replica-set - commands: - - func: run server - vars: - AUTH: noauth - SSL: ssl - TOPOLOGY: replica_set - VERSION: "5.0" - - func: run tests - vars: - AUTH: noauth - SSL: ssl - TOPOLOGY: replica_set - VERSION: "5.0" - UV_PYTHON: pypy3.11 - tags: - - test-non-standard - - server-5.0 - - python-pypy3.11 - - replica_set-noauth-ssl - - noauth - - pypy - name: test-non-standard-v5.0-python3.15t-auth-ssl-sharded-cluster commands: - func: run server @@ -4906,28 +4682,6 @@ tasks: - python-3.12 - sharded_cluster-auth-ssl - auth - - name: test-non-standard-v6.0-pypy3.11-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "6.0" - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "6.0" - UV_PYTHON: pypy3.11 - tags: - - test-non-standard - - server-6.0 - - python-pypy3.11 - - sharded_cluster-auth-ssl - - auth - - pypy - name: test-non-standard-v6.0-python3.15-noauth-nossl-standalone commands: - func: run server @@ -5013,28 +4767,6 @@ tasks: - python-3.13 - standalone-noauth-nossl - noauth - - name: test-non-standard-v7.0-pypy3.11-noauth-nossl-standalone - commands: - - func: run server - vars: - AUTH: noauth - SSL: nossl - TOPOLOGY: standalone - VERSION: "7.0" - - func: run tests - vars: - AUTH: noauth - SSL: nossl - TOPOLOGY: standalone - VERSION: "7.0" - UV_PYTHON: pypy3.11 - tags: - - test-non-standard - - server-7.0 - - python-pypy3.11 - - standalone-noauth-nossl - - noauth - - pypy - name: test-non-standard-v8.0-python3.15-noauth-ssl-replica-set commands: - func: run server @@ -5056,28 +4788,6 @@ tasks: - python-3.15 - replica_set-noauth-ssl - noauth - - name: test-non-standard-v8.0-pypy3.11-noauth-ssl-replica-set - commands: - - func: run server - vars: - AUTH: noauth - SSL: ssl - TOPOLOGY: replica_set - VERSION: "8.0" - - func: run tests - vars: - AUTH: noauth - SSL: ssl - TOPOLOGY: replica_set - VERSION: "8.0" - UV_PYTHON: pypy3.11 - tags: - - test-non-standard - - server-8.0 - - python-pypy3.11 - - replica_set-noauth-ssl - - noauth - - pypy - name: test-non-standard-v8.0-python3.11-auth-ssl-sharded-cluster-min-deps commands: - func: run server @@ -5166,28 +4876,6 @@ tasks: - sharded_cluster-auth-ssl - auth - free-threaded - - name: test-non-standard-v9.0-pypy3.11-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "9.0" - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "9.0" - UV_PYTHON: pypy3.11 - tags: - - test-non-standard - - server-9.0 - - python-pypy3.11 - - sharded_cluster-auth-ssl - - auth - - pypy - name: test-non-standard-v9.0-python3.12-noauth-nossl-standalone commands: - func: run server @@ -5230,28 +4918,6 @@ tasks: - python-3.12 - replica_set-noauth-ssl - noauth - - name: test-non-standard-latest-pypy3.11-noauth-ssl-replica-set - commands: - - func: run server - vars: - AUTH: noauth - SSL: ssl - TOPOLOGY: replica_set - VERSION: latest - - func: run tests - vars: - AUTH: noauth - SSL: ssl - TOPOLOGY: replica_set - VERSION: latest - UV_PYTHON: pypy3.11 - tags: - - test-non-standard - - server-latest - - python-pypy3.11 - - replica_set-noauth-ssl - - noauth - - pypy - name: test-non-standard-latest-python3.13-auth-ssl-sharded-cluster-cov commands: - func: run server @@ -5386,28 +5052,6 @@ tasks: - python-3.14 - standalone-noauth-nossl - noauth - - name: test-non-standard-rapid-pypy3.11-noauth-nossl-standalone - commands: - - func: run server - vars: - AUTH: noauth - SSL: nossl - TOPOLOGY: standalone - VERSION: rapid - - func: run tests - vars: - AUTH: noauth - SSL: nossl - TOPOLOGY: standalone - VERSION: rapid - UV_PYTHON: pypy3.11 - tags: - - test-non-standard - - server-rapid - - python-pypy3.11 - - standalone-noauth-nossl - - noauth - - pypy # Test numpy tests - name: test-numpy-python3.11-python3.11 @@ -5457,28 +5101,6 @@ tasks: - python-3.11 - sharded_cluster-auth-ssl - auth - - name: test-standard-auth-v4.4-pypy3.11-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "4.4" - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "4.4" - UV_PYTHON: pypy3.11 - tags: - - test-standard-auth - - server-4.4 - - python-pypy3.11 - - sharded_cluster-auth-ssl - - auth - - pypy - name: test-standard-auth-v5.0-python3.12-auth-ssl-sharded-cluster commands: - func: run server @@ -5500,28 +5122,6 @@ tasks: - python-3.12 - sharded_cluster-auth-ssl - auth - - name: test-standard-auth-v5.0-pypy3.11-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "5.0" - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "5.0" - UV_PYTHON: pypy3.11 - tags: - - test-standard-auth - - server-5.0 - - python-pypy3.11 - - sharded_cluster-auth-ssl - - auth - - pypy - name: test-standard-auth-v6.0-python3.13-auth-ssl-sharded-cluster commands: - func: run server @@ -5543,28 +5143,6 @@ tasks: - python-3.13 - sharded_cluster-auth-ssl - auth - - name: test-standard-auth-v6.0-pypy3.11-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "6.0" - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "6.0" - UV_PYTHON: pypy3.11 - tags: - - test-standard-auth - - server-6.0 - - python-pypy3.11 - - sharded_cluster-auth-ssl - - auth - - pypy - name: test-standard-auth-v7.0-python3.14t-auth-ssl-sharded-cluster commands: - func: run server @@ -5587,28 +5165,6 @@ tasks: - sharded_cluster-auth-ssl - auth - free-threaded - - name: test-standard-auth-v7.0-pypy3.11-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "7.0" - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "7.0" - UV_PYTHON: pypy3.11 - tags: - - test-standard-auth - - server-7.0 - - python-pypy3.11 - - sharded_cluster-auth-ssl - - auth - - pypy - name: test-standard-auth-v8.0-python3.14-auth-ssl-sharded-cluster commands: - func: run server @@ -5630,28 +5186,6 @@ tasks: - python-3.14 - sharded_cluster-auth-ssl - auth - - name: test-standard-auth-v8.0-pypy3.11-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "8.0" - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "8.0" - UV_PYTHON: pypy3.11 - tags: - - test-standard-auth - - server-8.0 - - python-pypy3.11 - - sharded_cluster-auth-ssl - - auth - - pypy - name: test-standard-auth-v9.0-python3.15t-auth-ssl-sharded-cluster commands: - func: run server @@ -5674,28 +5208,6 @@ tasks: - sharded_cluster-auth-ssl - auth - free-threaded - - name: test-standard-auth-v9.0-pypy3.11-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "9.0" - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: "9.0" - UV_PYTHON: pypy3.11 - tags: - - test-standard-auth - - server-9.0 - - python-pypy3.11 - - sharded_cluster-auth-ssl - - auth - - pypy - name: test-standard-auth-latest-python3.11-auth-ssl-sharded-cluster-min-deps commands: - func: run server @@ -5720,28 +5232,6 @@ tasks: - sharded_cluster-auth-ssl - auth - pr - - name: test-standard-auth-latest-pypy3.11-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: latest - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: latest - UV_PYTHON: pypy3.11 - tags: - - test-standard-auth - - server-latest - - python-pypy3.11 - - sharded_cluster-auth-ssl - - auth - - pypy - name: test-standard-auth-rapid-python3.15-auth-ssl-sharded-cluster commands: - func: run server @@ -5763,25 +5253,3 @@ tasks: - python-3.15 - sharded_cluster-auth-ssl - auth - - name: test-standard-auth-rapid-pypy3.11-auth-ssl-sharded-cluster - commands: - - func: run server - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: rapid - - func: run tests - vars: - AUTH: auth - SSL: ssl - TOPOLOGY: sharded_cluster - VERSION: rapid - UV_PYTHON: pypy3.11 - tags: - - test-standard-auth - - server-rapid - - python-pypy3.11 - - sharded_cluster-auth-ssl - - auth - - pypy diff --git a/.evergreen/generated_configs/variants.yml b/.evergreen/generated_configs/variants.yml index 26027888fe..3aada2a8f6 100644 --- a/.evergreen/generated_configs/variants.yml +++ b/.evergreen/generated_configs/variants.yml @@ -196,8 +196,8 @@ buildvariants: tags: [encryption_tag] - name: encryption-macos tasks: - - name: .test-non-standard !.pypy !.cov !.python-3.15t - - name: .test-non-standard-no-cov !.pypy !.python-3.15t + - name: .test-non-standard !.cov !.python-3.15t + - name: .test-non-standard-no-cov !.python-3.15t - name: .test-string-query-preview display_name: Encryption macOS run_on: @@ -208,8 +208,8 @@ buildvariants: tags: [encryption_tag] - name: encryption-win64 tasks: - - name: .test-non-standard !.pypy !.cov !.python-3.15t - - name: .test-non-standard-no-cov !.pypy !.python-3.15t + - name: .test-non-standard !.cov !.python-3.15t + - name: .test-non-standard-no-cov !.python-3.15t - name: .test-string-query-preview display_name: Encryption Win64 run_on: @@ -232,8 +232,8 @@ buildvariants: tags: [encryption_tag] - name: encryption-crypt_shared-macos tasks: - - name: .test-non-standard !.pypy !.cov !.python-3.15t - - name: .test-non-standard-no-cov !.pypy !.python-3.15t + - name: .test-non-standard !.cov !.python-3.15t + - name: .test-non-standard-no-cov !.python-3.15t - name: .test-string-query-preview display_name: Encryption crypt_shared macOS run_on: @@ -245,8 +245,8 @@ buildvariants: tags: [encryption_tag] - name: encryption-crypt_shared-win64 tasks: - - name: .test-non-standard !.pypy !.cov !.python-3.15t - - name: .test-non-standard-no-cov !.pypy !.python-3.15t + - name: .test-non-standard !.cov !.python-3.15t + - name: .test-non-standard-no-cov !.python-3.15t - name: .test-string-query-preview display_name: Encryption crypt_shared Win64 run_on: @@ -301,7 +301,7 @@ buildvariants: AUTH: auth - name: auth-enterprise-macos tasks: - - name: .test-standard-auth !.pypy .auth !.free-threaded + - name: .test-standard-auth .auth !.free-threaded display_name: Auth Enterprise macOS run_on: - macos-14 @@ -310,7 +310,7 @@ buildvariants: AUTH: auth - name: auth-enterprise-win64 tasks: - - name: .test-standard-auth !.pypy .auth !.free-threaded + - name: .test-standard-auth .auth !.free-threaded display_name: Auth Enterprise Win64 run_on: - windows-2022-latest-small @@ -490,8 +490,8 @@ buildvariants: SUB_TEST_NAME: pyopenssl - name: pyopenssl-macos tasks: - - name: .test-standard !.pypy !.python-3.15t .sync - - name: .test-standard !.pypy !.python-3.15t .async .replica_set-noauth-ssl + - name: .test-standard !.python-3.15t .sync + - name: .test-standard !.python-3.15t .async .replica_set-noauth-ssl display_name: PyOpenSSL macOS run_on: - macos-14 @@ -500,8 +500,8 @@ buildvariants: SUB_TEST_NAME: pyopenssl - name: pyopenssl-win64 tasks: - - name: .test-standard !.pypy !.python-3.15t .sync - - name: .test-standard !.pypy !.python-3.15t .async .replica_set-noauth-ssl + - name: .test-standard !.python-3.15t .sync + - name: .test-standard !.python-3.15t .async .replica_set-noauth-ssl display_name: PyOpenSSL Win64 run_on: - windows-2022-latest-small @@ -651,34 +651,34 @@ buildvariants: # Standard nonlinux tests - name: test-macos tasks: - - name: .test-standard !.pypy + - name: .test-standard display_name: "* Test macOS" run_on: - macos-14 tags: [standard-non-linux] - name: test-macos-arm64 tasks: - - name: .test-standard !.pypy .server-6.0 - - name: .test-standard !.pypy .server-7.0 - - name: .test-standard !.pypy .server-8.0 - - name: .test-standard !.pypy .server-9.0 - - name: .test-standard !.pypy .server-rapid - - name: .test-standard !.pypy .server-latest + - name: .test-standard .server-6.0 + - name: .test-standard .server-7.0 + - name: .test-standard .server-8.0 + - name: .test-standard .server-9.0 + - name: .test-standard .server-rapid + - name: .test-standard .server-latest display_name: "* Test macOS Arm64" run_on: - macos-14-arm64 tags: [standard-non-linux] - name: test-win64 tasks: - - name: .test-standard !.pypy - - name: .test-no-orchestration !.pypy + - name: .test-standard + - name: .test-no-orchestration display_name: "* Test Win64" run_on: - windows-2022-latest-small tags: [standard-non-linux] - name: test-win32 tasks: - - name: .test-standard !.pypy !.free-threaded + - name: .test-standard !.free-threaded display_name: "* Test Win32" run_on: - windows-64-vsMulti-small diff --git a/.evergreen/scripts/generate_config.py b/.evergreen/scripts/generate_config.py index 9ec13d5037..358c213b1c 100644 --- a/.evergreen/scripts/generate_config.py +++ b/.evergreen/scripts/generate_config.py @@ -15,7 +15,6 @@ HOSTS, MIN_MAX_PYTHON, OTHER_HOSTS, - PYPYS, SYNCS, TOPOLOGIES, create_variant, @@ -104,20 +103,18 @@ def create_standard_nonlinux_variants() -> list[BuildVariant]: # Test a subset on each of the other platforms. for host_name in ("macos", "macos-arm64", "win64", "win32"): - tasks = [".test-standard !.pypy"] + tasks = [".test-standard"] # MacOS arm64 only works on server versions 6.0+ if host_name == "macos-arm64": - tasks = [ - f".test-standard !.pypy .server-{version}" for version in get_versions_from("6.0") - ] + tasks = [f".test-standard .server-{version}" for version in get_versions_from("6.0")] if host_name == "win64": - tasks.append(".test-no-orchestration !.pypy") + tasks.append(".test-no-orchestration") host = HOSTS[host_name] tags = ["standard-non-linux"] expansions = dict() if host_name == "win32": expansions["IS_WIN32"] = "1" - tasks = [".test-standard !.pypy !.free-threaded"] + tasks = [".test-standard !.free-threaded"] display_name = get_variant_name(base_display_name, host) variant = create_variant(tasks, display_name, host=host, tags=tags, expansions=expansions) variants.append(variant) @@ -146,13 +143,13 @@ def get_encryption_expansions(encryption): display_name = get_variant_name(encryption, host, **expansions) tasks = [".test-non-standard !.python-3.15t", ".test-string-query-preview"] if host != "rhel8": - # Exclude PyPy (not tested with encryption on macOS/win64) and coverage tasks - # (encryption suites exceed the 60-min timeout with coverage overhead on macOS/win64). + # Exclude coverage tasks (encryption suites exceed the 60-min timeout with + # coverage overhead on macOS/win64). # Also include the non-coverage companion tasks (test-non-standard-no-cov) which # carry the "latest" server tasks without COVERAGE=1. tasks = [ - ".test-non-standard !.pypy !.cov !.python-3.15t", - ".test-non-standard-no-cov !.pypy !.python-3.15t", + ".test-non-standard !.cov !.python-3.15t", + ".test-non-standard-no-cov !.python-3.15t", ".test-string-query-preview", ] variant = create_variant( @@ -275,10 +272,10 @@ def create_enterprise_auth_variants(): tasks = [".test-standard-auth .auth !.free-threaded"] # https://jira.mongodb.org/browse/PYTHON-5586 if host == "macos": - tasks = [".test-standard-auth !.pypy .auth !.free-threaded"] + tasks = [".test-standard-auth .auth !.free-threaded"] if host == "win64": # https://jira.mongodb.org/browse/PYTHON-5704 - tasks = [".test-standard-auth !.pypy .auth !.free-threaded"] + tasks = [".test-standard-auth .auth !.free-threaded"] variant = create_variant(tasks, display_name, host=host, expansions=expansions) variants.append(variant) return variants @@ -292,11 +289,7 @@ def create_pyopenssl_variants(): for host in ["rhel8", "macos", "win64"]: display_name = get_variant_name(base_name, host) - base_task = ( - ".test-standard !.python-3.15t" - if host == "rhel8" - else ".test-standard !.pypy !.python-3.15t" - ) + base_task = ".test-standard !.python-3.15t" # We only need to run a subset on async. tasks = [f"{base_task} .sync", f"{base_task} .async .replica_set-noauth-ssl"] variants.append( @@ -728,9 +721,6 @@ def create_test_non_standard_tasks(): for (version, topology), python in zip_cycle(list(product(ALL_VERSIONS, TOPOLOGIES)), CPYTHONS): pr = version == "latest" and topology == "sharded_cluster" task_combos.add((version, topology, python, pr)) - # For each PyPy and topology, rotate through the MongoDB versions. - for (python, topology), version in zip_cycle(list(product(PYPYS, TOPOLOGIES)), ALL_VERSIONS): - task_combos.add((version, topology, python, False)) for version, topology, python, pr in sorted(task_combos): auth, ssl = get_standard_auth_ssl(topology) tags = [ @@ -742,8 +732,6 @@ def create_test_non_standard_tasks(): ] if "t" in python: tags.append("free-threaded") - if python in PYPYS: - tags.append("pypy") if pr: tags.append("pr") expansions = dict(AUTH=auth, SSL=ssl, TOPOLOGY=topology, VERSION=version) @@ -819,11 +807,6 @@ def create_test_standard_auth_tasks(): ): pr = version == "latest" task_combos.add((version, topology, python, pr)) - # Rotate through each PyPy and MongoDB versions. - for (python, topology), version in zip_cycle( - list(product(PYPYS, ["sharded_cluster"])), ALL_VERSIONS - ): - task_combos.add((version, topology, python, False)) for version, topology, python, pr in sorted(task_combos): auth, ssl = get_standard_auth_ssl(topology) tags = [ @@ -835,8 +818,6 @@ def create_test_standard_auth_tasks(): ] if "t" in python: tags.append("free-threaded") - if python in PYPYS: - tags.append("pypy") if pr: tags.append("pr") expansions = dict(AUTH=auth, SSL=ssl, TOPOLOGY=topology, VERSION=version) @@ -859,9 +840,9 @@ def create_standard_tasks(): 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 + list(product(CPYTHONS, TOPOLOGIES, SYNCS)), ALL_VERSIONS ): - pr = version == "latest" and python not in PYPYS + pr = version == "latest" task_combos.add((version, topology, python, sync, pr)) for version, topology, python, sync, pr in sorted(task_combos): @@ -875,8 +856,6 @@ def create_standard_tasks(): ] if "t" in python: tags.append("free-threaded") - if python in PYPYS: - tags.append("pypy") if pr: tags.append("pr") expansions = dict(AUTH=auth, SSL=ssl, TOPOLOGY=topology, VERSION=version) @@ -896,7 +875,7 @@ def create_standard_tasks(): def create_no_orchestration_tasks(): tasks = [] - for python in [*MIN_MAX_PYTHON, PYPYS[-1]]: + for python in MIN_MAX_PYTHON: tags = [ "test-no-orchestration", f"python-{python}", diff --git a/.evergreen/scripts/generate_config_utils.py b/.evergreen/scripts/generate_config_utils.py index b3f6000b32..18be347d56 100644 --- a/.evergreen/scripts/generate_config_utils.py +++ b/.evergreen/scripts/generate_config_utils.py @@ -23,9 +23,8 @@ ALL_VERSIONS = ["4.4", "5.0", "6.0", "7.0", "8.0", "9.0", "rapid", "latest"] CPYTHONS = ["3.11", "3.12", "3.13", "3.14t", "3.14", "3.15t", "3.15"] -PYPYS = ["pypy3.11"] MIN_SUPPORT_VERSIONS = ["3.11"] -ALL_PYTHONS = CPYTHONS + PYPYS +ALL_PYTHONS = CPYTHONS MIN_MAX_PYTHON = [CPYTHONS[0], CPYTHONS[-1]] BATCHTIME_WEEK = 10080 BATCHTIME_DAY = 1440 @@ -179,10 +178,7 @@ def get_common_name(base: str, sep: str, **kwargs) -> str: for key, value in kwargs.items(): name = value if key.lower() in ["python", "uv_python"]: - if not value.startswith("pypy"): - name = f"Python{value}" - else: - name = f"PyPy{value.replace('pypy', '')}" + name = f"Python{value}" elif key.lower() in DISPLAY_LOOKUP and value in DISPLAY_LOOKUP[key.lower()]: name = DISPLAY_LOOKUP[key.lower()][value] else: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d277f9e14d..dd187b1747 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,8 +16,7 @@ be of interest or that has already been addressed. ## Supported Interpreters -PyMongo supports CPython 3.11+ and PyPy 3.11+. Language features not -supported by all interpreters can not be used. +PyMongo supports CPython 3.11+. ## Style Guide diff --git a/README.md b/README.md index a1c725c97b..8528bf35ac 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ package that is incompatible with PyMongo. ## Dependencies -PyMongo supports CPython 3.11+ and PyPy3.11+. PyPy support is deprecated and will be removed in a future release. +PyMongo supports CPython 3.11+. Required dependencies: diff --git a/doc/changelog.rst b/doc/changelog.rst index cea0a44699..d3678d3083 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -6,11 +6,12 @@ Changes in Version 4.19.0 (2026/XX/XX) PyMongo 4.19 brings a number of changes including: -.. warning:: PyMongo 4.19 drops support for Python 3.9 and 3.10 and PyPy 3.9 - and 3.10: Python 3.11+ or PyPy 3.11+ is now required. +.. warning:: PyMongo 4.19 drops support for Python 3.9 and 3.10 and removes + PyPy support: Python 3.11+ is now required. - Added support for Python 3.15. -- Dropped support for Python 3.9 and 3.10 and PyPy 3.9 and 3.10 (PYTHON-6138). +- Dropped support for Python 3.9 and 3.10. +- Removed support for PyPy. - Added support for running the synchronous and asynchronous clients in subinterpreters, including inside ``concurrent.futures.InterpreterPoolExecutor`` (Python 3.14+). Only in diff --git a/pyproject.toml b/pyproject.toml index 17e4ecda4b..56b932efdc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,6 @@ classifiers = [ "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.11", From 077b75e9e6074077aeab9ea318f40637e250f8c1 Mon Sep 17 00:00:00 2001 From: Iris Date: Tue, 13 Oct 2026 15:16:59 -0700 Subject: [PATCH 3/5] remove any pypy workarounds in the code base --- .evergreen/scripts/setup-uv-python.sh | 4 ++-- .evergreen/scripts/setup_tests.py | 3 +-- CONTRIBUTING.md | 6 +++--- _setup.py | 6 +----- bson/codec_options.py | 4 ++-- pymongo/asynchronous/pool.py | 4 ++-- pymongo/common.py | 4 ++-- pymongo/network_layer.py | 16 ++++------------ pymongo/pool_options.py | 15 +++------------ pymongo/synchronous/pool.py | 4 ++-- test/asynchronous/test_async_network_layer.py | 2 +- test/asynchronous/test_client.py | 5 ----- test/asynchronous/test_collection.py | 2 -- .../test_discovery_and_monitoring.py | 1 - test/asynchronous/test_load_balancer.py | 16 ++++------------ test/asynchronous/test_logger.py | 2 +- test/asynchronous/test_monitor.py | 1 - test/asynchronous/test_session.py | 16 +++++++--------- test/asynchronous/test_ssl.py | 10 ---------- test/asynchronous/test_streaming_protocol.py | 4 +--- test/asynchronous/test_transactions.py | 4 ---- test/asynchronous/unified_format.py | 7 ------- test/helpers_shared.py | 2 +- test/test_client.py | 5 ----- test/test_collection.py | 2 -- test/test_compression_support.py | 16 ---------------- test/test_discovery_and_monitoring.py | 1 - test/test_load_balancer.py | 16 ++++------------ test/test_logger.py | 2 +- test/test_monitor.py | 1 - test/test_network_layer.py | 2 +- test/test_session.py | 16 +++++++--------- test/test_ssl.py | 10 ---------- test/test_streaming_protocol.py | 4 +--- test/test_transactions.py | 4 ---- test/unified_format.py | 7 ------- 36 files changed, 51 insertions(+), 173 deletions(-) diff --git a/.evergreen/scripts/setup-uv-python.sh b/.evergreen/scripts/setup-uv-python.sh index b570a95c7d..2fe4ff5f3c 100755 --- a/.evergreen/scripts/setup-uv-python.sh +++ b/.evergreen/scripts/setup-uv-python.sh @@ -2,8 +2,8 @@ # Choose the Python that uv uses, and make sure uv can provide it. # # Input: -# UV_PYTHON - a version ("3.11", "3.14t"), an implementation ("pypy3.11"), -# or an interpreter path ("/usr/bin/python3.11"). +# UV_PYTHON - a version ("3.11", "3.14t") or an interpreter path +# ("/usr/bin/python3.11"). # # Exports: # UV_PYTHON_SEARCH_PATH - the Python toolchain bin dir for the request, so uv diff --git a/.evergreen/scripts/setup_tests.py b/.evergreen/scripts/setup_tests.py index c8a15ad4a6..28e0666eaf 100644 --- a/.evergreen/scripts/setup_tests.py +++ b/.evergreen/scripts/setup_tests.py @@ -528,8 +528,7 @@ def handle_test_env() -> None: TEST_ARGS = f"test/performance/async_perf_test.py {TEST_ARGS}" # Add coverage if requested. - # Only cover CPython. PyPy reports suspiciously low coverage. - if opts.cov and platform.python_implementation() == "CPython": + if opts.cov: # Keep in sync with combine-coverage.sh. # coverage >=5 is needed for relative_files=true. UV_ARGS.append("--group coverage") diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dd187b1747..e1b6a12605 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -463,10 +463,10 @@ To run any of the test suites with minimum supported dependencies, pass `--test- - If there are any services or atlas clusters to teardown, handle them in `.evergreen/scripts/teardown_tests.py`. - Add functions to generate the test variant(s) and task(s) to the `.evergreen/scripts/generate_config.py`. - There are some considerations about the Python version used in the test: - - To request a specific Python, set `UV_PYTHON` (e.g. `UV_PYTHON=3.10`, `UV_PYTHON=3.14t`, or -`UV_PYTHON=pypy3.11`). Tasks are host-agnostic, so the interpreter lookup happens on the host: for a plain + - To request a specific Python, set `UV_PYTHON` (e.g. `UV_PYTHON=3.10` or `UV_PYTHON=3.14t`). +Tasks are host-agnostic, so the interpreter lookup happens on the host: for a plain CPython version whose toolchain dir exists, `UV_PYTHON_SEARCH_PATH` points uv at it, and for anything else -(including PyPy, or a version the toolchain lacks) uv downloads it. +(a version the toolchain lacks) uv downloads it. - If a specific Python binary is needed (for example on the FIPS host), set `UV_PYTHON=/path/to/python`. - The default if `UV_PYTHON` is not set is CPython 3.10. This is deterministic across host types, so a task that does not pin a version always gets the same Python (with the build headers (`Python.h`) needed to build diff --git a/_setup.py b/_setup.py index f8536b3371..8a1f1e6e82 100644 --- a/_setup.py +++ b/_setup.py @@ -130,11 +130,7 @@ def build_extension(self, ext): except ValueError: pass ext_modules = [] -elif ( - sys.platform.startswith("java") - or sys.platform == "cli" - or sys.implementation.name in ("pypy", "graalpy") -): +elif sys.implementation.name == "graalpy": sys.stdout.write( """ *****************************************************\n diff --git a/bson/codec_options.py b/bson/codec_options.py index 89d87a74b6..5190126c7f 100644 --- a/bson/codec_options.py +++ b/bson/codec_options.py @@ -384,8 +384,8 @@ def __new__( # Generic aliases like SON[str, Any] or dict[str, Any] aren't classes, so # resolve to their origin before the subclass check. Whether issubclass() # raises TypeError or just returns False for such aliases is inconsistent - # across Python implementations (e.g. PyPy vs CPython), so check the - # origin proactively instead of relying on catching the error. + # across Python versions, so check the origin proactively instead of + # relying on catching the error. check_class = getattr(doc_class, "__origin__", doc_class) try: is_mapping = issubclass(check_class, _MutableMapping) diff --git a/pymongo/asynchronous/pool.py b/pymongo/asynchronous/pool.py index b7f7a1f6a0..b1103f6e4b 100644 --- a/pymongo/asynchronous/pool.py +++ b/pymongo/asynchronous/pool.py @@ -715,8 +715,8 @@ async def _reset( # Publish PoolClearedEvent while holding the lock and before # notify_all(). This guarantees it is recorded before any waiting # thread wakes up and emits ConnectionCheckOutFailedEvent, which - # also requires size_cond. Without this ordering, a race on PyPy - # and free-threaded Python causes ConnectionCheckOutFailedEvent to + # also requires size_cond. Without this ordering, a race on + # free-threaded Python causes ConnectionCheckOutFailedEvent to # arrive before PoolClearedEvent (PYTHON-3519). if not close and old_state != PoolState.PAUSED: self._telemetry.pool_cleared(service_id, interrupt_connections) diff --git a/pymongo/common.py b/pymongo/common.py index 9fa3bb15db..7bbef6bf96 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -513,8 +513,8 @@ def validate_document_class( # Generic aliases like SON[str, Any] or dict[str, Any] aren't classes, so # resolve to their origin before the subclass check. Whether issubclass() # raises TypeError or just returns False for such aliases is inconsistent - # across Python implementations (e.g. PyPy vs CPython), so check the - # origin proactively instead of relying on catching the error. + # across Python versions, so check the origin proactively instead of + # relying on catching the error. check_class = getattr(value, "__origin__", value) try: is_mapping = issubclass(check_class, abc.MutableMapping) diff --git a/pymongo/network_layer.py b/pymongo/network_layer.py index f01dd242ec..3f5afc1262 100644 --- a/pymongo/network_layer.py +++ b/pymongo/network_layer.py @@ -265,7 +265,6 @@ async def _async_socket_receive( return mv -_PYPY = "PyPy" in sys.version _WINDOWS = sys.platform == "win32" @@ -317,9 +316,8 @@ def receive_data(conn: Connection, length: int, deadline: Optional[float]) -> me try: while bytes_read < length: try: - # Use the legacy wait_for_read cancellation approach on PyPy due to PYTHON-5011. - # also use it on Windows due to PYTHON-5405 - if _PYPY or _WINDOWS: + # Use the legacy wait_for_read cancellation approach on Windows due to PYTHON-5405. + if _WINDOWS: wait_for_read(conn, deadline) if _csot.get_timeout() and deadline is not None: conn.set_conn_timeout(max(deadline - time.monotonic(), 0)) @@ -339,14 +337,8 @@ def receive_data(conn: Connection, length: int, deadline: Optional[float]) -> me except socket.timeout: if conn.cancel_context.cancelled: raise _OperationCancelled("operation cancelled") from None - if ( - _PYPY - or _WINDOWS - or ( - not conn.is_sdam - and deadline is not None - and deadline - time.monotonic() < 0 - ) + if _WINDOWS or ( + not conn.is_sdam and deadline is not None and deadline - time.monotonic() < 0 ): # We reached the true deadline. raise diff --git a/pymongo/pool_options.py b/pymongo/pool_options.py index f20033ad0e..69f194206e 100644 --- a/pymongo/pool_options.py +++ b/pymongo/pool_options.py @@ -93,18 +93,9 @@ "version": _aliased[2], } -if platform.python_implementation().startswith("PyPy"): - _METADATA["platform"] = " ".join( - ( - platform.python_implementation(), - ".".join(map(str, sys.pypy_version_info)), # type: ignore - "(Python {})".format(".".join(map(str, sys.version_info))), - ) - ) -else: - _METADATA["platform"] = " ".join( - (platform.python_implementation(), ".".join(map(str, sys.version_info))) - ) +_METADATA["platform"] = " ".join( + (platform.python_implementation(), ".".join(map(str, sys.version_info))) +) DOCKER_ENV_PATH = "/.dockerenv" ENV_VAR_K8S = "KUBERNETES_SERVICE_HOST" diff --git a/pymongo/synchronous/pool.py b/pymongo/synchronous/pool.py index dd562ac68e..0fb669b2f6 100644 --- a/pymongo/synchronous/pool.py +++ b/pymongo/synchronous/pool.py @@ -713,8 +713,8 @@ def _reset( # Publish PoolClearedEvent while holding the lock and before # notify_all(). This guarantees it is recorded before any waiting # thread wakes up and emits ConnectionCheckOutFailedEvent, which - # also requires size_cond. Without this ordering, a race on PyPy - # and free-threaded Python causes ConnectionCheckOutFailedEvent to + # also requires size_cond. Without this ordering, a race on + # free-threaded Python causes ConnectionCheckOutFailedEvent to # arrive before PoolClearedEvent (PYTHON-3519). if not close and old_state != PoolState.PAUSED: self._telemetry.pool_cleared(service_id, interrupt_connections) diff --git a/test/asynchronous/test_async_network_layer.py b/test/asynchronous/test_async_network_layer.py index 2c4b9cd7e4..ad146e1e79 100644 --- a/test/asynchronous/test_async_network_layer.py +++ b/test/asynchronous/test_async_network_layer.py @@ -317,7 +317,7 @@ async def cancel_again(): class _FakeSocket: """Feeds a byte buffer, simulating a socket. - On Windows and PyPy, receive_data() calls wait_for_read() before + On Windows, receive_data() calls wait_for_read() before recv_into(), which reaches through conn.conn.sock, so this also has to look like a socket to that code path. """ diff --git a/test/asynchronous/test_client.py b/test/asynchronous/test_client.py index 46249f762f..7f66139b1e 100644 --- a/test/asynchronous/test_client.py +++ b/test/asynchronous/test_client.py @@ -1324,9 +1324,6 @@ async def test_close_kills_cursors(self): cursor = await coll.aggregate([], batchSize=10) self.assertTrue(bool(await anext(cursor))) del cursor - # Required for PyPy and other Python implementations that - # don't use reference counting garbage collection. - gc.collect() # Close the client and ensure the topology is closed. self.assertTrue(test_client._topology._opened) @@ -2197,7 +2194,6 @@ async def test_direct_connection(self): with self.assertRaises(ConfigurationError): AsyncMongoClient(["host1", "host2"], directConnection=True) - @unittest.skipIf("PyPy" in sys.version, "PYTHON-2927 fails often on PyPy") async def test_continuous_network_errors(self): def server_description_count(): i = 0 @@ -2237,7 +2233,6 @@ async def test_network_error_message(self): with self.assertRaisesRegex(AutoReconnect, expected): await client.pymongo_test.coll.find_one({}) - @unittest.skipIf("PyPy" in sys.version, "PYTHON-2938 could fail on PyPy") async def test_process_periodic_tasks(self): client = await self.async_rs_or_single_client() coll = client.db.collection diff --git a/test/asynchronous/test_collection.py b/test/asynchronous/test_collection.py index e7172a9977..d63952cbe2 100644 --- a/test/asynchronous/test_collection.py +++ b/test/asynchronous/test_collection.py @@ -1866,8 +1866,6 @@ async def test_exhaust(self): for _ in range(3): await anext(cur) self.assertEqual(0, len(pool.conns)) - # if sys.platform.startswith("java") or "PyPy" in sys.version: - # # Don't wait for GC or use gc.collect(), it's unreliable. await cur.close() cur = None # Wait until the background thread returns the socket. diff --git a/test/asynchronous/test_discovery_and_monitoring.py b/test/asynchronous/test_discovery_and_monitoring.py index c60cef35c1..c0e60c9838 100644 --- a/test/asynchronous/test_discovery_and_monitoring.py +++ b/test/asynchronous/test_discovery_and_monitoring.py @@ -409,7 +409,6 @@ async def test_pool_unpause(self): @async_client_context.require_failCommand_appName @async_client_context.require_test_commands @async_client_context.require_async - @flaky(reason="PyPy is slow") async def test_connection_close_does_not_block_other_operations(self): listener = CMAPHeartbeatListener() client = await self.async_single_client( diff --git a/test/asynchronous/test_load_balancer.py b/test/asynchronous/test_load_balancer.py index 169a973632..7866f1f7e6 100644 --- a/test/asynchronous/test_load_balancer.py +++ b/test/asynchronous/test_load_balancer.py @@ -66,14 +66,10 @@ async def test_connections_are_only_returned_once(self): pool = await async_get_pool(self.client) n_conns = len(pool.conns) await self.db.coll.find_one({}) - # On PyPy it can take a few rounds to collect the cursor. - for _ in range(3): - gc.collect() + gc.collect() self.assertEqual(len(pool.conns), n_conns) await (await self.db.coll.aggregate([{"$limit": 1}])).to_list() - # On PyPy it can take a few rounds to collect the cursor. - for _ in range(3): - gc.collect() + gc.collect() self.assertEqual(len(pool.conns), n_conns) @async_client_context.require_load_balancer @@ -132,9 +128,7 @@ async def _test_no_gc_deadlock(self, create_resource): # Garbage collect the resource while the pool is locked to ensure we # don't deadlock. del resource - # On PyPy it can take a few rounds to collect the cursor. - for _ in range(3): - gc.collect() + gc.collect() task.unlock.set() await task.join(5) self.assertFalse(task.is_alive()) @@ -162,9 +156,7 @@ async def test_session_gc(self): # Garbage collect the session while the pool is locked to ensure we # don't deadlock. del session - # On PyPy it can take a few rounds to collect the session. - for _ in range(3): - gc.collect() + gc.collect() task.unlock.set() await task.join(5) self.assertFalse(task.is_alive()) diff --git a/test/asynchronous/test_logger.py b/test/asynchronous/test_logger.py index c9a80b9eb6..3291169b07 100644 --- a/test/asynchronous/test_logger.py +++ b/test/asynchronous/test_logger.py @@ -32,7 +32,7 @@ async def asyncTearDown(self) -> None: await super().asyncTearDown() def _get_command_log(self, records, command_name, status): - # PyPy's GC is non-deterministic, so cleanup commands from earlier tests can pollute the logs, + # Cleanup commands from earlier tests can pollute the logs, # filter for the specific command and status we want for record in records: log = json_util.loads(record.getMessage()) diff --git a/test/asynchronous/test_monitor.py b/test/asynchronous/test_monitor.py index ed4a025580..0022946ee4 100644 --- a/test/asynchronous/test_monitor.py +++ b/test/asynchronous/test_monitor.py @@ -61,7 +61,6 @@ async def create_client(self): await connected(client) return client - @unittest.skipIf("PyPy" in sys.version, "PYTHON-5283 fails often on PyPy") @unittest.skipIf( gevent_monkey_patched(), "PYTHON-5516 Resources are not cleared when using gevent" ) diff --git a/test/asynchronous/test_session.py b/test/asynchronous/test_session.py index 0809a23ea8..5210e25d36 100644 --- a/test/asynchronous/test_session.py +++ b/test/asynchronous/test_session.py @@ -177,15 +177,13 @@ async def _test_ops(self, client, *ops): lsids.append(event.command["lsid"]) - if not (sys.platform.startswith("java") or "PyPy" in sys.version): - # Server session was returned to pool. Ignore interpreters with - # non-deterministic GC. - for lsid in lsids: - self.assertIn( - lsid, - session_ids(client), - f"{f.__name__} did not return implicit session to pool", - ) + # Server session was returned to pool. + for lsid in lsids: + self.assertIn( + lsid, + session_ids(client), + f"{f.__name__} did not return implicit session to pool", + ) # Explicit bound session for f, args, kw in ops: diff --git a/test/asynchronous/test_ssl.py b/test/asynchronous/test_ssl.py index 1ec39c5e09..c66fb30af1 100644 --- a/test/asynchronous/test_ssl.py +++ b/test/asynchronous/test_ssl.py @@ -412,8 +412,6 @@ async def asyncTearDown(self): @async_client_context.require_tls async def test_simple_ssl(self): - if "PyPy" in sys.version: - self.skipTest("Test is flaky on PyPy") # Expects the server to be running with ssl and with # no --sslPEMKeyFile or with --sslWeakCertificateValidation await self.assertClientWorks(self.client) @@ -550,10 +548,6 @@ async def test_cert_ssl_uri_support(self): client = self.simple_client(uri_fmt % (CLIENT_PEM, "true", CA_PEM)) await self.assertClientWorks(client) - @unittest.skipIf( - "PyPy" in sys.version and not _IS_SYNC, - "https://github.com/pypy/pypy/issues/5131 flaky on async PyPy due to SSL EOF", - ) @async_client_context.require_tlsCertificateKeyFile @async_client_context.require_server_resolvable @async_client_context.require_no_api_version @@ -681,10 +675,6 @@ async def test_tlsCRLFile_support(self): self.simple_client(uri_fmt % (CRL_PEM, CA_PEM), **self.credentials) # type: ignore[arg-type] ) - @unittest.skipIf( - "PyPy" in sys.version and not _IS_SYNC, - "https://github.com/pypy/pypy/issues/5131 flaky on async PyPy due to SSL EOF", - ) @async_client_context.require_tlsCertificateKeyFile @async_client_context.require_server_resolvable @async_client_context.require_no_api_version diff --git a/test/asynchronous/test_streaming_protocol.py b/test/asynchronous/test_streaming_protocol.py index b87bd4a2e3..a47d40cd8a 100644 --- a/test/asynchronous/test_streaming_protocol.py +++ b/test/asynchronous/test_streaming_protocol.py @@ -199,9 +199,7 @@ def hb_failed(event): "appName": "heartbeatEventAwaitedFlag", }, } - # PYTHON-6002: PyPy's JIT warm-up can delay the heartbeat monitor - # thread past the default timeout on slow/throttled CI runners. - timeout = 30 if "PyPy" in sys.version else 10 + timeout = 10 async with self.fail_point(fail_heartbeat): await async_wait_until( lambda: hb_listener.matching(hb_failed), diff --git a/test/asynchronous/test_transactions.py b/test/asynchronous/test_transactions.py index 436c608a41..64b58ba5e6 100644 --- a/test/asynchronous/test_transactions.py +++ b/test/asynchronous/test_transactions.py @@ -308,10 +308,6 @@ async def gridfs_open_upload_stream(*args, **kwargs): @async_client_context.require_transactions @unittest.skipIf(sys.platform == "win32", "Our Windows machines are too slow to pass this test") async def test_transaction_starts_with_batched_write(self): - if "PyPy" in sys.version and async_client_context.tls: - self.skipTest( - "PYTHON-2937 PyPy is so slow sending large messages over TLS that this test fails" - ) # Start a transaction with a batch of operations that needs to be # split. listener = OvertCommandListener() diff --git a/test/asynchronous/unified_format.py b/test/asynchronous/unified_format.py index 2ee4e68657..06062ee8fc 100644 --- a/test/asynchronous/unified_format.py +++ b/test/asynchronous/unified_format.py @@ -618,9 +618,6 @@ def maybe_skip_test(self, spec): "maxTimeMS value in the command is less than timeoutMS", "timeoutMS applies to whole operation.*", ] - slow_pypy = [ - "timeoutMS applies to whole operation.*", - ] if "CI" in os.environ and sys.platform == "win32" and "gridfs" in class_name: self.skipTest("PYTHON-3522 CSOT GridFS test runs too slow on Windows") if "CI" in os.environ and sys.platform == "win32": @@ -631,10 +628,6 @@ def maybe_skip_test(self, spec): for pat in slow_macos: if re.match(pat.lower(), description): self.skipTest("PYTHON-3522 CSOT test runs too slow on MacOS") - if "CI" in os.environ and sys.implementation.name.lower() == "pypy": - for pat in slow_pypy: - if re.match(pat.lower(), description): - self.skipTest("PYTHON-3522 CSOT test runs too slow on PyPy") if "change" in description or "change" in class_name: self.skipTest("CSOT not implemented for watch()") if "cursors" in class_name: diff --git a/test/helpers_shared.py b/test/helpers_shared.py index 49cf131808..e67508a3ac 100644 --- a/test/helpers_shared.py +++ b/test/helpers_shared.py @@ -43,7 +43,7 @@ import ssl -# Enable debug output for uncollectable objects. PyPy does not have set_debug. +# Enable debug output for uncollectable objects. if hasattr(gc, "set_debug"): gc.set_debug( gc.DEBUG_UNCOLLECTABLE | getattr(gc, "DEBUG_OBJECTS", 0) | getattr(gc, "DEBUG_INSTANCES", 0) diff --git a/test/test_client.py b/test/test_client.py index a2640def28..58c5795776 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -1293,9 +1293,6 @@ def test_close_kills_cursors(self): cursor = coll.aggregate([], batchSize=10) self.assertTrue(bool(next(cursor))) del cursor - # Required for PyPy and other Python implementations that - # don't use reference counting garbage collection. - gc.collect() # Close the client and ensure the topology is closed. self.assertTrue(test_client._topology._opened) @@ -2150,7 +2147,6 @@ def test_direct_connection(self): with self.assertRaises(ConfigurationError): MongoClient(["host1", "host2"], directConnection=True) - @unittest.skipIf("PyPy" in sys.version, "PYTHON-2927 fails often on PyPy") def test_continuous_network_errors(self): def server_description_count(): i = 0 @@ -2190,7 +2186,6 @@ def test_network_error_message(self): with self.assertRaisesRegex(AutoReconnect, expected): client.pymongo_test.coll.find_one({}) - @unittest.skipIf("PyPy" in sys.version, "PYTHON-2938 could fail on PyPy") def test_process_periodic_tasks(self): client = self.rs_or_single_client() coll = client.db.collection diff --git a/test/test_collection.py b/test/test_collection.py index af19ee54e1..58589f5916 100644 --- a/test/test_collection.py +++ b/test/test_collection.py @@ -1848,8 +1848,6 @@ def test_exhaust(self): for _ in range(3): next(cur) self.assertEqual(0, len(pool.conns)) - # if sys.platform.startswith("java") or "PyPy" in sys.version: - # # Don't wait for GC or use gc.collect(), it's unreliable. cur.close() cur = None # Wait until the background thread returns the socket. diff --git a/test/test_compression_support.py b/test/test_compression_support.py index e1b903f32b..961c598d08 100644 --- a/test/test_compression_support.py +++ b/test/test_compression_support.py @@ -39,16 +39,6 @@ from test import unittest -def _have_tracemalloc() -> bool: - try: - import tracemalloc - - return True - except ImportError: - # PyPy does not ship the _tracemalloc C extension. - return False - - class TestValidateCompressors(unittest.TestCase): def test_string_input_single(self): with patch("pymongo.compression_support._have_zlib", return_value=True): @@ -232,8 +222,6 @@ def test_zstd_roundtrip(self): class TestDecompressSizeLimit(unittest.TestCase): def test_decompression_peak_memory_bounded(self): - if not _have_tracemalloc(): - self.skipTest("tracemalloc not available") import tracemalloc # High expansion ratio payload (repeated zeros, ~100000:1 ratio) @@ -275,8 +263,6 @@ def test_snappy_exceeds_max_rejected(self): def test_snappy_peak_memory_bounded(self): if not _have_snappy(): self.skipTest("python-snappy not installed") - if not _have_tracemalloc(): - self.skipTest("tracemalloc not available") import tracemalloc payload = SnappyContext.compress(b"\x00" * 100_000_000) @@ -294,8 +280,6 @@ def test_snappy_peak_memory_bounded(self): def test_zstd_peak_memory_bounded(self): if not _have_zstd(): self.skipTest("zstd not available") - if not _have_tracemalloc(): - self.skipTest("tracemalloc not available") import tracemalloc payload = ZstdContext.compress(b"\x00" * 100_000_000) diff --git a/test/test_discovery_and_monitoring.py b/test/test_discovery_and_monitoring.py index 3bec615274..8d95efeeb6 100644 --- a/test/test_discovery_and_monitoring.py +++ b/test/test_discovery_and_monitoring.py @@ -409,7 +409,6 @@ def test_pool_unpause(self): @client_context.require_failCommand_appName @client_context.require_test_commands @client_context.require_async - @flaky(reason="PyPy is slow") def test_connection_close_does_not_block_other_operations(self): listener = CMAPHeartbeatListener() client = self.single_client( diff --git a/test/test_load_balancer.py b/test/test_load_balancer.py index 3a2960c0c7..66a410a5f1 100644 --- a/test/test_load_balancer.py +++ b/test/test_load_balancer.py @@ -66,14 +66,10 @@ def test_connections_are_only_returned_once(self): pool = get_pool(self.client) n_conns = len(pool.conns) self.db.coll.find_one({}) - # On PyPy it can take a few rounds to collect the cursor. - for _ in range(3): - gc.collect() + gc.collect() self.assertEqual(len(pool.conns), n_conns) (self.db.coll.aggregate([{"$limit": 1}])).to_list() - # On PyPy it can take a few rounds to collect the cursor. - for _ in range(3): - gc.collect() + gc.collect() self.assertEqual(len(pool.conns), n_conns) @client_context.require_load_balancer @@ -132,9 +128,7 @@ def _test_no_gc_deadlock(self, create_resource): # Garbage collect the resource while the pool is locked to ensure we # don't deadlock. del resource - # On PyPy it can take a few rounds to collect the cursor. - for _ in range(3): - gc.collect() + gc.collect() task.unlock.set() task.join(5) self.assertFalse(task.is_alive()) @@ -162,9 +156,7 @@ def test_session_gc(self): # Garbage collect the session while the pool is locked to ensure we # don't deadlock. del session - # On PyPy it can take a few rounds to collect the session. - for _ in range(3): - gc.collect() + gc.collect() task.unlock.set() task.join(5) self.assertFalse(task.is_alive()) diff --git a/test/test_logger.py b/test/test_logger.py index 781b7b5f11..a1ae3291f7 100644 --- a/test/test_logger.py +++ b/test/test_logger.py @@ -31,7 +31,7 @@ def tearDown(self) -> None: super().tearDown() def _get_command_log(self, records, command_name, status): - # PyPy's GC is non-deterministic, so cleanup commands from earlier tests can pollute the logs, + # Cleanup commands from earlier tests can pollute the logs, # filter for the specific command and status we want for record in records: log = json_util.loads(record.getMessage()) diff --git a/test/test_monitor.py b/test/test_monitor.py index 8fd427cb3a..edbde15c47 100644 --- a/test/test_monitor.py +++ b/test/test_monitor.py @@ -61,7 +61,6 @@ def create_client(self): connected(client) return client - @unittest.skipIf("PyPy" in sys.version, "PYTHON-5283 fails often on PyPy") @unittest.skipIf( gevent_monkey_patched(), "PYTHON-5516 Resources are not cleared when using gevent" ) diff --git a/test/test_network_layer.py b/test/test_network_layer.py index 725d1b9597..50158c4562 100644 --- a/test/test_network_layer.py +++ b/test/test_network_layer.py @@ -36,7 +36,7 @@ def _make_conn(): conn = MagicMock() conn.conn.gettimeout.return_value = None - # On PyPy/Windows, receive_data() calls wait_for_read() before recv_into(). + # On Windows, receive_data() calls wait_for_read() before recv_into(). # wait_for_read() checks fileno() == -1 as an early-exit; without this mock, # sock.fileno() returns a MagicMock and sock.pending() > 0 raises TypeError. conn.conn.sock.fileno.return_value = -1 diff --git a/test/test_session.py b/test/test_session.py index 2d4427960e..727868e00f 100644 --- a/test/test_session.py +++ b/test/test_session.py @@ -177,15 +177,13 @@ def _test_ops(self, client, *ops): lsids.append(event.command["lsid"]) - if not (sys.platform.startswith("java") or "PyPy" in sys.version): - # Server session was returned to pool. Ignore interpreters with - # non-deterministic GC. - for lsid in lsids: - self.assertIn( - lsid, - session_ids(client), - f"{f.__name__} did not return implicit session to pool", - ) + # Server session was returned to pool. + for lsid in lsids: + self.assertIn( + lsid, + session_ids(client), + f"{f.__name__} did not return implicit session to pool", + ) # Explicit bound session for f, args, kw in ops: diff --git a/test/test_ssl.py b/test/test_ssl.py index 9e76de2cf8..c725bda984 100644 --- a/test/test_ssl.py +++ b/test/test_ssl.py @@ -403,8 +403,6 @@ def tearDown(self): @client_context.require_tls def test_simple_ssl(self): - if "PyPy" in sys.version: - self.skipTest("Test is flaky on PyPy") # Expects the server to be running with ssl and with # no --sslPEMKeyFile or with --sslWeakCertificateValidation self.assertClientWorks(self.client) @@ -541,10 +539,6 @@ def test_cert_ssl_uri_support(self): client = self.simple_client(uri_fmt % (CLIENT_PEM, "true", CA_PEM)) self.assertClientWorks(client) - @unittest.skipIf( - "PyPy" in sys.version and not _IS_SYNC, - "https://github.com/pypy/pypy/issues/5131 flaky on async PyPy due to SSL EOF", - ) @client_context.require_tlsCertificateKeyFile @client_context.require_server_resolvable @client_context.require_no_api_version @@ -672,10 +666,6 @@ def test_tlsCRLFile_support(self): self.simple_client(uri_fmt % (CRL_PEM, CA_PEM), **self.credentials) # type: ignore[arg-type] ) - @unittest.skipIf( - "PyPy" in sys.version and not _IS_SYNC, - "https://github.com/pypy/pypy/issues/5131 flaky on async PyPy due to SSL EOF", - ) @client_context.require_tlsCertificateKeyFile @client_context.require_server_resolvable @client_context.require_no_api_version diff --git a/test/test_streaming_protocol.py b/test/test_streaming_protocol.py index faa8cee63a..3446bc03c5 100644 --- a/test/test_streaming_protocol.py +++ b/test/test_streaming_protocol.py @@ -199,9 +199,7 @@ def hb_failed(event): "appName": "heartbeatEventAwaitedFlag", }, } - # PYTHON-6002: PyPy's JIT warm-up can delay the heartbeat monitor - # thread past the default timeout on slow/throttled CI runners. - timeout = 30 if "PyPy" in sys.version else 10 + timeout = 10 with self.fail_point(fail_heartbeat): wait_until( lambda: hb_listener.matching(hb_failed), diff --git a/test/test_transactions.py b/test/test_transactions.py index 5ccd38fd3f..dfaeebf897 100644 --- a/test/test_transactions.py +++ b/test/test_transactions.py @@ -300,10 +300,6 @@ def gridfs_open_upload_stream(*args, **kwargs): @client_context.require_transactions @unittest.skipIf(sys.platform == "win32", "Our Windows machines are too slow to pass this test") def test_transaction_starts_with_batched_write(self): - if "PyPy" in sys.version and client_context.tls: - self.skipTest( - "PYTHON-2937 PyPy is so slow sending large messages over TLS that this test fails" - ) # Start a transaction with a batch of operations that needs to be # split. listener = OvertCommandListener() diff --git a/test/unified_format.py b/test/unified_format.py index 657d7c0f22..4dcada2046 100644 --- a/test/unified_format.py +++ b/test/unified_format.py @@ -617,9 +617,6 @@ def maybe_skip_test(self, spec): "maxTimeMS value in the command is less than timeoutMS", "timeoutMS applies to whole operation.*", ] - slow_pypy = [ - "timeoutMS applies to whole operation.*", - ] if "CI" in os.environ and sys.platform == "win32" and "gridfs" in class_name: self.skipTest("PYTHON-3522 CSOT GridFS test runs too slow on Windows") if "CI" in os.environ and sys.platform == "win32": @@ -630,10 +627,6 @@ def maybe_skip_test(self, spec): for pat in slow_macos: if re.match(pat.lower(), description): self.skipTest("PYTHON-3522 CSOT test runs too slow on MacOS") - if "CI" in os.environ and sys.implementation.name.lower() == "pypy": - for pat in slow_pypy: - if re.match(pat.lower(), description): - self.skipTest("PYTHON-3522 CSOT test runs too slow on PyPy") if "change" in description or "change" in class_name: self.skipTest("CSOT not implemented for watch()") if "cursors" in class_name: From f7fbddb829ad8b639ed5d43fa25358dc1fc14fa0 Mon Sep 17 00:00:00 2001 From: Iris Date: Wed, 14 Oct 2026 09:43:47 -0700 Subject: [PATCH 4/5] remove unused import --- test/asynchronous/test_discovery_and_monitoring.py | 1 - test/test_discovery_and_monitoring.py | 1 - 2 files changed, 2 deletions(-) diff --git a/test/asynchronous/test_discovery_and_monitoring.py b/test/asynchronous/test_discovery_and_monitoring.py index c0e60c9838..a3129812b1 100644 --- a/test/asynchronous/test_discovery_and_monitoring.py +++ b/test/asynchronous/test_discovery_and_monitoring.py @@ -31,7 +31,6 @@ from pymongo.operations import _Op from pymongo.server_selectors import writable_server_selector from test.asynchronous.helpers import ConcurrentRunner -from test.asynchronous.utils import flaky from test.utils_shared import delay sys.path[0:0] = [""] diff --git a/test/test_discovery_and_monitoring.py b/test/test_discovery_and_monitoring.py index 8d95efeeb6..face947397 100644 --- a/test/test_discovery_and_monitoring.py +++ b/test/test_discovery_and_monitoring.py @@ -31,7 +31,6 @@ from pymongo.server_selectors import writable_server_selector from pymongo.synchronous.pool import Connection from test.helpers import ConcurrentRunner -from test.utils import flaky from test.utils_shared import delay sys.path[0:0] = [""] From d7432d26dd8639c37779e9069a1f3ee4b7d1b3cc Mon Sep 17 00:00:00 2001 From: Iris Date: Wed, 14 Oct 2026 09:44:12 -0700 Subject: [PATCH 5/5] reword comment --- bson/codec_options.py | 5 ++--- pymongo/common.py | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/bson/codec_options.py b/bson/codec_options.py index 5190126c7f..622d317f44 100644 --- a/bson/codec_options.py +++ b/bson/codec_options.py @@ -382,9 +382,8 @@ def __new__( ) -> CodecOptions: doc_class = document_class or dict # Generic aliases like SON[str, Any] or dict[str, Any] aren't classes, so - # resolve to their origin before the subclass check. Whether issubclass() - # raises TypeError or just returns False for such aliases is inconsistent - # across Python versions, so check the origin proactively instead of + # resolve to their origin before the subclass check. issubclass() raises + # TypeError for such aliases, so check the origin proactively instead of # relying on catching the error. check_class = getattr(doc_class, "__origin__", doc_class) try: diff --git a/pymongo/common.py b/pymongo/common.py index 7bbef6bf96..ce4379b507 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -511,9 +511,8 @@ def validate_document_class( ) -> Union[type[MutableMapping[str, Any]], type[RawBSONDocument]]: """Validate the document_class option.""" # Generic aliases like SON[str, Any] or dict[str, Any] aren't classes, so - # resolve to their origin before the subclass check. Whether issubclass() - # raises TypeError or just returns False for such aliases is inconsistent - # across Python versions, so check the origin proactively instead of + # resolve to their origin before the subclass check. issubclass() raises + # TypeError for such aliases, so check the origin proactively instead of # relying on catching the error. check_class = getattr(value, "__origin__", value) try: