Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


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

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions .evergreen/scripts/generate_config_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
##############

ALL_VERSIONS = ["4.4", "5.0", "6.0", "7.0", "8.0", "9.0", "rapid", "latest"]
CPYTHONS = ["3.10", "3.11", "3.12", "3.13", "3.14t", "3.14", "3.15t", "3.15"]
CPYTHONS = ["3.11", "3.12", "3.13", "3.14t", "3.14", "3.15t", "3.15"]
PYPYS = ["pypy3.11"]
MIN_SUPPORT_VERSIONS = ["3.9", "pypy3.9", "pypy3.10"]
MIN_SUPPORT_VERSIONS = ["3.11"]
ALL_PYTHONS = CPYTHONS + PYPYS
MIN_MAX_PYTHON = [CPYTHONS[0], CPYTHONS[-1]]
BATCHTIME_WEEK = 10080
Expand Down
8 changes: 4 additions & 4 deletions .evergreen/scripts/setup-uv-python.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Choose the Python that uv uses, and make sure uv can provide it.
#
# Input:
# UV_PYTHON - a version ("3.10", "3.14t"), an implementation ("pypy3.11"),
# UV_PYTHON - a version ("3.11", "3.14t"), an implementation ("pypy3.11"),
# or an interpreter path ("/usr/bin/python3.11").
#
# Exports:
Expand All @@ -11,7 +11,7 @@
# UV_PYTHON_PREFERENCE - "system" so the toolchain wins over managed installs.
# A preference set by the task is left alone.
# UV_PYTHON - the Python interpreter uv uses; defaults to CPython
# 3.10 when the task does not set one.
# 3.11 when the task does not set one.
set -euo pipefail

HERE=$(dirname "${BASH_SOURCE:-$0}")
Expand Down Expand Up @@ -46,9 +46,9 @@ fi
# Default to a known-good Python so behavior is deterministic when a task does
# not pin one. Selecting the uv binary is separate and driven by the required
# uv version in pyproject.toml.
export UV_PYTHON="${UV_PYTHON:-3.10}"
export UV_PYTHON="${UV_PYTHON:-3.11}"

