Merge branch 'master' of github.com:mongodb/mongo-python-driver

This commit is contained in:
Steven Silvester 2024-10-09 17:19:27 -05:00
commit 4e84bd45a8
No known key found for this signature in database
GPG Key ID: B1BF5EC3A8B32F91
52 changed files with 363 additions and 287 deletions

View File

@ -651,63 +651,16 @@ functions:
CA_FILE="${DRIVERS_TOOLS}/.evergreen/ocsp/${OCSP_ALGORITHM}/ca.pem" \
OCSP_TLS_SHOULD_SUCCEED="${OCSP_TLS_SHOULD_SUCCEED}" \
bash ${PROJECT_DIRECTORY}/.evergreen/hatch.sh test:test-eg
bash ${DRIVERS_TOOLS}/.evergreen/ocsp/teardown.sh
run-valid-ocsp-server:
- command: shell.exec
"run-ocsp-server":
- command: subprocess.exec
params:
background: true
script: |
. src/.evergreen/scripts/env.sh
cd ${DRIVERS_TOOLS}/.evergreen/ocsp
. ./activate-ocspvenv.sh
python ocsp_mock.py \
--ca_file ${OCSP_ALGORITHM}/ca.pem \
--ocsp_responder_cert ${OCSP_ALGORITHM}/ca.crt \
--ocsp_responder_key ${OCSP_ALGORITHM}/ca.key \
-p 8100 -v
run-revoked-ocsp-server:
- command: shell.exec
params:
background: true
script: |
. src/.evergreen/scripts/env.sh
cd ${DRIVERS_TOOLS}/.evergreen/ocsp
. ./activate-ocspvenv.sh
python ocsp_mock.py \
--ca_file ${OCSP_ALGORITHM}/ca.pem \
--ocsp_responder_cert ${OCSP_ALGORITHM}/ca.crt \
--ocsp_responder_key ${OCSP_ALGORITHM}/ca.key \
-p 8100 \
-v \
--fault revoked
run-valid-delegate-ocsp-server:
- command: shell.exec
params:
background: true
script: |
. src/.evergreen/scripts/env.sh
cd ${DRIVERS_TOOLS}/.evergreen/ocsp
. ./activate-ocspvenv.sh
python ocsp_mock.py \
--ca_file ${OCSP_ALGORITHM}/ca.pem \
--ocsp_responder_cert ${OCSP_ALGORITHM}/ocsp-responder.crt \
--ocsp_responder_key ${OCSP_ALGORITHM}/ocsp-responder.key \
-p 8100 -v
run-revoked-delegate-ocsp-server:
- command: shell.exec
params:
background: true
script: |
. src/.evergreen/scripts/env.sh
cd ${DRIVERS_TOOLS}/.evergreen/ocsp
. ./activate-ocspvenv.sh
python ocsp_mock.py \
--ca_file ${OCSP_ALGORITHM}/ca.pem \
--ocsp_responder_cert ${OCSP_ALGORITHM}/ocsp-responder.crt \
--ocsp_responder_key ${OCSP_ALGORITHM}/ocsp-responder.key \
-p 8100 \
-v \
--fault revoked
binary: bash
include_expansions_in_env: [SERVER_TYPE, OCSP_ALGORITHM]
args:
- ${DRIVERS_TOOLS}/.evergreen/ocsp/setup.sh
"run load-balancer":
- command: shell.exec
@ -1014,33 +967,6 @@ tasks:
TOPOLOGY: "server"
- func: "run doctests"
- name: "test-3.6-standalone"
tags: ["3.6", "standalone"]
commands:
- func: "bootstrap mongo-orchestration"
vars:
VERSION: "3.6"
TOPOLOGY: "server"
- func: "run tests"
- name: "test-3.6-replica_set"
tags: ["3.6", "replica_set"]
commands:
- func: "bootstrap mongo-orchestration"
vars:
VERSION: "3.6"
TOPOLOGY: "replica_set"
- func: "run tests"
- name: "test-3.6-sharded_cluster"
tags: ["3.6", "sharded_cluster"]
commands:
- func: "bootstrap mongo-orchestration"
vars:
VERSION: "3.6"
TOPOLOGY: "sharded_cluster"
- func: "run tests"
- name: "test-4.0-standalone"
tags: ["4.0", "standalone"]
commands:
@ -1387,9 +1313,10 @@ tasks:
- name: test-ocsp-rsa-valid-cert-server-staples
tags: ["ocsp", "ocsp-rsa", "ocsp-staple"]
commands:
- func: run-valid-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "rsa"
SERVER_TYPE: "valid"
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple.json"
@ -1401,9 +1328,10 @@ tasks:
- name: test-ocsp-rsa-invalid-cert-server-staples
tags: ["ocsp", "ocsp-rsa", "ocsp-staple"]
commands:
- func: run-revoked-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "rsa"
SERVER_TYPE: "revoked"
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple.json"
@ -1415,9 +1343,10 @@ tasks:
- name: test-ocsp-rsa-valid-cert-server-does-not-staple
tags: ["ocsp", "ocsp-rsa"]
commands:
- func: run-valid-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "rsa"
SERVER_TYPE: valid
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-disableStapling.json"
@ -1429,9 +1358,10 @@ tasks:
- name: test-ocsp-rsa-invalid-cert-server-does-not-staple
tags: ["ocsp", "ocsp-rsa"]
commands:
- func: run-revoked-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "rsa"
SERVER_TYPE: revoked
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-disableStapling.json"
@ -1454,9 +1384,10 @@ tasks:
- name: test-ocsp-rsa-malicious-invalid-cert-mustStaple-server-does-not-staple
tags: ["ocsp", "ocsp-rsa"]
commands:
- func: run-revoked-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "rsa"
SERVER_TYPE: revoked
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple-disableStapling.json"
@ -1479,9 +1410,10 @@ tasks:
- name: test-ocsp-rsa-delegate-valid-cert-server-staples
tags: ["ocsp", "ocsp-rsa", "ocsp-staple"]
commands:
- func: run-valid-delegate-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "rsa"
SERVER_TYPE: valid-delegate
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple.json"
@ -1493,9 +1425,10 @@ tasks:
- name: test-ocsp-rsa-delegate-invalid-cert-server-staples
tags: ["ocsp", "ocsp-rsa", "ocsp-staple"]
commands:
- func: run-revoked-delegate-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "rsa"
SERVER_TYPE: revoked-delegate
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple.json"
@ -1507,9 +1440,10 @@ tasks:
- name: test-ocsp-rsa-delegate-valid-cert-server-does-not-staple
tags: ["ocsp", "ocsp-rsa"]
commands:
- func: run-valid-delegate-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "rsa"
SERVER_TYPE: valid-delegate
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-disableStapling.json"
@ -1521,9 +1455,10 @@ tasks:
- name: test-ocsp-rsa-delegate-invalid-cert-server-does-not-staple
tags: ["ocsp", "ocsp-rsa"]
commands:
- func: run-revoked-delegate-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "rsa"
SERVER_TYPE: revoked-delegate
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-disableStapling.json"
@ -1535,9 +1470,10 @@ tasks:
- name: test-ocsp-rsa-delegate-malicious-invalid-cert-mustStaple-server-does-not-staple
tags: ["ocsp", "ocsp-rsa"]
commands:
- func: run-revoked-delegate-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "rsa"
SERVER_TYPE: revoked-delegate
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple-disableStapling.json"
@ -1549,9 +1485,10 @@ tasks:
- name: test-ocsp-ecdsa-valid-cert-server-staples
tags: ["ocsp", "ocsp-ecdsa", "ocsp-staple"]
commands:
- func: run-valid-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "ecdsa"
SERVER_TYPE: valid
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple.json"
@ -1563,9 +1500,10 @@ tasks:
- name: test-ocsp-ecdsa-invalid-cert-server-staples
tags: ["ocsp", "ocsp-ecdsa", "ocsp-staple"]
commands:
- func: run-revoked-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "ecdsa"
SERVER_TYPE: revoked
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple.json"
@ -1577,9 +1515,10 @@ tasks:
- name: test-ocsp-ecdsa-valid-cert-server-does-not-staple
tags: ["ocsp", "ocsp-ecdsa"]
commands:
- func: run-valid-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "ecdsa"
SERVER_TYPE: valid
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-disableStapling.json"
@ -1591,9 +1530,10 @@ tasks:
- name: test-ocsp-ecdsa-invalid-cert-server-does-not-staple
tags: ["ocsp", "ocsp-ecdsa"]
commands:
- func: run-revoked-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "ecdsa"
SERVER_TYPE: revoked
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-disableStapling.json"
@ -1616,9 +1556,10 @@ tasks:
- name: test-ocsp-ecdsa-malicious-invalid-cert-mustStaple-server-does-not-staple
tags: ["ocsp", "ocsp-ecdsa"]
commands:
- func: run-revoked-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "ecdsa"
SERVER_TYPE: revoked
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple-disableStapling.json"
@ -1641,9 +1582,10 @@ tasks:
- name: test-ocsp-ecdsa-delegate-valid-cert-server-staples
tags: ["ocsp", "ocsp-ecdsa", "ocsp-staple"]
commands:
- func: run-valid-delegate-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "ecdsa"
SERVER_TYPE: valid-delegate
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple.json"
@ -1655,9 +1597,10 @@ tasks:
- name: test-ocsp-ecdsa-delegate-invalid-cert-server-staples
tags: ["ocsp", "ocsp-ecdsa", "ocsp-staple"]
commands:
- func: run-revoked-delegate-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "ecdsa"
SERVER_TYPE: revoked-delegate
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple.json"
@ -1669,9 +1612,10 @@ tasks:
- name: test-ocsp-ecdsa-delegate-valid-cert-server-does-not-staple
tags: ["ocsp", "ocsp-ecdsa"]
commands:
- func: run-valid-delegate-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "ecdsa"
SERVER_TYPE: valid-delegate
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-disableStapling.json"
@ -1683,9 +1627,10 @@ tasks:
- name: test-ocsp-ecdsa-delegate-invalid-cert-server-does-not-staple
tags: ["ocsp", "ocsp-ecdsa"]
commands:
- func: run-revoked-delegate-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "ecdsa"
SERVER_TYPE: revoked-delegate
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-disableStapling.json"
@ -1697,9 +1642,10 @@ tasks:
- name: test-ocsp-ecdsa-delegate-malicious-invalid-cert-mustStaple-server-does-not-staple
tags: ["ocsp", "ocsp-ecdsa"]
commands:
- func: run-revoked-delegate-ocsp-server
- func: run-ocsp-server
vars:
OCSP_ALGORITHM: "ecdsa"
SERVER_TYPE: valid-delegate
- func: "bootstrap mongo-orchestration"
vars:
ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple-disableStapling.json"
@ -2186,10 +2132,6 @@ axes:
- id: mongodb-version
display_name: "MongoDB"
values:
- id: "3.6"
display_name: "MongoDB 3.6"
variables:
VERSION: "3.6"
- id: "4.0"
display_name: "MongoDB 4.0"
variables:
@ -2233,10 +2175,6 @@ axes:
values:
# Note: always display platform with python-version to avoid ambiguous display names.
# Linux
- id: "3.8"
display_name: "Python 3.8"
variables:
PYTHON_BINARY: "/opt/python/3.8/bin/python3"
- id: "3.9"
display_name: "Python 3.9"
variables:
@ -2269,10 +2207,6 @@ axes:
- id: python-version-windows
display_name: "Python"
values:
- id: "3.8"
display_name: "Python 3.8"
variables:
PYTHON_BINARY: "C:/python/Python38/python.exe"
- id: "3.9"
display_name: "Python 3.9"
variables:
@ -2297,10 +2231,8 @@ axes:
- id: python-version-windows-32
display_name: "Python"
values:
- id: "3.8"
display_name: "32-bit Python 3.8"
variables:
PYTHON_BINARY: "C:/python/32/Python38/python.exe"
- id: "3.9"
display_name: "32-bit Python 3.9"
variables:
@ -2500,7 +2432,6 @@ buildvariants:
- ".4.4"
- ".4.2"
- ".4.0"
- ".3.6"
- matrix_name: "test-macos-arm64"
matrix_spec:
@ -2572,7 +2503,6 @@ buildvariants:
- ".4.4"
- ".4.2"
- ".4.0"
- ".3.6"
- matrix_name: "tests-pyopenssl"
matrix_spec:
@ -2581,10 +2511,10 @@ buildvariants:
auth: "*"
ssl: "ssl"
pyopenssl: "*"
# Only test "noauth" with Python 3.8.
# Only test "noauth" with Python 3.9.
exclude_spec:
platform: rhel8
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.9", "pypy3.10"]
python-version: ["3.10", "3.11", "3.12", "3.13", "pypy3.9", "pypy3.10"]
auth: "noauth"
ssl: "ssl"
pyopenssl: "*"
@ -2667,19 +2597,22 @@ buildvariants:
display_name: "${compression} ${c-extensions} ${python-version} ${platform}"
tasks:
- "test-latest-standalone"
- "test-8.0-standalone"
- "test-7.0-standalone"
- "test-6.0-standalone"
- "test-5.0-standalone"
- "test-4.4-standalone"
- "test-4.2-standalone"
- "test-4.0-standalone"
rules:
# Server versions 3.6 and 4.0 support snappy and zlib.
# Server version 4.0 supports snappy and zlib but not zstd.
- if:
python-version: "*"
c-extensions: "*"
compression: ["snappy", "zlib"]
compression: ["zstd"]
then:
add_tasks:
remove_tasks:
- "test-4.0-standalone"
- "test-3.6-standalone"
- matrix_name: "tests-python-version-green-framework-rhel8"
matrix_spec:
@ -2716,7 +2649,7 @@ buildvariants:
matrix_spec:
platform: rhel7
# Python 3.10+ requires OpenSSL 1.1.1+
python-version: ["3.8", "3.9"]
python-version: ["3.9"]
auth-ssl: "*"
display_name: "OpenSSL 1.0.2 ${python-version} ${platform} ${auth-ssl}"
tasks:
@ -2739,12 +2672,12 @@ buildvariants:
then:
add_tasks: *encryption-server-versions
# Storage engine tests on RHEL 8.4 (x86_64) with Python 3.8.
# Storage engine tests on RHEL 8.4 (x86_64) with Python 3.9.
- matrix_name: "tests-storage-engines"
matrix_spec:
platform: rhel8
storage-engine: "*"
python-version: 3.8
python-version: "3.9"
display_name: "Storage ${storage-engine} ${python-version} ${platform}"
rules:
- if:
@ -2761,7 +2694,6 @@ buildvariants:
- "test-4.4-standalone"
- "test-4.2-standalone"
- "test-4.0-standalone"
- "test-3.6-standalone"
- if:
# MongoDB 4.2 drops support for MMAPv1
platform: rhel8
@ -2771,15 +2703,13 @@ buildvariants:
add_tasks:
- "test-4.0-standalone"
- "test-4.0-replica_set"
- "test-3.6-standalone"
- "test-3.6-replica_set"
# enableTestCommands=0 tests on RHEL 8.4 (x86_64) with Python 3.8.
# enableTestCommands=0 tests on RHEL 8.4 (x86_64) with Python 3.9.
- matrix_name: "test-disableTestCommands"
matrix_spec:
platform: rhel8
disableTestCommands: "*"
python-version: "3.8"
python-version: "3.9"
display_name: "Disable test commands ${python-version} ${platform}"
tasks:
- ".latest"
@ -2805,7 +2735,7 @@ buildvariants:
- matrix_name: "test-search-index-helpers"
matrix_spec:
platform: rhel8
python-version: "3.8"
python-version: "3.9"
display_name: "Search Index Helpers ${platform}"
tasks:
- name: "test_atlas_task_group_search_indexes"
@ -2813,7 +2743,7 @@ buildvariants:
- matrix_name: "tests-mod-wsgi"
matrix_spec:
platform: ubuntu-22.04
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
mod-wsgi-version: "*"
display_name: "${mod-wsgi-version} ${python-version} ${platform}"
tasks:
@ -2825,7 +2755,7 @@ buildvariants:
- matrix_name: "mockupdb-tests"
matrix_spec:
platform: rhel8
python-version: 3.8
python-version: 3.9
display_name: "MockupDB Tests"
tasks:
- name: "mockupdb"
@ -2833,7 +2763,7 @@ buildvariants:
- matrix_name: "tests-doctests"
matrix_spec:
platform: rhel8
python-version: ["3.8"]
python-version: ["3.9"]
display_name: "Doctests ${python-version} ${platform}"
tasks:
- name: "doctests"
@ -2873,7 +2803,7 @@ buildvariants:
- matrix_name: "data-lake-spec-tests"
matrix_spec:
platform: ubuntu-22.04
python-version: ["3.8", "3.10"]
python-version: ["3.9", "3.10"]
auth: "auth"
c-extensions: "*"
display_name: "Atlas Data Lake ${python-version} ${c-extensions}"
@ -2883,7 +2813,7 @@ buildvariants:
- matrix_name: "stable-api-tests"
matrix_spec:
platform: rhel8
python-version: ["3.8", "3.10"]
python-version: ["3.9", "3.10"]
auth: "auth"
versionedApi: "*"
display_name: "Versioned API ${versionedApi} ${python-version}"
@ -2891,12 +2821,15 @@ buildvariants:
tasks:
# Versioned API was introduced in MongoDB 4.7
- "test-latest-standalone"
- "test-8.0-standalone"
- "test-7.0-standalone"
- "test-6.0-standalone"
- "test-5.0-standalone"
- matrix_name: "ocsp-test"
matrix_spec:
platform: rhel8
python-version: ["3.8", "3.10", "pypy3.9", "pypy3.10"]
python-version: ["3.9", "3.10", "pypy3.9", "pypy3.10"]
mongodb-version: ["4.4", "5.0", "6.0", "7.0", "8.0", "latest"]
auth: "noauth"
ssl: "ssl"
@ -2908,7 +2841,7 @@ buildvariants:
- matrix_name: "ocsp-test-windows"
matrix_spec:
platform: windows
python-version-windows: ["3.8", "3.10"]
python-version-windows: ["3.9", "3.10"]
mongodb-version: ["4.4", "5.0", "6.0", "7.0", "8.0", "latest"]
auth: "noauth"
ssl: "ssl"

