diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 053dc0cde..6ab459e42 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -1846,6 +1846,10 @@ axes: display_name: "Python 3.9" variables: PYTHON_BINARY: "/opt/python/3.9/bin/python3" + - id: "3.10" + display_name: "Python 3.10" + variables: + PYTHON_BINARY: "/opt/python/3.10/bin/python3" - id: "pypy3.6" display_name: "PyPy 3.6" variables: @@ -1878,6 +1882,10 @@ axes: display_name: "Python 3.9" variables: PYTHON_BINARY: "C:/python/Python39/python.exe" + - id: "3.10" + display_name: "Python 3.10" + variables: + PYTHON_BINARY: "C:/python/Python310/python.exe" - id: python-version-windows-32 display_name: "Python" @@ -1898,6 +1906,10 @@ axes: display_name: "32-bit Python 3.9" variables: PYTHON_BINARY: "C:/python/32/Python39/python.exe" + - id: "3.10" + display_name: "32-bit Python 3.10" + variables: + PYTHON_BINARY: "C:/python/32/Python310/python.exe" # Choice of mod_wsgi version - id: mod-wsgi-version @@ -2144,6 +2156,17 @@ buildvariants: display_name: "${python-version} ${platform} ${auth-ssl} ${coverage}" tasks: *all-server-versions +- matrix_name: "tests-python-version-ubuntu20-ssl" + matrix_spec: + platform: ubuntu-20.04 + python-version: ["3.10"] + auth-ssl: "*" + display_name: "${python-version} ${platform} ${auth-ssl} ${coverage}" + tasks: + - ".latest" + - ".5.0" + - ".4.4" + - matrix_name: "tests-pyopenssl" matrix_spec: platform: awslinux diff --git a/setup.py b/setup.py index f09e2c6f0..88ec93a00 100755 --- a/setup.py +++ b/setup.py @@ -17,11 +17,15 @@ except ImportError: from setuptools import setup, __version__ as _setuptools_version -from distutils.cmd import Command -from distutils.command.build_ext import build_ext -from distutils.errors import CCompilerError, DistutilsOptionError -from distutils.errors import DistutilsPlatformError, DistutilsExecError -from distutils.core import Extension + +if sys.version_info[:2] < (3, 10): + from distutils.cmd import Command + from distutils.command.build_ext import build_ext + from distutils.core import Extension +else: + from setuptools import Command + from setuptools.command.build_ext import build_ext + from setuptools.extension import Extension _HAVE_SPHINX = True try: @@ -82,7 +86,7 @@ class test(Command): if self.test_suite is None and self.test_module is None: self.test_module = 'test' elif self.test_module is not None and self.test_suite is not None: - raise DistutilsOptionError( + raise Exception( "You may specify a module or suite, but not both" ) @@ -176,15 +180,6 @@ class doc(Command): " %s/\n" % (mode, path)) -if sys.platform == 'win32': - # distutils.msvc9compiler can raise an IOError when failing to - # find the compiler - build_errors = (CCompilerError, DistutilsExecError, - DistutilsPlatformError, IOError) -else: - build_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError) - - class custom_build_ext(build_ext): """Allow C extension building to fail. @@ -237,7 +232,7 @@ https://pymongo.readthedocs.io/en/stable/installation.html#osx def run(self): try: build_ext.run(self) - except DistutilsPlatformError: + except Exception: e = sys.exc_info()[1] sys.stdout.write('%s\n' % str(e)) warnings.warn(self.warning_message % ("Extension modules", @@ -249,7 +244,7 @@ https://pymongo.readthedocs.io/en/stable/installation.html#osx name = ext.name try: build_ext.build_extension(self, ext) - except build_errors: + except Exception: e = sys.exc_info()[1] sys.stdout.write('%s\n' % str(e)) warnings.warn(self.warning_message % ("The %s extension " diff --git a/test/utils.py b/test/utils.py index 02a0a5883..ae75d7647 100644 --- a/test/utils.py +++ b/test/utils.py @@ -15,7 +15,6 @@ """Utilities for testing pymongo """ -import collections import contextlib import copy import functools @@ -27,7 +26,7 @@ import threading import time import warnings -from collections import defaultdict +from collections import abc, defaultdict from functools import partial from bson import json_util @@ -300,11 +299,11 @@ class ScenarioDict(dict): """Dict that returns {} for any unknown key, recursively.""" def __init__(self, data): def convert(v): - if isinstance(v, collections.Mapping): + if isinstance(v, abc.Mapping): return ScenarioDict(v) if isinstance(v, (str, bytes)): return v - if isinstance(v, collections.Sequence): + if isinstance(v, abc.Sequence): return [convert(item) for item in v] return v