Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
699 changes: 256 additions & 443 deletions .evergreen/generated_configs/tasks.yml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .evergreen/scripts/generate_config_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
##############

ALL_VERSIONS = ["4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "rapid", "latest"]
CPYTHONS = ["3.10", "3.9", "3.11", "3.12", "3.13", "3.14"]
CPYTHONS = ["3.10", "3.11", "3.12", "3.13", "3.14"]
PYPYS = ["pypy3.10"]
ALL_PYTHONS = CPYTHONS + PYPYS
MIN_MAX_PYTHON = [CPYTHONS[0], CPYTHONS[-1]]
Expand Down
32 changes: 16 additions & 16 deletions .evergreen/utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ find_python3() {
PYTHON=""
# Find a suitable toolchain version, if available.
if [ "$(uname -s)" = "Darwin" ]; then
PYTHON="/Library/Frameworks/Python.Framework/Versions/3.9/bin/python3"
PYTHON="/Library/Frameworks/Python.Framework/Versions/3.10/bin/python3"
elif [ "Windows_NT" = "${OS:-}" ]; then # Magic variable in cygwin
PYTHON="C:/python/Python39/python.exe"
PYTHON="C:/python/Python310/python.exe"
else
# Prefer our own toolchain, fall back to mongodb toolchain if it has Python 3.9+.
if [ -f "/opt/python/3.9/bin/python3" ]; then
# Prefer our own toolchain, fall back to mongodb toolchain if it has Python 3.10+.
if [ -f "/opt/python/3.10/bin/python3" ]; then
PYTHON="/opt/python/Current/bin/python3"
elif is_python_39 "$(command -v /opt/mongodbtoolchain/v5/bin/python3)"; then
elif is_python_310 "$(command -v /opt/mongodbtoolchain/v5/bin/python3)"; then
PYTHON="/opt/mongodbtoolchain/v5/bin/python3"
elif is_python_39 "$(command -v /opt/mongodbtoolchain/v4/bin/python3)"; then
elif is_python_310 "$(command -v /opt/mongodbtoolchain/v4/bin/python3)"; then
PYTHON="/opt/mongodbtoolchain/v4/bin/python3"
elif is_python_39 "$(command -v /opt/mongodbtoolchain/v3/bin/python3)"; then
elif is_python_310 "$(command -v /opt/mongodbtoolchain/v3/bin/python3)"; then
PYTHON="/opt/mongodbtoolchain/v3/bin/python3"
fi
fi
# Add a fallback system python3 if it is available and Python 3.9+.
# Add a fallback system python3 if it is available and Python 3.10+.
if [ -z "$PYTHON" ]; then
if is_python_39 "$(command -v python3)"; then
if is_python_310 "$(command -v python3)"; then
PYTHON="$(command -v python3)"
fi
fi
if [ -z "$PYTHON" ]; then
echo "Cannot test without python3.9+ installed!"
echo "Cannot test without python3.10+ installed!"
exit 1
fi
echo "$PYTHON"
Expand Down Expand Up @@ -99,15 +99,15 @@ testinstall () {
fi
}

# Function that returns success if the provided Python binary is version 3.9 or later
# Function that returns success if the provided Python binary is version 3.10 or later
# Usage:
# is_python_39 /path/to/python
# is_python_310 /path/to/python
# * param1: Python binary
is_python_39() {
is_python_310() {
if [ -z "$1" ]; then
return 1
elif $1 -c "import sys; exit(sys.version_info[:2] < (3, 9))"; then
# runs when sys.version_info[:2] >= (3, 9)
elif $1 -c "import sys; exit(sys.version_info[:2] < (3, 10))"; then
# runs when sys.version_info[:2] >= (3, 10)
return 0
else
return 1
Expand All @@ -131,7 +131,7 @@ get_python_binary() {
else
PYTHON="/opt/python/$version/bin/python3"
fi
if is_python_39 "$(command -v $PYTHON)"; then
if is_python_310 "$(command -v $PYTHON)"; then
echo "$PYTHON"
else
echo "Could not find suitable python binary for '$version'" >&2
Expand Down
13 changes: 3 additions & 10 deletions .github/workflows/dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,17 @@ jobs:
CIBW_BUILD: ${{ matrix.buildplat[2] }}
run: python -m cibuildwheel --output-dir wheelhouse

- name: Build manylinux1 wheels
if: ${{ matrix.buildplat[1] == 'manylinux_x86_64' || matrix.buildplat[1] == 'manylinux_i686' }}
env:
CIBW_MANYLINUX_X86_64_IMAGE: manylinux1
CIBW_MANYLINUX_I686_IMAGE: manylinux1
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/*cp39*.whl
ls wheelhouse/*cp310*.whl
ls wheelhouse/*cp311*.whl
ls wheelhouse/*cp312*.whl
ls wheelhouse/*cp313*.whl
ls wheelhouse/*cp314*.whl
# Free-threading builds:
ls wheelhouse/*cp313t*.whl
ls wheelhouse/*cp314t*.whl

- uses: actions/upload-artifact@v4
with:
Expand All @@ -118,7 +111,7 @@ jobs:
- uses: actions/setup-python@v6
with:
# Build sdist on lowest supported Python
python-version: '3.9'
python-version: "3.10"

- name: Build SDist
run: |
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v5
with:
enable-cache: true
python-version: "3.9"
python-version: "3.10"
- name: Install just
run: uv tool install rust-just
- name: Install Python dependencies
Expand Down Expand Up @@ -56,7 +56,7 @@ jobs:
matrix:
# Tests currently only pass on ubuntu on GitHub Actions.
os: [ubuntu-latest]
python-version: ["3.9", "pypy-3.10", "3.13t"]
python-version: ["3.10", "pypy-3.10", "3.13t"]
mongodb-version: ["8.0"]

name: CPython ${{ matrix.python-version }}-${{ matrix.os }}
Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:
uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v5
with:
enable-cache: true
python-version: "3.9"
python-version: "3.10"
- name: Install just
run: uv tool install rust-just
- id: setup-mongodb
Expand All @@ -112,7 +112,7 @@ jobs:
uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v5
with:
enable-cache: true
python-version: "3.9"
python-version: "3.10"
- name: Install just
run: uv tool install rust-just
- name: Install dependencies
Expand All @@ -131,7 +131,7 @@ jobs:
uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v5
with:
enable-cache: true
python-version: "3.9"
python-version: "3.10"
- name: Install just
run: uv tool install rust-just
- name: Install dependencies
Expand All @@ -144,7 +144,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python: ["3.9", "3.11"]
python: ["3.10", "3.11"]
steps:
- uses: actions/checkout@v5
with:
Expand Down Expand Up @@ -175,7 +175,7 @@ jobs:
cache: 'pip'
cache-dependency-path: 'pyproject.toml'
# Build sdist on lowest supported Python
python-version: '3.9'
python-version: "3.10"
- name: Build SDist
shell: bash
run: |
Expand Down Expand Up @@ -209,7 +209,7 @@ jobs:
cache: 'pip'
cache-dependency-path: 'sdist/test/pyproject.toml'
# Test sdist on lowest supported Python
python-version: '3.9'
python-version: "3.10"
- id: setup-mongodb
uses: mongodb-labs/drivers-evergreen-tools@master
- name: Run connect test from sdist
Expand All @@ -233,7 +233,7 @@ jobs:
- name: Install uv
uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v5
with:
python-version: '3.9'
python-version: "3.10"
- id: setup-mongodb
uses: mongodb-labs/drivers-evergreen-tools@master
with:
Expand Down
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.10+. Language features not
PyMongo supports CPython 3.10+ and PyPy3.10+. 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 @@ -97,7 +97,7 @@ package that is incompatible with PyMongo.

## Dependencies

PyMongo supports CPython 3.9+ and PyPy3.10+.
PyMongo supports CPython 3.10+ and PyPy3.10+.

Required dependencies:

Expand Down
3 changes: 3 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ Changes in Version 4.16.0 (XXXX/XX/XX)

PyMongo 4.16 brings a number of changes including:

.. warning:: PyMongo 4.16 drops support for Python 3.9: Python 3.10+is now required.

- Dropped support for Python 3.9.
- Removed invalid documents from :class:`bson.errors.InvalidDocument` error messages as
doing so may leak sensitive user data.
Instead, invalid documents are stored in :attr:`bson.errors.InvalidDocument.document`.
Expand Down
1 change: 0 additions & 1 deletion gridfs/asynchronous/grid_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
from pymongo.asynchronous.collection import AsyncCollection
from pymongo.asynchronous.cursor import AsyncCursor
from pymongo.asynchronous.database import AsyncDatabase
from pymongo.asynchronous.helpers import anext
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At long last 🙏

from pymongo.common import validate_string
from pymongo.errors import (
BulkWriteError,
Expand Down
1 change: 0 additions & 1 deletion gridfs/synchronous/grid_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
from pymongo.synchronous.collection import Collection
from pymongo.synchronous.cursor import Cursor
from pymongo.synchronous.database import Database
from pymongo.synchronous.helpers import next

_IS_SYNC = True

Expand Down
1 change: 0 additions & 1 deletion pymongo/asynchronous/cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
from bson.code import Code
from bson.son import SON
from pymongo import _csot, helpers_shared
from pymongo.asynchronous.helpers import anext
from pymongo.collation import validate_collation_or_none
from pymongo.common import (
validate_is_document_type,
Expand Down
16 changes: 0 additions & 16 deletions pymongo/asynchronous/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
from __future__ import annotations

import asyncio
import builtins
import socket
import sys
from typing import (
Any,
Callable,
Expand Down Expand Up @@ -86,17 +84,3 @@ async def _getaddrinfo(
return await loop.getaddrinfo(host, port, **kwargs) # type: ignore[return-value]
else:
return socket.getaddrinfo(host, port, **kwargs)


if sys.version_info >= (3, 10):
anext = builtins.anext
aiter = builtins.aiter
else:

async def anext(cls: Any) -> Any:
"""Compatibility function until we drop 3.9 support: https://docs.python.org/3/library/functions.html#anext."""
return await cls.__anext__()

def aiter(cls: Any) -> Any:
"""Compatibility function until we drop 3.9 support: https://docs.python.org/3/library/functions.html#anext."""
return cls.__aiter__()
1 change: 0 additions & 1 deletion pymongo/synchronous/cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
_RawBatchQuery,
)
from pymongo.response import PinnedResponse
from pymongo.synchronous.helpers import next
from pymongo.typings import _Address, _CollationIn, _DocumentOut, _DocumentType
from pymongo.write_concern import validate_boolean

Expand Down
16 changes: 0 additions & 16 deletions pymongo/synchronous/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
from __future__ import annotations

import asyncio
import builtins
import socket
import sys
from typing import (
Any,
Callable,
Expand Down Expand Up @@ -86,17 +84,3 @@ def _getaddrinfo(
return loop.getaddrinfo(host, port, **kwargs) # type: ignore[return-value]
else:
return socket.getaddrinfo(host, port, **kwargs)


if sys.version_info >= (3, 10):
next = builtins.next
iter = builtins.iter
else:

def next(cls: Any) -> Any:
"""Compatibility function until we drop 3.9 support: https://docs.python.org/3/library/functions.html#next."""
return cls.__next__()

def iter(cls: Any) -> Any:
"""Compatibility function until we drop 3.9 support: https://docs.python.org/3/library/functions.html#next."""
return cls.__iter__()
1 change: 0 additions & 1 deletion test/asynchronous/test_change_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
from bson.raw_bson import DEFAULT_RAW_BSON_OPTIONS, RawBSONDocument
from pymongo import AsyncMongoClient
from pymongo.asynchronous.command_cursor import AsyncCommandCursor
from pymongo.asynchronous.helpers import anext
from pymongo.errors import (
InvalidOperation,
OperationFailure,
Expand Down
1 change: 0 additions & 1 deletion test/asynchronous/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@
from pymongo.asynchronous.command_cursor import AsyncCommandCursor
from pymongo.asynchronous.cursor import AsyncCursor, CursorType
from pymongo.asynchronous.database import AsyncDatabase
from pymongo.asynchronous.helpers import anext
from pymongo.asynchronous.mongo_client import AsyncMongoClient
from pymongo.asynchronous.pool import (
AsyncConnection,
Expand Down
1 change: 0 additions & 1 deletion test/asynchronous/test_collation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from test.utils_shared import EventListener, OvertCommandListener
from typing import Any

from pymongo.asynchronous.helpers import anext
from pymongo.collation import (
Collation,
CollationAlternate,
Expand Down
1 change: 0 additions & 1 deletion test/asynchronous/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
from pymongo import ASCENDING, DESCENDING, GEO2D, GEOSPHERE, HASHED, TEXT
from pymongo.asynchronous.collection import AsyncCollection, ReturnDocument
from pymongo.asynchronous.command_cursor import AsyncCommandCursor
from pymongo.asynchronous.helpers import anext
from pymongo.asynchronous.mongo_client import AsyncMongoClient
from pymongo.bulk_shared import BulkWriteError
from pymongo.cursor_shared import CursorType
Expand Down
1 change: 0 additions & 1 deletion test/asynchronous/test_cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
from bson.raw_bson import RawBSONDocument
from pymongo import ASCENDING, DESCENDING
from pymongo.asynchronous.cursor import AsyncCursor, CursorType
from pymongo.asynchronous.helpers import anext
from pymongo.collation import Collation
from pymongo.errors import ExecutionTimeout, InvalidOperation, OperationFailure, PyMongoError
from pymongo.operations import _IndexList
Expand Down
1 change: 0 additions & 1 deletion test/asynchronous/test_custom_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
from bson.int64 import Int64
from bson.raw_bson import RawBSONDocument
from pymongo.asynchronous.collection import ReturnDocument
from pymongo.asynchronous.helpers import anext
from pymongo.errors import DuplicateKeyError
from pymongo.message import _CursorAddress

Expand Down
1 change: 0 additions & 1 deletion test/asynchronous/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
from pymongo.asynchronous import auth
from pymongo.asynchronous.collection import AsyncCollection
from pymongo.asynchronous.database import AsyncDatabase
from pymongo.asynchronous.helpers import anext
from pymongo.asynchronous.mongo_client import AsyncMongoClient
from pymongo.errors import (
CollectionInvalid,
Expand Down
1 change: 0 additions & 1 deletion test/asynchronous/test_encryption.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import pytest

from pymongo.asynchronous.collection import AsyncCollection
from pymongo.asynchronous.helpers import anext
from pymongo.daemon import _spawn_daemon
from pymongo.uri_parser_shared import _parse_kms_tls_options

Expand Down
1 change: 0 additions & 1 deletion test/asynchronous/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
from test.utils_shared import async_wait_until

import pymongo
from pymongo.asynchronous.helpers import anext
from pymongo.errors import ConnectionFailure, OperationFailure
from pymongo.read_concern import ReadConcern
from pymongo.read_preferences import ReadPreference
Expand Down
1 change: 0 additions & 1 deletion test/asynchronous/test_grid_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
)
from gridfs.errors import NoFile
from pymongo import AsyncMongoClient
from pymongo.asynchronous.helpers import aiter, anext
from pymongo.errors import ConfigurationError, ServerSelectionTimeoutError
from pymongo.message import _CursorAddress

Expand Down
Loading
Loading