View File

@ -4,8 +4,8 @@ set -o xtrace
find_python3() {
PYTHON=""
# Add a fallback system python3 if it is available and Python 3.8+.
if is_python_38 "$(command -v python3)"; then
# Add a fallback system python3 if it is available and Python 3.9+.
if is_python_39 "$(command -v python3)"; then
PYTHON="$(command -v python3)"
fi
# Find a suitable toolchain version, if available.
@ -14,23 +14,23 @@ find_python3() {
if [ -d "/Library/Frameworks/Python.Framework/Versions/3.10" ]; then
PYTHON="/Library/Frameworks/Python.Framework/Versions/3.10/bin/python3"
# macos 10.14
elif [ -d "/Library/Frameworks/Python.Framework/Versions/3.8" ]; then
PYTHON="/Library/Frameworks/Python.Framework/Versions/3.8/bin/python3"
elif [ -d "/Library/Frameworks/Python.Framework/Versions/3.9" ]; then
PYTHON="/Library/Frameworks/Python.Framework/Versions/3.9/bin/python3"
fi
elif [ "Windows_NT" = "$OS" ]; then # Magic variable in cygwin
PYTHON="C:/python/Python38/python.exe"
PYTHON="C:/python/Python39/python.exe"
else
# Prefer our own toolchain, fall back to mongodb toolchain if it has Python 3.8+.
if [ -f "/opt/python/3.8/bin/python3" ]; then
PYTHON="/opt/python/3.8/bin/python3"
elif is_python_38 "$(command -v /opt/mongodbtoolchain/v4/bin/python3)"; then
# Prefer our own toolchain, fall back to mongodb toolchain if it has Python 3.9+.
if [ -f "/opt/python/3.9/bin/python3" ]; then
PYTHON="/opt/python/3.9/bin/python3"
elif is_python_39 "$(command -v /opt/mongodbtoolchain/v4/bin/python3)"; then
PYTHON="/opt/mongodbtoolchain/v4/bin/python3"
elif is_python_38 "$(command -v /opt/mongodbtoolchain/v3/bin/python3)"; then
elif is_python_39 "$(command -v /opt/mongodbtoolchain/v3/bin/python3)"; then
PYTHON="/opt/mongodbtoolchain/v3/bin/python3"
fi
fi
if [ -z "$PYTHON" ]; then
echo "Cannot test without python3.8+ installed!"
echo "Cannot test without python3.9+ installed!"
exit 1
fi
echo "$PYTHON"
@ -96,15 +96,15 @@ testinstall () {
fi
}
# Function that returns success if the provided Python binary is version 3.8 or later
# Function that returns success if the provided Python binary is version 3.9 or later
# Usage:
# is_python_38 /path/to/python
# is_python_39 /path/to/python
# * param1: Python binary
is_python_38() {
is_python_39() {
if [ -z "$1" ]; then
return 1
elif $1 -c "import sys; exit(sys.version_info[:2] < (3, 8))"; then
# runs when sys.version_info[:2] >= (3, 8)
elif $1 -c "import sys; exit(sys.version_info[:2] < (3, 9))"; then
# runs when sys.version_info[:2] >= (3, 9)
return 0
else
return 1

View File

@ -39,7 +39,7 @@ jobs:
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
- uses: actions/setup-python@v3
- uses: actions/setup-python@v5
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@ -53,7 +53,7 @@ jobs:
- uses: actions/setup-python@v5
with:
cache: 'pip'
python-version: 3.8
python-version: 3.9
cache-dependency-path: 'pyproject.toml'
allow-prereleases: true
@ -79,13 +79,12 @@ jobs:
env:
CIBW_MANYLINUX_X86_64_IMAGE: manylinux1
CIBW_MANYLINUX_I686_IMAGE: manylinux1
CIBW_BUILD: "cp38-${{ matrix.buildplat[1] }} cp39-${{ matrix.buildplat[1] }}"
CIBW_BUILD: "cp39-${{ matrix.buildplat[1] }} cp39-${{ matrix.buildplat[1] }}"
run: python -m cibuildwheel --output-dir wheelhouse
- name: Assert all versions in wheelhouse
if: ${{ ! startsWith(matrix.buildplat[1], 'macos') }}
run: |
ls wheelhouse/*cp38*.whl
ls wheelhouse/*cp39*.whl
ls wheelhouse/*cp310*.whl
ls wheelhouse/*cp311*.whl
@ -109,7 +108,7 @@ jobs:
- uses: actions/setup-python@v5
with:
# Build sdist on lowest supported Python
python-version: '3.8'
python-version: '3.9'
- name: Build SDist
run: |

View File

@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.8"
python-version: "3.9"
cache: 'pip'
cache-dependency-path: 'pyproject.toml'
- name: Install Python dependencies
@ -51,7 +51,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-20.04]
python-version: ["3.8", "pypy-3.9", "3.13"]
python-version: ["3.9", "pypy-3.9", "3.13"]
name: CPython ${{ matrix.python-version }}-${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@ -72,7 +72,7 @@ jobs:
pip install hatch
fi
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.10.0
uses: supercharge/mongodb-github-action@1.11.0
with:
mongodb-version: 6.0
- name: Run tests
@ -87,14 +87,14 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.8"
python-version: "3.9"
cache: 'pip'
cache-dependency-path: 'pyproject.toml'
- name: Install dependencies
run: |
pip install -U hatch pip
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.10.0
uses: supercharge/mongodb-github-action@1.11.0
with:
mongodb-version: '8.0.0-rc4'
- name: Run tests
@ -111,7 +111,7 @@ jobs:
cache: 'pip'
cache-dependency-path: 'pyproject.toml'
# Build docs on lowest supported Python for furo
python-version: '3.8'
python-version: '3.9'
- name: Install dependencies
run: |
pip install -U pip hatch
@ -129,7 +129,7 @@ jobs:
cache: 'pip'
cache-dependency-path: 'pyproject.toml'
# Build docs on lowest supported Python for furo
python-version: '3.8'
python-version: '3.9'
- name: Install dependencies
run: |
pip install -U pip hatch
@ -142,7 +142,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python: ["3.8", "3.11"]
python: ["3.9", "3.11"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
@ -167,7 +167,7 @@ jobs:
cache: 'pip'
cache-dependency-path: 'pyproject.toml'
# Build sdist on lowest supported Python
python-version: '3.8'
python-version: '3.9'
- name: Build SDist
shell: bash
run: |
@ -199,9 +199,9 @@ jobs:
cache: 'pip'
cache-dependency-path: 'sdist/test/pyproject.toml'
# Test sdist on lowest supported Python
python-version: '3.8'
python-version: '3.9'
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.10.0
uses: supercharge/mongodb-github-action@1.11.0
- name: Run connect test from sdist
shell: bash
run: |

View File

@ -16,7 +16,7 @@ be of interest or that has already been addressed.
## Supported Interpreters
PyMongo supports CPython 3.8+ and PyPy3.9+. Language features not
PyMongo supports CPython 3.9+ and PyPy3.9+. Language features not
supported by all interpreters can not be used.
## Style Guide

View File

@ -14,7 +14,7 @@ a native Python driver for MongoDB. The `gridfs` package is a
[gridfs](https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst/)
implementation on top of `pymongo`.
PyMongo supports MongoDB 3.6, 4.0, 4.2, 4.4, 5.0, 6.0, 7.0, and 8.0.
PyMongo supports MongoDB 4.0, 4.2, 4.4, 5.0, 6.0, 7.0, and 8.0.
## Support / Feedback
@ -90,7 +90,7 @@ package that is incompatible with PyMongo.
## Dependencies
PyMongo supports CPython 3.8+ and PyPy3.9+.
PyMongo supports CPython 3.9+ and PyPy3.9+.
Required dependencies:

View File

@ -1,6 +1,26 @@
Changelog
=========
Changes in Version 4.11.0
-------------------------
.. warning:: PyMongo 4.11 drops support for Python 3.8: Python 3.9+ or PyPy 3.9+ is now required.
.. warning:: PyMongo 4.11 drops support for MongoDB 3.6. PyMongo now supports MongoDB 4.0+.
Driver support for MongoDB 3.6 reached end of life in April 2024.
PyMongo 4.11 brings a number of changes including:
- Dropped support for Python 3.8.
- Dropped support for MongoDB 3.6.
Issues Resolved
...............
See the `PyMongo 4.11 release notes in JIRA`_ for the list of resolved issues
in this release.
.. _PyMongo 4.11 release notes in JIRA: https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=40784
Changes in Version 4.10.1
-------------------------

View File

@ -6,14 +6,14 @@ Also see the :ref:`TLSErrors` section.
Server reports wire version X, PyMongo requires Y
-------------------------------------------------
When one attempts to connect to a <=3.4 version server, PyMongo will throw the following error::
When one attempts to connect to a <=3.6 version server, PyMongo will throw the following error::
>>> client.admin.command('ping')
...
pymongo.errors.ConfigurationError: Server at localhost:27017 reports wire version 5, but this version of PyMongo requires at least 6 (MongoDB 3.6).
pymongo.errors.ConfigurationError: Server at localhost:27017 reports wire version 6, but this version of PyMongo requires at least 7 (MongoDB 4.0).
This is caused by the driver being too new for the server it is being run against.
To resolve this issue either upgrade your database to version >= 3.6 or downgrade to PyMongo 3.x which supports MongoDB >= 2.6.
To resolve this issue either upgrade your database to version >= 4.0 or downgrade to an early version of PyMongo which supports MongoDB < 4.0.
'Cursor' object has no attribute '_Cursor__killed'

View File

@ -97,9 +97,8 @@ the "MongoDB Challenge-Response" protocol::
Default Authentication Mechanism
--------------------------------
If no mechanism is specified, PyMongo automatically SCRAM-SHA-1 when connected
to MongoDB 3.6 and negotiates the mechanism to use (SCRAM-SHA-1
or SCRAM-SHA-256) when connected to MongoDB 4.0+.
If no mechanism is specified, PyMongo automatically negotiates the mechanism to use (SCRAM-SHA-1
or SCRAM-SHA-256) with the MongoDB server.
Default Database and "authSource"
---------------------------------

View File

@ -70,9 +70,9 @@ those datetimes to UTC automatically:
.. doctest::
>>> import pytz
>>> pacific = pytz.timezone("US/Pacific")
>>> aware_datetime = pacific.localize(datetime.datetime(2002, 10, 27, 6, 0, 0))
>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime
>>> aware_datetime = datetime(2002, 10, 27, 6, 0, 0, tzinfo=ZoneInfo("US/Pacific"))
>>> result = db.times.insert_one({"date": aware_datetime})
>>> db.times.find_one()["date"]
datetime.datetime(2002, 10, 27, 14, 0)
@ -97,7 +97,7 @@ out of MongoDB in US/Pacific time:
datetime.datetime(2002, 10, 27, 14, 0)
>>> aware_times = db.times.with_options(codec_options=CodecOptions(
... tz_aware=True,
... tzinfo=pytz.timezone('US/Pacific')))
... tzinfo=ZoneInfo("US/Pacific")))
>>> result = aware_times.find_one()['date']
datetime.datetime(2002, 10, 27, 6, 0, # doctest: +NORMALIZE_WHITESPACE
tzinfo=<DstTzInfo 'US/Pacific' PST-1 day, 16:00:00 STD>)

View File

@ -166,7 +166,7 @@ they are returned to the pool.
Does PyMongo support Python 3?
------------------------------
PyMongo supports CPython 3.8+ and PyPy3.9+. See the :doc:`python3` for details.
PyMongo supports CPython 3.9+ and PyPy3.9+. See the :doc:`python3` for details.
Does PyMongo support asynchronous frameworks like Gevent, asyncio, Tornado, or Twisted?
---------------------------------------------------------------------------------------

View File

@ -28,7 +28,7 @@ To upgrade using pip::
Dependencies
------------
PyMongo supports CPython 3.8+ and PyPy3.9+.
PyMongo supports CPython 3.9+ and PyPy3.9+.
Required dependencies
.....................
@ -140,7 +140,7 @@ See `http://bugs.python.org/issue11623 <http://bugs.python.org/issue11623>`_
for a more detailed explanation.
**Lion (10.7) and newer** - PyMongo's C extensions can be built against
versions of Python 3.8+ downloaded from python.org. In all cases Xcode must be
versions of Python 3.9+ downloaded from python.org. In all cases Xcode must be
installed with 'UNIX Development Support'.
**Xcode 5.1**: Starting with version 5.1 the version of clang that ships with

View File

@ -4,7 +4,7 @@ Python 3 FAQ
What Python 3 versions are supported?
-------------------------------------
PyMongo supports CPython 3.8+ and PyPy3.9+.
PyMongo supports CPython 3.9+ and PyPy3.9+.
Are there any PyMongo behavior changes with Python 3?
-----------------------------------------------------

View File

@ -1960,20 +1960,15 @@ class AsyncCollection(common.BaseObject, Generic[_DocumentType]):
collation: Optional[Collation],
) -> int:
"""Internal count command helper."""
# XXX: "ns missing" checks can be removed when we drop support for
# MongoDB 3.0, see SERVER-17051.
res = await self._command(
conn,
cmd,
read_preference=read_preference,
allowable_errors=["ns missing"],
codec_options=self._write_response_codec_options,
read_concern=self.read_concern,
collation=collation,
session=session,
)
if res.get("errmsg", "") == "ns missing":
return 0
return int(res["n"])
async def _aggregate_one_result(

View File

@ -498,9 +498,8 @@ class AsyncMongoClient(common.BaseObject, Generic[_DocumentType]):
- `authSource`: The database to authenticate on. Defaults to the
database specified in the URI, if provided, or to "admin".
- `authMechanism`: See :data:`~pymongo.auth.MECHANISMS` for options.
If no mechanism is specified, PyMongo automatically SCRAM-SHA-1
when connected to MongoDB 3.6 and negotiates the mechanism to use
(SCRAM-SHA-1 or SCRAM-SHA-256) when connected to MongoDB 4.0+.
If no mechanism is specified, PyMongo automatically negotiates the
mechanism to use (SCRAM-SHA-1 or SCRAM-SHA-256) with the MongoDB server.
- `authMechanismProperties`: Used to specify authentication mechanism
specific options. To specify the service name for GSSAPI
authentication pass authMechanismProperties='SERVICE_NAME:<service

View File

@ -66,8 +66,8 @@ MAX_WIRE_VERSION = 0
MAX_WRITE_BATCH_SIZE = 1000
# What this version of PyMongo supports.
MIN_SUPPORTED_SERVER_VERSION = "3.6"
MIN_SUPPORTED_WIRE_VERSION = 6
MIN_SUPPORTED_SERVER_VERSION = "4.0"
MIN_SUPPORTED_WIRE_VERSION = 7
# MongoDB 8.0
MAX_SUPPORTED_WIRE_VERSION = 25

View File

@ -99,7 +99,7 @@ class _SrvResolver:
raise ConfigurationError(str(exc)) from None
if len(results) > 1:
raise ConfigurationError("Only one TXT record is supported")
return (b"&".join([b"".join(res.strings) for res in results])).decode("utf-8")
return (b"&".join([b"".join(res.strings) for res in results])).decode("utf-8") # type: ignore[attr-defined]
def _resolve_uri(self, encapsulate_errors: bool) -> resolver.Answer:
try:
@ -121,7 +121,8 @@ class _SrvResolver:
# Construct address tuples
nodes = [
(maybe_decode(res.target.to_text(omit_final_dot=True)), res.port) for res in results
(maybe_decode(res.target.to_text(omit_final_dot=True)), res.port) # type: ignore[attr-defined]
for res in results
]
# Validate hosts

View File

@ -1959,20 +1959,15 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
collation: Optional[Collation],
) -> int:
"""Internal count command helper."""
# XXX: "ns missing" checks can be removed when we drop support for
# MongoDB 3.0, see SERVER-17051.
res = self._command(
conn,
cmd,
read_preference=read_preference,
allowable_errors=["ns missing"],
codec_options=self._write_response_codec_options,
read_concern=self.read_concern,
collation=collation,
session=session,
)
if res.get("errmsg", "") == "ns missing":
return 0
return int(res["n"])
def _aggregate_one_result(

View File

@ -496,9 +496,8 @@ class MongoClient(common.BaseObject, Generic[_DocumentType]):
- `authSource`: The database to authenticate on. Defaults to the
database specified in the URI, if provided, or to "admin".
- `authMechanism`: See :data:`~pymongo.auth.MECHANISMS` for options.
If no mechanism is specified, PyMongo automatically SCRAM-SHA-1
when connected to MongoDB 3.6 and negotiates the mechanism to use
(SCRAM-SHA-1 or SCRAM-SHA-256) when connected to MongoDB 4.0+.
If no mechanism is specified, PyMongo automatically negotiates the
mechanism to use (SCRAM-SHA-1 or SCRAM-SHA-256) with the MongoDB server.
- `authMechanismProperties`: Used to specify authentication mechanism
specific options. To specify the service name for GSSAPI
authentication pass authMechanismProperties='SERVICE_NAME:<service

View File

@ -8,7 +8,7 @@ dynamic = ["version", "dependencies", "optional-dependencies"]
description = "Python driver for MongoDB <http://www.mongodb.org>"
readme = "README.md"
license = {file="LICENSE"}
requires-python = ">=3.8"
requires-python = ">=3.9"
authors = [
{ name = "The MongoDB Python Team" },
]
@ -30,7 +30,6 @@ classifiers = [
"Programming Language :: Python :: Implementation :: PyPy",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",

View File

@ -1,6 +1,6 @@
sphinx>=5.3,<8
sphinx_rtd_theme>=2,<3
sphinx>=5.3,<9
sphinx_rtd_theme>=2,<4
readthedocs-sphinx-search~=0.3
sphinxcontrib-shellcheck>=1,<2
sphinx-autobuild>=2020.9.1
furo==2023.9.10
furo==2024.8.6

View File

@ -1,5 +1,5 @@
mypy==1.11.2
pyright==1.1.382.post1
pyright==1.1.383
typing_extensions
-r ./encryption.txt
-r ./ocsp.txt

View File

@ -17,8 +17,6 @@ def event_loop_policy():
# has issues with sharing sockets across loops (https://github.com/python/cpython/issues/122240)
# We explicitly use a different loop implementation here to prevent that issue
if sys.platform == "win32":
# Needed for Python 3.8.
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
return asyncio.WindowsSelectorEventLoopPolicy() # type: ignore[attr-defined]
return asyncio.get_event_loop_policy()

View File

@ -99,7 +99,7 @@ from pymongo.asynchronous.pool import (
from pymongo.asynchronous.settings import TOPOLOGY_TYPE
from pymongo.asynchronous.topology import _ErrorContext
from pymongo.client_options import ClientOptions
from pymongo.common import _UUID_REPRESENTATIONS, CONNECT_TIMEOUT, has_c
from pymongo.common import _UUID_REPRESENTATIONS, CONNECT_TIMEOUT, MIN_SUPPORTED_WIRE_VERSION, has_c
from pymongo.compression_support import _have_snappy, _have_zstd
from pymongo.driver_info import DriverInfo
from pymongo.errors import (
@ -2455,8 +2455,8 @@ class TestMongoClientFailover(AsyncMockClientTest):
self.addAsyncCleanup(c.close)
# Set host-specific information so we can test whether it is reset.
c.set_wire_version_range("a:1", 2, 6)
c.set_wire_version_range("b:2", 2, 7)
c.set_wire_version_range("a:1", 2, MIN_SUPPORTED_WIRE_VERSION)
c.set_wire_version_range("b:2", 2, MIN_SUPPORTED_WIRE_VERSION + 1)
await (await c._get_topology()).select_servers(writable_server_selector, _Op.TEST)
wait_until(lambda: len(c.nodes) == 2, "connect")
@ -2480,7 +2480,7 @@ class TestMongoClientFailover(AsyncMockClientTest):
sd_b = server_b.description
self.assertEqual(SERVER_TYPE.RSSecondary, sd_b.server_type)
self.assertEqual(2, sd_b.min_wire_version)
self.assertEqual(7, sd_b.max_wire_version)
self.assertEqual(MIN_SUPPORTED_WIRE_VERSION + 1, sd_b.max_wire_version)
async def test_network_error_on_query(self):
async def callback(client):

View File

@ -0,0 +1,54 @@
# Copyright 2024-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests to ensure that the async API is properly concurrent with asyncio."""
from __future__ import annotations
import asyncio
import time
from test.asynchronous import AsyncIntegrationTest, async_client_context
from test.utils import delay
_IS_SYNC = False
class TestAsyncConcurrency(AsyncIntegrationTest):
async def _task(self, client):
await client.db.test.find_one({"$where": delay(0.20)})
async def test_concurrency(self):
tasks = []
iterations = 5
client = await self.async_single_client()
await client.db.test.drop()
await client.db.test.insert_one({"x": 1})
start = time.time()
for _ in range(iterations):
await self._task(client)
sequential_time = time.time() - start
start = time.time()
for i in range(iterations):
tasks.append(self._task(client))
await asyncio.gather(*tasks)
concurrent_time = time.time() - start
percent_faster = (sequential_time - concurrent_time) / concurrent_time * 100
# We expect the concurrent tasks to be at least 75% faster on all platforms as a conservative benchmark
self.assertGreaterEqual(percent_faster, 75)

View File

@ -15,8 +15,6 @@ def event_loop_policy():
# has issues with sharing sockets across loops (https://github.com/python/cpython/issues/122240)
# We explicitly use a different loop implementation here to prevent that issue
if sys.platform == "win32":
# Needed for Python 3.8.
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
return asyncio.WindowsSelectorEventLoopPolicy() # type: ignore[attr-defined]
return asyncio.get_event_loop_policy()

View File

@ -66,7 +66,7 @@
"$oid": "000000000000000000000002"
},
"minWireVersion": 0,
"maxWireVersion": 21
"maxWireVersion": 7
}
]
],

View File

@ -25,7 +25,7 @@ try:
except ImportError:
_HAVE_MOCKUPDB = False
from pymongo import MongoClient
from pymongo import common
from pymongo.errors import ServerSelectionTimeoutError
pytestmark = pytest.mark.mockupdb
@ -39,7 +39,7 @@ class TestAuthRecoveringMember(PyMongoTestCase):
"ismaster",
{
"minWireVersion": 2,
"maxWireVersion": 6,
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
"ismaster": False,
"secondary": False,
"setName": "rs",

View File

@ -30,13 +30,16 @@ except ImportError:
from bson import Timestamp
from pymongo import DeleteMany, InsertOne, MongoClient, UpdateOne
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
from pymongo.errors import OperationFailure
pytestmark = pytest.mark.mockupdb
class TestClusterTime(PyMongoTestCase):
def cluster_time_conversation(self, callback, replies, max_wire_version=6):
def cluster_time_conversation(
self, callback, replies, max_wire_version=MIN_SUPPORTED_WIRE_VERSION
):
cluster_time = Timestamp(0, 0)
server = MockupDB()
@ -110,7 +113,7 @@ class TestClusterTime(PyMongoTestCase):
cluster_time = Timestamp(0, 0)
reply = {
"minWireVersion": 0,
"maxWireVersion": 6,
"maxWireVersion": MIN_SUPPORTED_WIRE_VERSION,
"$clusterTime": {"clusterTime": cluster_time},
}

View File

@ -29,6 +29,7 @@ except ImportError:
from bson.objectid import ObjectId
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
from pymongo.errors import OperationFailure
pytestmark = pytest.mark.mockupdb
@ -74,7 +75,7 @@ class TestRetryableErrorCodeCatch(PyMongoTestCase):
server = MockupDB()
server.run()
self.addCleanup(server.stop)
server.autoresponds("ismaster", maxWireVersion=6)
server.autoresponds("ismaster", maxWireVersion=MIN_SUPPORTED_WIRE_VERSION)
client = self.simple_client(server.uri)

View File

@ -29,6 +29,7 @@ except ImportError:
from pymongo import MongoClient
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
pytestmark = pytest.mark.mockupdb
@ -39,7 +40,7 @@ class TestCursorNamespace(PyMongoTestCase):
@classmethod
def setUpClass(cls):
cls.server = MockupDB(auto_ismaster={"maxWireVersion": 6})
cls.server = MockupDB(auto_ismaster={"maxWireVersion": 7})
cls.server.run()
cls.client = cls.unmanaged_simple_client(cls.server.uri)
@ -95,7 +96,7 @@ class TestKillCursorsNamespace(PyMongoTestCase):
@classmethod
def setUpClass(cls):
cls.server = MockupDB(auto_ismaster={"maxWireVersion": 6})
cls.server = MockupDB(auto_ismaster={"maxWireVersion": MIN_SUPPORTED_WIRE_VERSION})
cls.server.run()
cls.client = cls.unmanaged_simple_client(cls.server.uri)

View File

@ -29,7 +29,7 @@ except ImportError:
_HAVE_MOCKUPDB = False
from pymongo import MongoClient
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
pytestmark = pytest.mark.mockupdb
@ -43,7 +43,11 @@ class TestGetmoreSharded(PyMongoTestCase):
for server in servers:
server.subscribe(q.put)
server.autoresponds(
"ismaster", ismaster=True, msg="isdbgrid", minWireVersion=2, maxWireVersion=6
"ismaster",
ismaster=True,
msg="isdbgrid",
minWireVersion=2,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
)
server.run()
self.addCleanup(server.stop)

View File

@ -28,6 +28,7 @@ except ImportError:
from bson.objectid import ObjectId
from pymongo import MongoClient, has_c
from pymongo import version as pymongo_version
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
from pymongo.errors import OperationFailure
from pymongo.server_api import ServerApi, ServerApiVersion
@ -101,7 +102,12 @@ class TestHandshake(unittest.TestCase):
hosts = [server.address_string for server in (primary, secondary)]
primary_response = OpReply(
"ismaster", True, setName="rs", hosts=hosts, minWireVersion=2, maxWireVersion=6
"ismaster",
True,
setName="rs",
hosts=hosts,
minWireVersion=2,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
)
error_response = OpReply(0, errmsg="Cache Reader No keys found for HMAC ...", code=211)
@ -112,7 +118,7 @@ class TestHandshake(unittest.TestCase):
hosts=hosts,
secondary=True,
minWireVersion=2,
maxWireVersion=6,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
)
client = MongoClient(
@ -179,7 +185,9 @@ class TestHandshake(unittest.TestCase):
server.run()
self.addCleanup(server.stop)
primary_response = OpReply("ismaster", True, minWireVersion=2, maxWireVersion=6)
primary_response = OpReply(
"ismaster", True, minWireVersion=2, maxWireVersion=MIN_SUPPORTED_WIRE_VERSION
)
client = MongoClient(server.uri, username="username", password="password")
self.addCleanup(client.close)
@ -213,7 +221,7 @@ class TestHandshake(unittest.TestCase):
saslSupportedMechs=["SCRAM-SHA-256"],
speculativeAuthenticate=auth,
minWireVersion=2,
maxWireVersion=6,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
)
# Authentication should immediately fail with:
# OperationFailure: Server returned an invalid nonce.
@ -240,7 +248,12 @@ class TestHandshake(unittest.TestCase):
def test_handshake_max_wire(self):
server = MockupDB()
primary_response = {"hello": 1, "ok": 1, "minWireVersion": 0, "maxWireVersion": 6}
primary_response = {
"hello": 1,
"ok": 1,
"minWireVersion": 0,
"maxWireVersion": MIN_SUPPORTED_WIRE_VERSION,
}
self.found_auth_msg = False
def responder(request):

View File

@ -27,7 +27,7 @@ except ImportError:
_HAVE_MOCKUPDB = False
from pymongo import MongoClient
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
pytestmark = pytest.mark.mockupdb
@ -43,11 +43,15 @@ class TestInitialIsMaster(PyMongoTestCase):
# A single ismaster is enough for the client to be connected.
self.assertFalse(client.nodes)
server.receives("ismaster").ok(ismaster=True, minWireVersion=2, maxWireVersion=6)
server.receives("ismaster").ok(
ismaster=True, minWireVersion=2, maxWireVersion=MIN_SUPPORTED_WIRE_VERSION
)
wait_until(lambda: client.nodes, "update nodes", timeout=1)
# At least 10 seconds before next heartbeat.
server.receives("ismaster").ok(ismaster=True, minWireVersion=2, maxWireVersion=6)
server.receives("ismaster").ok(
ismaster=True, minWireVersion=2, maxWireVersion=MIN_SUPPORTED_WIRE_VERSION
)
self.assertGreaterEqual(time.time() - start, 10)

View File

@ -29,13 +29,14 @@ except ImportError:
from bson import SON
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
pytestmark = pytest.mark.mockupdb
class TestListIndexes(PyMongoTestCase):
def test_list_indexes_command(self):
server = MockupDB(auto_ismaster={"maxWireVersion": 6})
server = MockupDB(auto_ismaster={"maxWireVersion": MIN_SUPPORTED_WIRE_VERSION})
server.run()
self.addCleanup(server.stop)
client = self.simple_client(server.uri)

View File

@ -26,7 +26,7 @@ except ImportError:
_HAVE_MOCKUPDB = False
from pymongo import MongoClient
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
pytestmark = pytest.mark.mockupdb
@ -34,7 +34,9 @@ pytestmark = pytest.mark.mockupdb
class TestMaxStalenessMongos(PyMongoTestCase):
def test_mongos(self):
mongos = MockupDB()
mongos.autoresponds("ismaster", maxWireVersion=6, ismaster=True, msg="isdbgrid")
mongos.autoresponds(
"ismaster", maxWireVersion=MIN_SUPPORTED_WIRE_VERSION, ismaster=True, msg="isdbgrid"
)
mongos.run()
self.addCleanup(mongos.stop)

View File

@ -31,8 +31,6 @@ except ImportError:
from operations import upgrades # type: ignore[import]
from pymongo import MongoClient
pytestmark = pytest.mark.mockupdb

View File

@ -28,6 +28,7 @@ except ImportError:
from operations import operations # type: ignore[import]
from pymongo import MongoClient, ReadPreference
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
from pymongo.read_preferences import (
_MONGOS_MODES,
make_read_preference,
@ -41,7 +42,11 @@ class TestMongosCommandReadMode(unittest.TestCase):
def test_aggregate(self):
server = MockupDB()
server.autoresponds(
"ismaster", ismaster=True, msg="isdbgrid", minWireVersion=2, maxWireVersion=6
"ismaster",
ismaster=True,
msg="isdbgrid",
minWireVersion=2,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
)
self.addCleanup(server.stop)
server.run()
@ -76,7 +81,11 @@ def create_mongos_read_mode_test(mode, operation):
self.addCleanup(server.stop)
server.run()
server.autoresponds(
"ismaster", ismaster=True, msg="isdbgrid", minWireVersion=2, maxWireVersion=6
"ismaster",
ismaster=True,
msg="isdbgrid",
minWireVersion=2,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
)
pref = make_read_preference(read_pref_mode_from_name(mode), tag_sets=None)

View File

@ -26,6 +26,7 @@ except ImportError:
from pymongo import MongoClient
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
from pymongo.errors import ConnectionFailure
from pymongo.topology_description import TOPOLOGY_TYPE
@ -44,7 +45,11 @@ class TestNetworkDisconnectPrimary(unittest.TestCase):
hosts = [server.address_string for server in (primary, secondary)]
primary_response = OpReply(
ismaster=True, setName="rs", hosts=hosts, minWireVersion=2, maxWireVersion=6
ismaster=True,
setName="rs",
hosts=hosts,
minWireVersion=2,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
)
primary.autoresponds("ismaster", primary_response)
secondary.autoresponds(
@ -54,7 +59,7 @@ class TestNetworkDisconnectPrimary(unittest.TestCase):
setName="rs",
hosts=hosts,
minWireVersion=2,
maxWireVersion=6,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
)
client = MongoClient(primary.uri, replicaSet="rs")

View File

@ -30,7 +30,8 @@ except ImportError:
from operations import operations # type: ignore[import]
from pymongo import MongoClient, ReadPreference
from pymongo import ReadPreference
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
from pymongo.read_preferences import (
_MONGOS_MODES,
make_read_preference,
@ -66,7 +67,7 @@ class TestOpMsgMongos(OpMsgReadPrefBase):
"ismaster": True,
"msg": "isdbgrid", # Mongos.
"minWireVersion": 2,
"maxWireVersion": 6,
"maxWireVersion": MIN_SUPPORTED_WIRE_VERSION,
}
cls.primary = MockupDB(auto_ismaster=auto_ismaster)
cls.primary.run()
@ -93,7 +94,7 @@ class TestOpMsgReplicaSet(OpMsgReadPrefBase):
"setName": "rs",
"hosts": hosts,
"minWireVersion": 2,
"maxWireVersion": 6,
"maxWireVersion": MIN_SUPPORTED_WIRE_VERSION,
}
cls.primary.autoresponds(CommandBase("ismaster"), primary_ismaster)
secondary_ismaster = copy.copy(primary_ismaster)
@ -134,7 +135,7 @@ class TestOpMsgSingle(OpMsgReadPrefBase):
auto_ismaster = {
"ismaster": True,
"minWireVersion": 2,
"maxWireVersion": 6,
"maxWireVersion": MIN_SUPPORTED_WIRE_VERSION,
}
cls.primary = MockupDB(auto_ismaster=auto_ismaster)
cls.primary.run()

View File

@ -29,7 +29,7 @@ except ImportError:
from bson import SON
from pymongo import MongoClient
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
from pymongo.read_preferences import (
Nearest,
Primary,
@ -46,7 +46,11 @@ class TestQueryAndReadModeSharded(PyMongoTestCase):
"""Test OP_MSG sends non-primary $readPreference and never $query."""
server = MockupDB()
server.autoresponds(
"ismaster", ismaster=True, msg="isdbgrid", minWireVersion=2, maxWireVersion=6
"ismaster",
ismaster=True,
msg="isdbgrid",
minWireVersion=2,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
)
server.run()
self.addCleanup(server.stop)

View File

@ -30,7 +30,7 @@ except ImportError:
from operations import operations # type: ignore[import]
from pymongo import MongoClient
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
from pymongo.errors import ConnectionFailure
from pymongo.operations import _Op
from pymongo.server_type import SERVER_TYPE
@ -50,7 +50,9 @@ class TestResetAndRequestCheck(PyMongoTestCase):
def responder(request):
self.ismaster_time = time.time()
return request.ok(ismaster=True, minWireVersion=2, maxWireVersion=6)
return request.ok(
ismaster=True, minWireVersion=2, maxWireVersion=MIN_SUPPORTED_WIRE_VERSION
)
self.server.autoresponds("ismaster", responder)
self.server.run()

View File

@ -32,6 +32,7 @@ except ImportError:
from operations import operations # type: ignore[import]
from pymongo import MongoClient
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
pytestmark = pytest.mark.mockupdb
@ -45,7 +46,12 @@ class TestSlaveOkayRS(unittest.TestCase):
hosts = [server.address_string for server in (self.primary, self.secondary)]
self.primary.autoresponds(
"ismaster", ismaster=True, setName="rs", hosts=hosts, minWireVersion=2, maxWireVersion=6
"ismaster",
ismaster=True,
setName="rs",
hosts=hosts,
minWireVersion=2,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
)
self.secondary.autoresponds(
"ismaster",
@ -54,7 +60,7 @@ class TestSlaveOkayRS(unittest.TestCase):
setName="rs",
hosts=hosts,
minWireVersion=2,
maxWireVersion=6,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
)

View File

@ -36,6 +36,7 @@ except ImportError:
from operations import operations # type: ignore[import]
from pymongo import MongoClient
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
from pymongo.read_preferences import make_read_preference, read_pref_mode_from_name
pytestmark = pytest.mark.mockupdb
@ -52,7 +53,11 @@ class TestSlaveOkaySharded(unittest.TestCase):
server.run()
self.addCleanup(server.stop)
server.autoresponds(
"ismaster", minWireVersion=2, maxWireVersion=6, ismaster=True, msg="isdbgrid"
"ismaster",
minWireVersion=2,
maxWireVersion=MIN_SUPPORTED_WIRE_VERSION,
ismaster=True,
msg="isdbgrid",
)
self.mongoses_uri = f"mongodb://{self.mongos1.address_string},{self.mongos2.address_string}"

View File

@ -35,6 +35,7 @@ except ImportError:
from operations import operations # type: ignore[import]
from pymongo import MongoClient
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
from pymongo.read_preferences import make_read_preference, read_pref_mode_from_name
from pymongo.topology_description import TOPOLOGY_TYPE
@ -57,7 +58,7 @@ def create_slave_ok_single_test(mode, server_type, ismaster, operation):
def test(self):
ismaster_with_version = ismaster.copy()
ismaster_with_version["minWireVersion"] = 2
ismaster_with_version["maxWireVersion"] = 6
ismaster_with_version["maxWireVersion"] = MIN_SUPPORTED_WIRE_VERSION
self.server.autoresponds("ismaster", **ismaster_with_version)
self.assertIn(
operation.op_type, ("always-use-secondary", "may-use-secondary", "must-use-primary")

View File

@ -87,7 +87,7 @@ from bson.son import SON
from bson.tz_util import utc
from pymongo import event_loggers, message, monitoring
from pymongo.client_options import ClientOptions
from pymongo.common import _UUID_REPRESENTATIONS, CONNECT_TIMEOUT, has_c
from pymongo.common import _UUID_REPRESENTATIONS, CONNECT_TIMEOUT, MIN_SUPPORTED_WIRE_VERSION, has_c
from pymongo.compression_support import _have_snappy, _have_zstd
from pymongo.driver_info import DriverInfo
from pymongo.errors import (
@ -2411,8 +2411,8 @@ class TestMongoClientFailover(MockClientTest):
self.addCleanup(c.close)
# Set host-specific information so we can test whether it is reset.
c.set_wire_version_range("a:1", 2, 6)
c.set_wire_version_range("b:2", 2, 7)
c.set_wire_version_range("a:1", 2, MIN_SUPPORTED_WIRE_VERSION)
c.set_wire_version_range("b:2", 2, MIN_SUPPORTED_WIRE_VERSION + 1)
(c._get_topology()).select_servers(writable_server_selector, _Op.TEST)
wait_until(lambda: len(c.nodes) == 2, "connect")
@ -2436,7 +2436,7 @@ class TestMongoClientFailover(MockClientTest):
sd_b = server_b.description
self.assertEqual(SERVER_TYPE.RSSecondary, sd_b.server_type)
self.assertEqual(2, sd_b.min_wire_version)
self.assertEqual(7, sd_b.max_wire_version)
self.assertEqual(MIN_SUPPORTED_WIRE_VERSION + 1, sd_b.max_wire_version)
def test_network_error_on_query(self):
def callback(client):

View File

@ -250,7 +250,12 @@ class TestClusterTimeComparison(unittest.TestCase):
got_hello(
t,
("host", 27017),
{"ok": 1, "minWireVersion": 0, "maxWireVersion": 6, "$clusterTime": new},
{
"ok": 1,
"minWireVersion": 0,
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
"$clusterTime": new,
},
)
actual = t.max_cluster_time()

View File

@ -118,7 +118,7 @@ class TestServerDescription(unittest.TestCase):
"maxBsonObjectSize": 2,
"maxWriteBatchSize": 3,
"minWireVersion": 4,
"maxWireVersion": 5,
"maxWireVersion": 25,
"setName": "rs",
}
)
@ -130,7 +130,7 @@ class TestServerDescription(unittest.TestCase):
self.assertEqual(2, s.max_bson_size)
self.assertEqual(3, s.max_write_batch_size)
self.assertEqual(4, s.min_wire_version)
self.assertEqual(5, s.max_wire_version)
self.assertEqual(25, s.max_wire_version)
def test_default_max_message_size(self):
s = parse_hello_response({"ok": 1, HelloCompat.LEGACY_CMD: True, "maxBsonObjectSize": 2})

View File

@ -133,7 +133,7 @@ class TestSingleServerTopology(TopologyTest):
HelloCompat.LEGACY_CMD: True,
"hosts": ["a"],
"setName": "rs",
"maxWireVersion": 6,
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
},
),
(
@ -144,12 +144,17 @@ class TestSingleServerTopology(TopologyTest):
"secondary": True,
"hosts": ["a"],
"setName": "rs",
"maxWireVersion": 6,
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
},
),
(
SERVER_TYPE.Mongos,
{"ok": 1, HelloCompat.LEGACY_CMD: True, "msg": "isdbgrid", "maxWireVersion": 6},
{
"ok": 1,
HelloCompat.LEGACY_CMD: True,
"msg": "isdbgrid",
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
},
),
(
SERVER_TYPE.RSArbiter,
@ -159,14 +164,28 @@ class TestSingleServerTopology(TopologyTest):
"arbiterOnly": True,
"hosts": ["a"],
"setName": "rs",
"maxWireVersion": 6,
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
},
),
(
SERVER_TYPE.Standalone,
{
"ok": 1,
HelloCompat.LEGACY_CMD: True,
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
},
),
(SERVER_TYPE.Standalone, {"ok": 1, HelloCompat.LEGACY_CMD: True, "maxWireVersion": 6}),
# A "slave" in a master-slave deployment.
# This replication type was removed in MongoDB
# 4.0.
(SERVER_TYPE.Standalone, {"ok": 1, HelloCompat.LEGACY_CMD: False, "maxWireVersion": 6}),
(
SERVER_TYPE.Standalone,
{
"ok": 1,
HelloCompat.LEGACY_CMD: False,
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
},
),
]:
t = create_mock_topology(direct_connection=True)
@ -213,7 +232,10 @@ class TestSingleServerTopology(TopologyTest):
class TestMonitor(Monitor):
def _check_with_socket(self, *args, **kwargs):
if available:
return (Hello({"ok": 1, "maxWireVersion": 6}), round_trip_time)
return (
Hello({"ok": 1, "maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION}),
round_trip_time,
)
else:
raise AutoReconnect("mock monitor error")
@ -531,12 +553,12 @@ class TestMultiServerTopology(TopologyTest):
"setName": "rs",
"hosts": ["a"],
"minWireVersion": 1,
"maxWireVersion": 6,
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
},
)
self.assertEqual(server.description.min_wire_version, 1)
self.assertEqual(server.description.max_wire_version, 6)
self.assertEqual(server.description.max_wire_version, 7)
t.select_servers(any_server_selector, _Op.TEST)
# Incompatible.
@ -607,7 +629,7 @@ class TestMultiServerTopology(TopologyTest):
HelloCompat.LEGACY_CMD: True,
"setName": "rs",
"hosts": ["a", "b"],
"maxWireVersion": 6,
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
"maxWriteBatchSize": 1,
},
)
@ -621,7 +643,7 @@ class TestMultiServerTopology(TopologyTest):
"secondary": True,
"setName": "rs",
"hosts": ["a", "b"],
"maxWireVersion": 6,
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
"maxWriteBatchSize": 2,
},
)
@ -638,7 +660,7 @@ class TestMultiServerTopology(TopologyTest):
HelloCompat.LEGACY_CMD: True,
"setName": "rs",
"hosts": ["a", "b"],
"maxWireVersion": 6,
"maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION,
"maxWriteBatchSize": 2,
},
)
@ -735,7 +757,7 @@ class TestTopologyErrors(TopologyTest):
def _check_with_socket(self, *args, **kwargs):
hello_count[0] += 1
if hello_count[0] == 1:
return Hello({"ok": 1, "maxWireVersion": 6}), 0
return Hello({"ok": 1, "maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION}), 0
else:
raise AutoReconnect("mock monitor error")
@ -757,7 +779,7 @@ class TestTopologyErrors(TopologyTest):
def _check_with_socket(self, *args, **kwargs):
hello_count[0] += 1
if hello_count[0] in (1, 3):
return Hello({"ok": 1, "maxWireVersion": 6}), 0
return Hello({"ok": 1, "maxWireVersion": common.MIN_SUPPORTED_WIRE_VERSION}), 0
else:
raise AutoReconnect(f"mock monitor error #{hello_count[0]}")

View File

@ -26,7 +26,7 @@ from test.pymongo_mocks import DummyMonitor
from test.utils import MockPool, parse_read_preference
from bson import json_util
from pymongo.common import HEARTBEAT_FREQUENCY, clean_node
from pymongo.common import HEARTBEAT_FREQUENCY, MIN_SUPPORTED_WIRE_VERSION, clean_node
from pymongo.errors import AutoReconnect, ConfigurationError
from pymongo.hello import Hello, HelloCompat
from pymongo.operations import _Op
@ -85,7 +85,7 @@ def make_server_description(server, hosts):
if field in server:
hello_response[field] = server[field]
hello_response.setdefault("maxWireVersion", 6)
hello_response.setdefault("maxWireVersion", MIN_SUPPORTED_WIRE_VERSION)
# Sets _last_update_time to now.
sd = ServerDescription(

View File

@ -152,7 +152,7 @@ gridfs_files = [
def async_only_test(f: str) -> bool:
"""Return True for async tests that should not be converted to sync."""
return f in ["test_locks.py"]
return f in ["test_locks.py", "test_concurrency.py"]
test_files = [