diff --git a/.evergreen/config.yml b/.evergreen/config.yml
index 6a6af56c0..408a210d9 100644
--- a/.evergreen/config.yml
+++ b/.evergreen/config.yml
@@ -349,16 +349,6 @@ functions:
${PREPARE_SHELL}
PYTHON_BINARY=${PYTHON_BINARY} PROJECT_DIRECTORY=${PROJECT_DIRECTORY} sh ${PROJECT_DIRECTORY}/.evergreen/run-mockupdb-tests.sh
- "run cdecimal tests":
- - command: shell.exec
- type: test
- params:
- working_dir: "src"
- script: |
- set -o xtrace
- ${PREPARE_SHELL}
- PYTHON_BINARY=${PYTHON_BINARY} sh ${PROJECT_DIRECTORY}/.evergreen/run-cdecimal-tests.sh
-
"run doctests":
- command: shell.exec
type: test
@@ -1179,15 +1169,6 @@ tasks:
TOPOLOGY: "replica_set"
- func: "run mod_wsgi tests"
- - name: "cdecimal"
- tags: ["cdecimal"]
- commands:
- - func: "bootstrap mongo-orchestration"
- vars:
- VERSION: "latest"
- TOPOLOGY: "server"
- - func: "run cdecimal tests"
-
- name: "no-server"
tags: ["no-server"]
commands:
diff --git a/.travis.yml b/.travis.yml
index 5dd72f6da..585f3c28d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,13 +1,11 @@
language: python
python:
- - 2.7
- 3.4
- 3.5
- 3.6
- 3.7
- 3.8
- - pypy
- pypy3.5
services:
diff --git a/MANIFEST.in b/MANIFEST.in
index 5b8d2a565..d017d16ab 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,7 +1,6 @@
include README.rst
include LICENSE
include THIRD-PARTY-NOTICES
-include ez_setup.py
recursive-include doc *.rst
recursive-include doc *.py
recursive-include doc *.conf
diff --git a/README.rst b/README.rst
index 4cb6658df..0341ae44b 100644
--- a/README.rst
+++ b/README.rst
@@ -89,7 +89,7 @@ is incompatible with PyMongo.
Dependencies
============
-PyMongo supports CPython 2.7, 3.4+, PyPy, and PyPy3.5+.
+PyMongo supports CPython 3.4+ and PyPy3.5+.
Optional dependencies:
@@ -119,9 +119,6 @@ PyMongo::
$ python -m pip install pymongo[tls]
-.. note:: Users of Python versions older than 2.7.9 will also
- receive the dependencies for OCSP when using the tls extra.
-
OCSP (Online Certificate Status Protocol) requires `PyOpenSSL
`_, `requests
`_ and `service_identity
@@ -149,16 +146,6 @@ command::
$ python -m pip install pymongo[gssapi,aws,ocsp,snappy,srv,tls,zstd,encryption]
-Other optional packages:
-
-- `backports.pbkdf2 `_,
- improves authentication performance with SCRAM-SHA-1 and SCRAM-SHA-256.
- It especially improves performance on Python versions older than 2.7.8.
-- `monotonic `_ adds support for
- a monotonic clock, which improves reliability in environments
- where clock adjustments are frequent. Not needed in Python 3.
-
-
Additional dependencies are:
- (to generate documentation) sphinx_
diff --git a/RELEASE.rst b/RELEASE.rst
index b99c95515..220908084 100644
--- a/RELEASE.rst
+++ b/RELEASE.rst
@@ -33,10 +33,10 @@ Doing a Release
1. PyMongo is tested on Evergreen. Ensure the latest commit are passing CI
as expected: https://evergreen.mongodb.com/waterfall/mongo-python-driver.
- To test locally, ``python setup.py test`` will build the C extensions and
- test. ``python tools/clean.py`` will remove the extensions,
- and then ``python setup.py --no_ext test`` will run the tests without
- them. You can also run the doctests: ``python setup.py doc -t``.
+ To test locally, ``python3 setup.py test`` will build the C extensions and
+ test. ``python3 tools/clean.py`` will remove the extensions,
+ and then ``python3 setup.py --no_ext test`` will run the tests without
+ them. You can also run the doctests: ``python3 setup.py doc -t``.
2. Check Jira to ensure all the tickets in this version have been completed.
@@ -63,17 +63,11 @@ Doing a Release
the next steps let's assume we unpacked these files into the following paths::
$ ls path/to/manylinux
- pymongo--cp27-cp27m-manylinux1_i686.whl
- ...
pymongo--cp38-cp38-manylinux2014_x86_64.whl
- $ ls path/to/mac/
- pymongo--cp27-cp27m-macosx_10_14_intel.whl
...
- pymongo--py2.7-macosx-10.14-intel.egg
$ ls path/to/windows/
- pymongo--cp27-cp27m-win32.whl
- ...
pymongo--cp38-cp38-win_amd64.whl
+ ...
10. Build the source distribution::
diff --git a/cdecimal_test.py b/cdecimal_test.py
deleted file mode 100644
index 88262ffd9..000000000
--- a/cdecimal_test.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2017 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.
-
-"""Test PyMongo with cdecimal monkey-patched over stdlib decimal."""
-
-import getopt
-import sys
-
-try:
- import cdecimal
- _HAVE_CDECIMAL = True
-except ImportError:
- _HAVE_CDECIMAL = False
-
-
-def run(args):
- """Run tests with cdecimal monkey-patched over stdlib decimal."""
- # Monkey-patch.
- sys.modules['decimal'] = cdecimal
-
- # Run the tests.
- sys.argv[:] = ['setup.py', 'test'] + list(args)
- import setup
-
-
-def main():
- """Parse options and run tests."""
- usage = """python %s
-
-Test PyMongo with cdecimal monkey-patched over decimal.""" % (sys.argv[0],)
-
- try:
- opts, args = getopt.getopt(
- sys.argv[1:], "h", ["help"])
- except getopt.GetoptError as err:
- print(str(err))
- print(usage)
- sys.exit(2)
-
- for option_name, _ in opts:
- if option_name in ("-h", "--help"):
- print(usage)
- sys.exit()
- else:
- assert False, "unhandled option"
-
- if not _HAVE_CDECIMAL:
- print("The cdecimal package is not installed.")
- sys.exit(1)
-
- run(args) # Command line args to setup.py, like what test to run.
-
-
-if __name__ == '__main__':
- main()
diff --git a/doc/atlas.rst b/doc/atlas.rst
index 59605b58e..0a64b294c 100644
--- a/doc/atlas.rst
+++ b/doc/atlas.rst
@@ -7,32 +7,7 @@ Atlas to :class:`~pymongo.mongo_client.MongoClient`::
client = pymongo.MongoClient()
-Connections to Atlas require TLS/SSL. For connections using TLS/SSL, PyMongo
-may require third party dependencies as determined by your version of Python.
-With PyMongo 3.3+, you can install PyMongo 3.3+ and any TLS/SSL-related
-dependencies using the following pip command::
-
- $ python -m pip install pymongo[tls]
-
-Starting with PyMongo 3.11 this installs `PyOpenSSL
-`_, `requests`_
-and `service_identity
-`_
-for users of Python versions older than 2.7.9. PyOpenSSL supports SNI for these
-old Python versions, allowing applictions to connect to Altas free and shared
-tier instances.
-
-Earlier versions of PyMongo require you to manually install the dependencies.
-For a list of TLS/SSL-related dependencies, see :doc:`examples/tls`.
-
-.. note:: Connecting to Atlas "Free Tier" or "Shared Cluster" instances
- requires Server Name Indication (SNI) support. SNI support requires CPython
- 2.7.9 / PyPy 2.5.1 or newer or PyMongo 3.11+ with PyOpenSSL.
- To check if your version of Python supports SNI run the following command::
-
- $ python -c "import ssl; print(getattr(ssl, 'HAS_SNI', False))"
-
- You should see "True".
+Connections to Atlas require TLS/SSL.
.. warning:: Industry best practices recommend, and some regulations require,
the use of TLS 1.1 or newer. Though no application changes are required for
diff --git a/doc/compatibility-policy.rst b/doc/compatibility-policy.rst
index 08c5d5793..ed22c9735 100644
--- a/doc/compatibility-policy.rst
+++ b/doc/compatibility-policy.rst
@@ -18,9 +18,9 @@ effort to release at least one minor version that *deprecates* it. We add
`DeprecationWarning`_. You can ensure your code is future-proof by running
your code with the latest PyMongo release and looking for DeprecationWarnings.
-Starting with Python 2.7, the interpreter silences DeprecationWarnings by
-default. For example, the following code uses the deprecated ``insert``
-method but does not raise any warning:
+The interpreter silences DeprecationWarnings by default. For example, the
+following code uses the deprecated ``insert`` method but does not raise any
+warning:
.. code-block:: python
@@ -32,13 +32,13 @@ method but does not raise any warning:
To print deprecation warnings to stderr, run python with "-Wd"::
- $ python -Wd insert.py
+ $ python3 -Wd insert.py
insert.py:4: DeprecationWarning: insert is deprecated. Use insert_one or insert_many instead.
client.test.test.insert({})
You can turn warnings into exceptions with "python -We"::
- $ python -We insert.py
+ $ python3 -We insert.py
Traceback (most recent call last):
File "insert.py", line 4, in
client.test.test.insert({})
@@ -55,8 +55,8 @@ deprecated PyMongo features.
.. _semantic versioning: http://semver.org/
.. _DeprecationWarning:
- https://docs.python.org/2/library/exceptions.html#exceptions.DeprecationWarning
+ https://docs.python.org/3/library/exceptions.html#DeprecationWarning
-.. _the warnings module: https://docs.python.org/2/library/warnings.html
+.. _the warnings module: https://docs.python.org/3/library/warnings.html
-.. _the -W command line option: https://docs.python.org/2/using/cmdline.html#cmdoption-W
+.. _the -W command line option: https://docs.python.org/3/using/cmdline.html#cmdoption-w
diff --git a/doc/installation.rst b/doc/installation.rst
index f9f01a671..ea437aa4b 100644
--- a/doc/installation.rst
+++ b/doc/installation.rst
@@ -15,37 +15,20 @@ Installing with pip
We recommend using `pip `_
to install pymongo on all platforms::
- $ python -m pip install pymongo
+ $ python3 -m pip install pymongo
To get a specific version of pymongo::
- $ python -m pip install pymongo==3.5.1
+ $ python3 -m pip install pymongo==3.5.1
To upgrade using pip::
- $ python -m pip install --upgrade pymongo
-
-.. note::
- pip does not support installing python packages in .egg format. If you would
- like to install PyMongo from a .egg provided on pypi use easy_install
- instead.
-
-Installing with easy_install
-----------------------------
-
-To use ``easy_install`` from
-`setuptools `_ do::
-
- $ python -m easy_install pymongo
-
-To upgrade do::
-
- $ python -m easy_install -U pymongo
+ $ python3 -m pip install --upgrade pymongo
Dependencies
------------
-PyMongo supports CPython 2.7, 3.4+, PyPy, and PyPy3.5+.
+PyMongo supports CPython 3.4+ and PyPy3.5+.
Optional dependencies:
@@ -54,66 +37,44 @@ GSSAPI authentication requires `pykerberos
`_ on Windows. The correct
dependency can be installed automatically along with PyMongo::
- $ python -m pip install pymongo[gssapi]
+ $ python3 -m pip install pymongo[gssapi]
:ref:`MONGODB-AWS` authentication requires `pymongo-auth-aws
`_::
- $ python -m pip install pymongo[aws]
+ $ python3 -m pip install pymongo[aws]
Support for mongodb+srv:// URIs requires `dnspython
`_::
- $ python -m pip install pymongo[srv]
-
-TLS / SSL support may require `ipaddress
-`_ and `certifi
-`_ or `wincertstore
-`_ depending on the Python
-version in use. The necessary dependencies can be installed along with
-PyMongo::
-
- $ python -m pip install pymongo[tls]
-
-.. note:: Users of Python versions older than 2.7.9 will also
- receive the dependencies for OCSP when using the tls extra.
+ $ python3 -m pip install pymongo[srv]
:ref:`OCSP` requires `PyOpenSSL
`_, `requests
`_ and `service_identity
`_::
- $ python -m pip install pymongo[ocsp]
+ $ python3 -m pip install pymongo[ocsp]
Wire protocol compression with snappy requires `python-snappy
`_::
- $ python -m pip install pymongo[snappy]
+ $ python3 -m pip install pymongo[snappy]
Wire protocol compression with zstandard requires `zstandard
`_::
- $ python -m pip install pymongo[zstd]
+ $ python3 -m pip install pymongo[zstd]
:ref:`Client-Side Field Level Encryption` requires `pymongocrypt
`_::
- $ python -m pip install pymongo[encryption]
+ $ python3 -m pip install pymongo[encryption]
You can install all dependencies automatically with the following
command::
- $ python -m pip install pymongo[gssapi,aws,ocsp,snappy,srv,tls,zstd,encryption]
-
-Other optional packages:
-
-- `backports.pbkdf2 `_,
- improves authentication performance with SCRAM-SHA-1 and SCRAM-SHA-256.
- It especially improves performance on Python versions older than 2.7.8.
-- `monotonic `_ adds support for
- a monotonic clock, which improves reliability in environments
- where clock adjustments are frequent. Not needed in Python 3.
-
+ $ python3 -m pip install pymongo[gssapi,aws,ocsp,snappy,srv,zstd,encryption]
Installing from source
----------------------
@@ -124,7 +85,7 @@ latest source from GitHub and install the driver from the resulting tree::
$ git clone git://github.com/mongodb/mongo-python-driver.git pymongo
$ cd pymongo/
- $ python setup.py install
+ $ python3 setup.py install
Installing from source on Unix
..............................
@@ -172,9 +133,8 @@ 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 2.7 >= 2.7.4 or Python 3.4+ downloaded from
-python.org. In all cases Xcode must be installed with 'UNIX Development
-Support'.
+versions of Python 3.4+ 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
Xcode throws an error when it encounters compiler flags it doesn't recognize.
@@ -209,8 +169,7 @@ requirements apply to both CPython and ActiveState's ActivePython:
For Python 3.5 and newer install Visual Studio 2015. For Python 3.4
install Visual Studio 2010. You must use the full version of Visual Studio
2010 as Visual C++ Express does not provide 64-bit compilers. Make sure that
-you check the "x64 Compilers and Tools" option under Visual C++. For Python 2.7
-install the `Microsoft Visual C++ Compiler for Python 2.7`_.
+you check the "x64 Compilers and Tools" option under Visual C++.
32-bit Windows
~~~~~~~~~~~~~~
@@ -219,10 +178,6 @@ For Python 3.5 and newer install Visual Studio 2015.
For Python 3.4 install Visual C++ 2010 Express.
-For Python 2.7 install the `Microsoft Visual C++ Compiler for Python 2.7`_
-
-.. _`Microsoft Visual C++ Compiler for Python 2.7`: https://www.microsoft.com/en-us/download/details.aspx?id=44266
-
.. _install-no-c:
Installing Without C Extensions
@@ -237,34 +192,7 @@ If you wish to install PyMongo without the C extensions, even if the
extensions build properly, it can be done using a command line option to
*setup.py*::
- $ python setup.py --no_ext install
-
-Building PyMongo egg Packages
------------------------------
-
-Some organizations do not allow compilers and other build tools on production
-systems. To install PyMongo on these systems with C extensions you may need to
-build custom egg packages. Make sure that you have installed the dependencies
-listed above for your operating system then run the following command in the
-PyMongo source directory::
-
- $ python setup.py bdist_egg
-
-The egg package can be found in the dist/ subdirectory. The file name will
-resemble “pymongo-3.6-py2.7-linux-x86_64.egg” but may have a different name
-depending on your platform and the version of python you use to compile.
-
-.. warning::
-
- These “binary distributions,” will only work on systems that resemble the
- environment on which you built the package. In other words, ensure that
- operating systems and versions of Python and architecture (i.e. “32” or “64”
- bit) match.
-
-Copy this file to the target system and issue the following command to install the
-package::
-
- $ sudo python -m easy_install pymongo-3.6-py2.7-linux-x86_64.egg
+ $ python3 setup.py --no_ext install
Installing a beta or release candidate
--------------------------------------
@@ -275,4 +203,4 @@ but can be found on the
`GitHub tags page `_.
They can be installed by passing the full URL for the tag to pip::
- $ python -m pip install https://github.com/mongodb/mongo-python-driver/archive/3.11.0rc0.tar.gz
+ $ python3 -m pip install https://github.com/mongodb/mongo-python-driver/archive/3.11.0rc0.tar.gz
diff --git a/ez_setup.py b/ez_setup.py
deleted file mode 100644
index 800c31ef6..000000000
--- a/ez_setup.py
+++ /dev/null
@@ -1,414 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Setuptools bootstrapping installer.
-
-Maintained at https://github.com/pypa/setuptools/tree/bootstrap.
-
-Run this script to install or upgrade setuptools.
-
-This method is DEPRECATED. Check https://github.com/pypa/setuptools/issues/581 for more details.
-"""
-
-import os
-import shutil
-import sys
-import tempfile
-import zipfile
-import optparse
-import subprocess
-import platform
-import textwrap
-import contextlib
-
-from distutils import log
-
-try:
- from urllib.request import urlopen
-except ImportError:
- from urllib2 import urlopen
-
-try:
- from site import USER_SITE
-except ImportError:
- USER_SITE = None
-
-# 33.1.1 is the last version that supports setuptools self upgrade/installation.
-DEFAULT_VERSION = "33.1.1"
-DEFAULT_URL = "https://pypi.io/packages/source/s/setuptools/"
-DEFAULT_SAVE_DIR = os.curdir
-DEFAULT_DEPRECATION_MESSAGE = "ez_setup.py is deprecated and when using it setuptools will be pinned to {0} since it's the last version that supports setuptools self upgrade/installation, check https://github.com/pypa/setuptools/issues/581 for more info; use pip to install setuptools"
-
-MEANINGFUL_INVALID_ZIP_ERR_MSG = 'Maybe {0} is corrupted, delete it and try again.'
-
-log.warn(DEFAULT_DEPRECATION_MESSAGE.format(DEFAULT_VERSION))
-
-
-def _python_cmd(*args):
- """
- Execute a command.
-
- Return True if the command succeeded.
- """
- args = (sys.executable,) + args
- return subprocess.call(args) == 0
-
-
-def _install(archive_filename, install_args=()):
- """Install Setuptools."""
- with archive_context(archive_filename):
- # installing
- log.warn('Installing Setuptools')
- if not _python_cmd('setup.py', 'install', *install_args):
- log.warn('Something went wrong during the installation.')
- log.warn('See the error message above.')
- # exitcode will be 2
- return 2
-
-
-def _build_egg(egg, archive_filename, to_dir):
- """Build Setuptools egg."""
- with archive_context(archive_filename):
- # building an egg
- log.warn('Building a Setuptools egg in %s', to_dir)
- _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
- # returning the result
- log.warn(egg)
- if not os.path.exists(egg):
- raise IOError('Could not build the egg.')
-
-
-class ContextualZipFile(zipfile.ZipFile):
-
- """Supplement ZipFile class to support context manager for Python 2.6."""
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- self.close()
-
- def __new__(cls, *args, **kwargs):
- """Construct a ZipFile or ContextualZipFile as appropriate."""
- if hasattr(zipfile.ZipFile, '__exit__'):
- return zipfile.ZipFile(*args, **kwargs)
- return super(ContextualZipFile, cls).__new__(cls)
-
-
-@contextlib.contextmanager
-def archive_context(filename):
- """
- Unzip filename to a temporary directory, set to the cwd.
-
- The unzipped target is cleaned up after.
- """
- tmpdir = tempfile.mkdtemp()
- log.warn('Extracting in %s', tmpdir)
- old_wd = os.getcwd()
- try:
- os.chdir(tmpdir)
- try:
- with ContextualZipFile(filename) as archive:
- archive.extractall()
- except zipfile.BadZipfile as err:
- if not err.args:
- err.args = ('', )
- err.args = err.args + (
- MEANINGFUL_INVALID_ZIP_ERR_MSG.format(filename),
- )
- raise
-
- # going in the directory
- subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
- os.chdir(subdir)
- log.warn('Now working in %s', subdir)
- yield
-
- finally:
- os.chdir(old_wd)
- shutil.rmtree(tmpdir)
-
-
-def _do_download(version, download_base, to_dir, download_delay):
- """Download Setuptools."""
- py_desig = 'py{sys.version_info[0]}.{sys.version_info[1]}'.format(sys=sys)
- tp = 'setuptools-{version}-{py_desig}.egg'
- egg = os.path.join(to_dir, tp.format(**locals()))
- if not os.path.exists(egg):
- archive = download_setuptools(version, download_base,
- to_dir, download_delay)
- _build_egg(egg, archive, to_dir)
- sys.path.insert(0, egg)
-
- # Remove previously-imported pkg_resources if present (see
- # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details).
- if 'pkg_resources' in sys.modules:
- _unload_pkg_resources()
-
- import setuptools
- setuptools.bootstrap_install_from = egg
-
-
-def use_setuptools(
- version=DEFAULT_VERSION, download_base=DEFAULT_URL,
- to_dir=DEFAULT_SAVE_DIR, download_delay=15):
- """
- Ensure that a setuptools version is installed.
-
- Return None. Raise SystemExit if the requested version
- or later cannot be installed.
- """
- to_dir = os.path.abspath(to_dir)
-
- # prior to importing, capture the module state for
- # representative modules.
- rep_modules = 'pkg_resources', 'setuptools'
- imported = set(sys.modules).intersection(rep_modules)
-
- try:
- import pkg_resources
- pkg_resources.require("setuptools>=" + version)
- # a suitable version is already installed
- return
- except ImportError:
- # pkg_resources not available; setuptools is not installed; download
- pass
- except pkg_resources.DistributionNotFound:
- # no version of setuptools was found; allow download
- pass
- except pkg_resources.VersionConflict as VC_err:
- if imported:
- _conflict_bail(VC_err, version)
-
- # otherwise, unload pkg_resources to allow the downloaded version to
- # take precedence.
- del pkg_resources
- _unload_pkg_resources()
-
- return _do_download(version, download_base, to_dir, download_delay)
-
-
-def _conflict_bail(VC_err, version):
- """
- Setuptools was imported prior to invocation, so it is
- unsafe to unload it. Bail out.
- """
- conflict_tmpl = textwrap.dedent("""
- The required version of setuptools (>={version}) is not available,
- and can't be installed while this script is running. Please
- install a more recent version first, using
- 'easy_install -U setuptools'.
-
- (Currently using {VC_err.args[0]!r})
- """)
- msg = conflict_tmpl.format(**locals())
- sys.stderr.write(msg)
- sys.exit(2)
-
-
-def _unload_pkg_resources():
- sys.meta_path = [
- importer
- for importer in sys.meta_path
- if importer.__class__.__module__ != 'pkg_resources.extern'
- ]
- del_modules = [
- name for name in sys.modules
- if name.startswith('pkg_resources')
- ]
- for mod_name in del_modules:
- del sys.modules[mod_name]
-
-
-def _clean_check(cmd, target):
- """
- Run the command to download target.
-
- If the command fails, clean up before re-raising the error.
- """
- try:
- subprocess.check_call(cmd)
- except subprocess.CalledProcessError:
- if os.access(target, os.F_OK):
- os.unlink(target)
- raise
-
-
-def download_file_powershell(url, target):
- """
- Download the file at url to target using Powershell.
-
- Powershell will validate trust.
- Raise an exception if the command cannot complete.
- """
- target = os.path.abspath(target)
- ps_cmd = (
- "[System.Net.WebRequest]::DefaultWebProxy.Credentials = "
- "[System.Net.CredentialCache]::DefaultCredentials; "
- '(new-object System.Net.WebClient).DownloadFile("%(url)s", "%(target)s")'
- % locals()
- )
- cmd = [
- 'powershell',
- '-Command',
- ps_cmd,
- ]
- _clean_check(cmd, target)
-
-
-def has_powershell():
- """Determine if Powershell is available."""
- if platform.system() != 'Windows':
- return False
- cmd = ['powershell', '-Command', 'echo test']
- with open(os.path.devnull, 'wb') as devnull:
- try:
- subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
- except Exception:
- return False
- return True
-download_file_powershell.viable = has_powershell
-
-
-def download_file_curl(url, target):
- cmd = ['curl', url, '--location', '--silent', '--output', target]
- _clean_check(cmd, target)
-
-
-def has_curl():
- cmd = ['curl', '--version']
- with open(os.path.devnull, 'wb') as devnull:
- try:
- subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
- except Exception:
- return False
- return True
-download_file_curl.viable = has_curl
-
-
-def download_file_wget(url, target):
- cmd = ['wget', url, '--quiet', '--output-document', target]
- _clean_check(cmd, target)
-
-
-def has_wget():
- cmd = ['wget', '--version']
- with open(os.path.devnull, 'wb') as devnull:
- try:
- subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
- except Exception:
- return False
- return True
-download_file_wget.viable = has_wget
-
-
-def download_file_insecure(url, target):
- """Use Python to download the file, without connection authentication."""
- src = urlopen(url)
- try:
- # Read all the data in one block.
- data = src.read()
- finally:
- src.close()
-
- # Write all the data in one block to avoid creating a partial file.
- with open(target, "wb") as dst:
- dst.write(data)
-download_file_insecure.viable = lambda: True
-
-
-def get_best_downloader():
- downloaders = (
- download_file_powershell,
- download_file_curl,
- download_file_wget,
- download_file_insecure,
- )
- viable_downloaders = (dl for dl in downloaders if dl.viable())
- return next(viable_downloaders, None)
-
-
-def download_setuptools(
- version=DEFAULT_VERSION, download_base=DEFAULT_URL,
- to_dir=DEFAULT_SAVE_DIR, delay=15,
- downloader_factory=get_best_downloader):
- """
- Download setuptools from a specified location and return its filename.
-
- `version` should be a valid setuptools version number that is available
- as an sdist for download under the `download_base` URL (which should end
- with a '/'). `to_dir` is the directory where the egg will be downloaded.
- `delay` is the number of seconds to pause before an actual download
- attempt.
-
- ``downloader_factory`` should be a function taking no arguments and
- returning a function for downloading a URL to a target.
- """
- # making sure we use the absolute path
- to_dir = os.path.abspath(to_dir)
- zip_name = "setuptools-%s.zip" % version
- url = download_base + zip_name
- saveto = os.path.join(to_dir, zip_name)
- if not os.path.exists(saveto): # Avoid repeated downloads
- log.warn("Downloading %s", url)
- downloader = downloader_factory()
- downloader(url, saveto)
- return os.path.realpath(saveto)
-
-
-def _build_install_args(options):
- """
- Build the arguments to 'python setup.py install' on the setuptools package.
-
- Returns list of command line arguments.
- """
- return ['--user'] if options.user_install else []
-
-
-def _parse_args():
- """Parse the command line for options."""
- parser = optparse.OptionParser()
- parser.add_option(
- '--user', dest='user_install', action='store_true', default=False,
- help='install in user site package')
- parser.add_option(
- '--download-base', dest='download_base', metavar="URL",
- default=DEFAULT_URL,
- help='alternative URL from where to download the setuptools package')
- parser.add_option(
- '--insecure', dest='downloader_factory', action='store_const',
- const=lambda: download_file_insecure, default=get_best_downloader,
- help='Use internal, non-validating downloader'
- )
- parser.add_option(
- '--version', help="Specify which version to download",
- default=DEFAULT_VERSION,
- )
- parser.add_option(
- '--to-dir',
- help="Directory to save (and re-use) package",
- default=DEFAULT_SAVE_DIR,
- )
- options, args = parser.parse_args()
- # positional arguments are ignored
- return options
-
-
-def _download_args(options):
- """Return args for download_setuptools function from cmdline args."""
- return dict(
- version=options.version,
- download_base=options.download_base,
- downloader_factory=options.downloader_factory,
- to_dir=options.to_dir,
- )
-
-
-def main():
- """Install or upgrade setuptools and EasyInstall."""
- options = _parse_args()
- archive = download_setuptools(**_download_args(options))
- return _install(archive, _build_install_args(options))
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/setup.py b/setup.py
index b92104045..dc54b0704 100755
--- a/setup.py
+++ b/setup.py
@@ -5,8 +5,8 @@ import sys
import warnings
-if sys.version_info[:2] < (2, 7):
- raise RuntimeError("Python version >= 2.7 required.")
+if sys.version_info[:2] < (3, 4):
+ raise RuntimeError("Python version >= 3.4 required.")
# Hack to silence atexit traceback in some Python versions
@@ -15,14 +15,7 @@ try:
except ImportError:
pass
-# Don't force people to install setuptools unless
-# we have to.
-try:
- from setuptools import setup, __version__ as _setuptools_version
-except ImportError:
- from ez_setup import use_setuptools
- use_setuptools()
- from setuptools import setup, __version__ as _setuptools_version
+from setuptools import setup, __version__ as _setuptools_version
from distutils.cmd import Command
from distutils.command.build_ext import build_ext
@@ -152,45 +145,45 @@ class doc(Command):
raise RuntimeError(
"You must install Sphinx to build or test the documentation.")
- if sys.version_info[0] >= 3:
- import doctest
- from doctest import OutputChecker as _OutputChecker
+ # TODO: Convert all the docs to Python 3 and delete all this.
+ import doctest
+ from doctest import OutputChecker as _OutputChecker
- # Match u or U (possibly followed by r or R), removing it.
- # r/R can follow u/U but not precede it. Don't match the
- # single character string 'u' or 'U'.
- _u_literal_re = re.compile(
- r"(\W|^)(?=1.16.0,<2.0.0"],
}
-# https://jira.mongodb.org/browse/PYTHON-2117
-# Environment marker support didn't settle down until version 20.10
-# https://setuptools.readthedocs.io/en/latest/history.html#v20-10-0
-_use_env_markers = tuple(map(int, _setuptools_version.split('.')[:2])) > (20, 9)
-
-# TLS and DNS extras
-# We install PyOpenSSL and service_identity for Python < 2.7.9 to
-# get support for SNI, which is required to connection to Altas
-# free and shared tier.
-if sys.version_info[0] == 2:
- if _use_env_markers:
- # For building wheels on Python versions >= 2.7.9
- for req in pyopenssl_reqs:
- extras_require['tls'].append(
- "%s ; python_full_version < '2.7.9'" % (req,))
- if sys.platform == 'win32':
- extras_require['tls'].append(
- "wincertstore>=0.2 ; python_full_version < '2.7.9'")
- else:
- extras_require['tls'].append(
- "certifi ; python_full_version < '2.7.9'")
- elif sys.version_info < (2, 7, 9):
- # For installing from source or egg files on Python versions
- # older than 2.7.9, or systems that have setuptools versions
- # older than 20.10.
- extras_require['tls'].extend(pyopenssl_reqs)
- if sys.platform == 'win32':
- extras_require['tls'].append("wincertstore>=0.2")
- else:
- extras_require['tls'].append("certifi")
- extras_require.update({'srv': ["dnspython>=1.16.0,<1.17.0"]})
- extras_require.update({'tls': ["ipaddress"]})
-else:
- extras_require.update({'srv': ["dnspython>=1.16.0,<2.0.0"]})
-
# GSSAPI extras
if sys.platform == 'win32':
extras_require['gssapi'] = ["winkerberos>=0.5.0"]
@@ -404,7 +362,7 @@ setup(
keywords=["mongo", "mongodb", "pymongo", "gridfs", "bson"],
install_requires=[],
license="Apache License, Version 2.0",
- python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*",
+ python_requires=">=3.4",
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
@@ -412,8 +370,6 @@ setup(
"Operating System :: MacOS :: MacOS X",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",