# Print the Python toolchain bin dir for a version like "3.10" or "3.14t".
# Print the Python toolchain bin dir for a version like "3.11" or "3.14t".
function _toolchain_dir() {
local version="$1" dir
# Only plain CPython versions live in the toolchain.
Expand Down
2 changes: 1 addition & 1 deletion .evergreen/scripts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class Distro:
EXTRA_TESTS = ["aws_lambda", "doctest"]

# The managed Python version used for perf tests (PYTHON-6135).
PERF_PYTHON_VERSION = "3.10.11"
PERF_PYTHON_VERSION = "3.11.9"

# Tests that do not use run-mongodb directly.
NO_RUN_ORCHESTRATION = [
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@ jobs:
- name: Assert all versions in wheelhouse
if: ${{ ! startsWith(matrix.buildplat[1], 'macos') }}
run: |
ls wheelhouse/*cp39*.whl
ls wheelhouse/*cp310*.whl
ls wheelhouse/*cp311*.whl
ls wheelhouse/*cp312*.whl
ls wheelhouse/*cp313*.whl
Expand Down Expand Up @@ -118,7 +116,7 @@ jobs:
- uses: actions/setup-python@v7.0.0
with:
# Build sdist on lowest supported Python
python-version: "3.9"
python-version: "3.11"

- name: Build SDist
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sbom.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v7.0.0
with:
python-version: "3.10"
python-version: "3.11"

- name: Generate SBOM
run: |
Expand Down
20 changes: 10 additions & 10 deletions .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
- name: Install Python tooling
uses: mongodb-labs/drivers-github-tools/python/setup@4089c3eb27d7a5101d987088c3345013858d65f8 # v3.0.6
with:
python-version: "3.10"
python-version: "3.11"
# Runs before the install so a stale lock fails in seconds rather than
# after the build and typecheck.
- name: Check lockfile is up to date
Expand Down Expand Up @@ -71,7 +71,7 @@ jobs:
matrix:
# Tests currently only pass on ubuntu on GitHub Actions.
os: [ubuntu-latest]
python-version: ["3.10", "3.13t", "3.15"]
python-version: ["3.11", "3.13t", "3.15"]
mongodb-version: ["8.0"]

name: Python ${{ matrix.python-version }}-${{ matrix.os }}
Expand Down Expand Up @@ -105,7 +105,7 @@ jobs:
- name: Install Python tooling
uses: mongodb-labs/drivers-github-tools/python/setup@4089c3eb27d7a5101d987088c3345013858d65f8 # v3.0.6
with:
python-version: "3.10"
python-version: "3.11"
- id: setup-mongodb
uses: mongodb-labs/drivers-evergreen-tools@354a81692bfd2b654a38277b681d248507d17800 # v1.2.0
with:
Expand All @@ -131,7 +131,7 @@ jobs:
- name: Install Python tooling
uses: mongodb-labs/drivers-github-tools/python/setup@4089c3eb27d7a5101d987088c3345013858d65f8 # v3.0.6
with:
python-version: "3.10"
python-version: "3.11"
- name: Install dependencies
run: just install
- id: setup-mongodb
Expand All @@ -153,7 +153,7 @@ jobs:
- name: Install Python tooling
uses: mongodb-labs/drivers-github-tools/python/setup@4089c3eb27d7a5101d987088c3345013858d65f8 # v3.0.6
with:
python-version: "3.10"
python-version: "3.11"
- name: Install dependencies
run: just install
- name: Build docs
Expand All @@ -164,7 +164,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python: ["3.10", "3.11"]
python: ["3.11"]
steps:
- uses: actions/checkout@v7.0.1
with:
Expand All @@ -190,7 +190,7 @@ jobs:
- name: Install Python tooling
uses: mongodb-labs/drivers-github-tools/python/setup@4089c3eb27d7a5101d987088c3345013858d65f8 # v3.0.6
with:
python-version: "3.10"
python-version: "3.11"
- name: Install dependencies
run: just install
- id: setup-mongodb
Expand Down Expand Up @@ -218,7 +218,7 @@ jobs:
cache: 'pip'
cache-dependency-path: 'pyproject.toml'
# Build sdist on lowest supported Python
python-version: "3.9"
python-version: "3.11"
- name: Build SDist
shell: bash
run: |
Expand Down Expand Up @@ -252,7 +252,7 @@ jobs:
cache: 'pip'
cache-dependency-path: 'sdist/test/pyproject.toml'
# Test sdist on lowest supported Python
python-version: "3.9"
python-version: "3.11"
- id: setup-mongodb
uses: mongodb-labs/drivers-evergreen-tools@354a81692bfd2b654a38277b681d248507d17800 # v1.2.0
- name: Run connect test from sdist
Expand All @@ -276,7 +276,7 @@ jobs:
- name: Install Python tooling
uses: mongodb-labs/drivers-github-tools/python/setup@4089c3eb27d7a5101d987088c3345013858d65f8 # v3.0.6
with:
python-version: "3.9"
python-version: "3.11"
- id: setup-mongodb
uses: mongodb-labs/drivers-evergreen-tools@354a81692bfd2b654a38277b681d248507d17800 # v1.2.0
with:
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/uv-lock-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,9 @@ jobs:
- name: Install uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.10"
python-version: "3.11"
- uses: mongodb-labs/drivers-github-tools/python/uv-lock-update@4089c3eb27d7a5101d987088c3345013858d65f8 # v3.0.6
with:
app_id: ${{ vars.APP_ID }}
private_key: ${{ secrets.APP_PRIVATE_KEY }}
dry_run: ${{ inputs.dry_run || 'false' }}
# Unset UV_EXCLUDE_NEWER, so the cutoff comes from exclude-newer in
# pyproject.toml instead of the action default.
exclude_newer: ""
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ be of interest or that has already been addressed.

## Supported Interpreters

PyMongo supports CPython 3.9+ and PyPy3.9+. Language features not
PyMongo supports CPython 3.11+ and PyPy 3.11+. Language features not
supported by all interpreters can not be used.

## Style Guide
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ package that is incompatible with PyMongo.

## Dependencies

PyMongo supports CPython 3.9+ and PyPy3.9+. PyPy support is deprecated and will be removed in a future release.
PyMongo supports CPython 3.11+ and PyPy3.11+. PyPy support is deprecated and will be removed in a future release.

Required dependencies:

Expand Down
4 changes: 4 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ 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.

- Added support for Python 3.15.
- Dropped support for Python 3.9 and 3.10 and PyPy 3.9 and 3.10 (PYTHON-6138).
- Added support for running the synchronous and asynchronous clients in
subinterpreters, including inside
``concurrent.futures.InterpreterPoolExecutor`` (Python 3.14+). Only in
Expand Down
75 changes: 75 additions & 0 deletions pymongo/_kms_connect_shared.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright 2026-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
#
# https://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.

"""KMS connection support shared by the synchronous and asynchronous APIs.

The per-API connection logic lives in ``pymongo.asynchronous._kms_connect``
and its generated synchronous mirror.
"""

from __future__ import annotations

import contextlib
import socket
from collections.abc import Awaitable
from dataclasses import dataclass
from typing import Any, Callable


@dataclass(frozen=True)
class KMSConnectContext:
"""Information about a pending KMS connection.

Passed to ``kms_connect_callback``, which must return a plain, unwrapped
:class:`socket.socket`. The driver performs the KMS TLS handshake over it,
verifying against ``host`` rather than the peer actually reached.

:param host: Hostname of the KMS server, and the TLS verification target.
:param port: Port of the KMS server.
:param timeout: Seconds allowed for the connection: the default KMS
connect timeout, capped by the remaining ``timeoutMS`` budget.

.. note:: ``timeoutMS`` does not constrain KMS requests for explicit
encryption, so ``timeout`` is always the default there. Automatic
encryption passes the remaining budget. This deviates from the Client
Side Operations Timeout specification; see PYTHON-6037.

.. versionadded:: 4.19
"""

host: str
port: int
timeout: float


# A callback that opens a connection to a KMS host.
AsyncKMSConnectCallback = Callable[[KMSConnectContext], Awaitable[socket.socket]]
KMSConnectCallback = Callable[[KMSConnectContext], socket.socket]


def _close_rejected_kms_socket(obj: Any) -> None:
"""Close a callback return value that failed validation, best effort.

``_connect_kms`` raises on a contract violation, so no caller takes
ownership. Tolerates non-socket values and ``close()`` failures.
"""
close = getattr(obj, "close", None)
if callable(close):
with contextlib.suppress(Exception):
close()


# Sphinx documents this class under pymongo.encryption_options, so the
# definition must claim that module name.
KMSConnectContext.__module__ = "pymongo.encryption_options"
Loading
Loading