diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 14e3426b32..7fb48c8054 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -2233,10 +2233,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 +2265,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 +2289,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: @@ -2581,10 +2571,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: "*" @@ -2716,7 +2706,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 +2729,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: @@ -2774,12 +2764,12 @@ buildvariants: - "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 +2795,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 +2803,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 +2815,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 +2823,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 +2863,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 +2873,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}" @@ -2896,7 +2886,7 @@ buildvariants: - 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 +2898,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" diff --git a/.evergreen/utils.sh b/.evergreen/utils.sh index 1a5e2a153f..d44425a905 100755 --- a/.evergreen/utils.sh +++ b/.evergreen/utils.sh @@ -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 diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index 7ec55dd3b3..fbc7ff7390 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -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: | diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 3ecdfa52f3..e55444ceca 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -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 @@ -87,7 +87,7 @@ 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 @@ -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,7 +199,7 @@ 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.11.0 - name: Run connect test from sdist diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2c2a5f4316..7516fbc9ed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 diff --git a/README.md b/README.md index 1076b66377..9b5aa33f78 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/doc/changelog.rst b/doc/changelog.rst index 574ecad763..a73a89a0ef 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -1,6 +1,11 @@ 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. + Changes in Version 4.10.1 ------------------------- diff --git a/doc/faq.rst b/doc/faq.rst index f0463badaa..15950e7716 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -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? --------------------------------------------------------------------------------------- diff --git a/doc/installation.rst b/doc/installation.rst index ee83b30c6f..dd8eb6ab42 100644 --- a/doc/installation.rst +++ b/doc/installation.rst @@ -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 `_ 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 diff --git a/doc/python3.rst b/doc/python3.rst index 148c5ee454..1ea43b3ccb 100644 --- a/doc/python3.rst +++ b/doc/python3.rst @@ -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? ----------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index 30c7c046b9..2688aab27e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version", "dependencies", "optional-dependencies"] description = "Python driver for MongoDB " 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", diff --git a/test/asynchronous/conftest.py b/test/asynchronous/conftest.py index c08f224abd..e443dff6c0 100644 --- a/test/asynchronous/conftest.py +++ b/test/asynchronous/conftest.py @@ -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() diff --git a/test/conftest.py b/test/conftest.py index ca817a5a62..a3d954c7c3 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -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()