Repository: pypa/setuptools
Pull request #1909 (2019-11-17 21:18:27)

Revert "drop easy_install script and associated documentation"
This reverts commit 6e1838a9fb5feb000ba9b6a3c37c8b39d7e872b3.


Patch:
diff --git a/changelog.d/1829.change.rst b/changelog.d/1829.change.rst
deleted file mode 100644
index 36be832ac..000000000
--- a/changelog.d/1829.change.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Update handling of wheels compatibility tags:
-* add support for manylinux2010
-* fix use of removed 'm' ABI flag in Python 3.8 on Windows
diff --git a/changelog.d/1830.breaking.rst b/changelog.d/1830.breaking.rst
new file mode 100644
index 000000000..9f2214ab7
--- /dev/null
+++ b/changelog.d/1830.breaking.rst
@@ -0,0 +1,7 @@
+Mark the easy_install script and setuptools command as deprecated, and use `pip <https://pip.pypa.io/en/stable/>`_ when available to fetch/build wheels for missing ``setup_requires``/``tests_require`` requirements, with the following differences in behavior:
+ * support for ``python_requires``
+ * better support for wheels (proper handling of priority with respect to PEP 425 tags)
+ * PEP 517/518 support
+ * eggs are not supported
+ * no support for the ``allow_hosts`` easy_install option (``index_url``/``find_links`` are still honored)
+ * pip environment variables are honored (and take precedence over easy_install options)
diff --git a/changelog.d/1909.breaking.rst b/changelog.d/1909.breaking.rst
new file mode 100644
index 000000000..9f2214ab7
--- /dev/null
+++ b/changelog.d/1909.breaking.rst
@@ -0,0 +1,7 @@
+Mark the easy_install script and setuptools command as deprecated, and use `pip <https://pip.pypa.io/en/stable/>`_ when available to fetch/build wheels for missing ``setup_requires``/``tests_require`` requirements, with the following differences in behavior:
+ * support for ``python_requires``
+ * better support for wheels (proper handling of priority with respect to PEP 425 tags)
+ * PEP 517/518 support
+ * eggs are not supported
+ * no support for the ``allow_hosts`` easy_install option (``index_url``/``find_links`` are still honored)
+ * pip environment variables are honored (and take precedence over easy_install options)
diff --git a/docs/easy_install.txt b/docs/easy_install.txt
new file mode 100644
index 000000000..544b9efd5
--- /dev/null
+++ b/docs/easy_install.txt
@@ -0,0 +1,1085 @@
+============
+Easy Install
+============
+
+.. warning::
+    Easy Install is deprecated. Do not use it. Instead use pip. If
+    you think you need Easy Install, please reach out to the PyPA
+    team (a ticket to pip or setuptools is fine), describing your
+    use-case.
+
+Easy Install is a python module (``easy_install``) bundled with ``setuptools``
+that lets you automatically download, build, install, and manage Python
+packages.
+
+Please share your experiences with us! If you encounter difficulty installing
+a package, please contact us via the `distutils mailing list
+<http://mail.python.org/pipermail/distutils-sig/>`_.  (Note: please DO NOT send
+private email directly to the author of setuptools; it will be discarded.  The
+mailing list is a searchable archive of previously-asked and answered
+questions; you should begin your research there before reporting something as a
+bug -- and then do so via list discussion first.)
+
+(Also, if you'd like to learn about how you can use ``setuptools`` to make your
+own packages work better with EasyInstall, or provide EasyInstall-like features
+without requiring your users to use EasyInstall directly, you'll probably want
+to check out the full documentation as well.)
+
+.. contents:: **Table of Contents**
+
+
+Using "Easy Install"
+====================
+
+
+.. _installation instructions:
+
+Installing "Easy Install"
+-------------------------
+
+Please see the `setuptools PyPI page <https://pypi.org/project/setuptools/>`_
+for download links and basic installation instructions for each of the
+supported platforms.
+
+You will need at least Python 3.4 or 2.7.  An ``easy_install`` script will be
+installed in the normal location for Python scripts on your platform.
+
+Note that the instructions on the setuptools PyPI page assume that you are
+are installing to Python's primary ``site-packages`` directory.  If this is
+not the case, you should consult the section below on `Custom Installation
+Locations`_ before installing.  (And, on Windows, you should not use the
+``.exe`` installer when installing to an alternate location.)
+
+Note that ``easy_install`` normally works by downloading files from the
+internet.  If you are behind an NTLM-based firewall that prevents Python
+programs from accessing the net directly, you may wish to first install and use
+the `APS proxy server <http://ntlmaps.sf.net/>`_, which lets you get past such
+firewalls in the same way that your web browser(s) do.
+
+(Alternately, if you do not wish easy_install to actually download anything, you
+can restrict it from doing so with the ``--allow-hosts`` option; see the
+sections on `restricting downloads with --allow-hosts`_ and `command-line
+options`_ for more details.)
+
+
+Troubleshooting
+~~~~~~~~~~~~~~~
+
+If EasyInstall/setuptools appears to install correctly, and you can run the
+``easy_install`` command but it fails with an ``ImportError``, the most likely
+cause is that you installed to a location other than ``site-packages``,
+without taking any of the steps described in the `Custom Installation
+Locations`_ section below.  Please see that section and follow the steps to
+make sure that your custom location will work correctly.  Then re-install.
+
+Similarly, if you can run ``easy_install``, and it appears to be installing
+packages, but then you can't import them, the most likely issue is that you
+installed EasyInstall correctly but are using it to install packages to a
+non-standard location that hasn't been properly prepared.  Again, see the
+section on `Custom Installation Locations`_ for more details.
+
+
+Windows Notes
+~~~~~~~~~~~~~
+
+Installing setuptools will provide an ``easy_install`` command according to
+the techniques described in `Executables and Launchers`_. If the
+``easy_install`` command is not available after installation, that section
+provides details on how to configure Windows to make the commands available.
+
+
+Downloading and Installing a Package
+------------------------------------
+
+For basic use of ``easy_install``, you need only supply the filename or URL of
+a source distribution or .egg file (`Python Egg`__).
+
+__ http://peak.telecommunity.com/DevCenter/PythonEggs
+
+**Example 1**. Install a package by name, searching PyPI for the latest
+version, and automatically downloading, building, and installing it::
+
+    easy_install SQLObject
+
+**Example 2**. Install or upgrade a package by name and version by finding
+links on a given "download page"::
+
+    easy_install -f http://pythonpaste.org/package_index.html SQLObject
+
+**Example 3**. Download a source distribution from a specified URL,
+automatically building and installing it::
+
+    easy_install http://example.com/path/to/MyPackage-1.2.3.tgz
+
+**Example 4**. Install an already-downloaded .egg file::
+
+    easy_install /my_downloads/OtherPackage-3.2.1-py2.3.egg
+
+**Example 5**.  Upgrade an already-installed package to the latest version
+listed on PyPI::
+
+    easy_install --upgrade PyProtocols
+
+**Example 6**.  Install a source distribution that's already downloaded and
+extracted in the current directory (New in 0.5a9)::
+
+    easy_install .
+
+**Example 7**.  (New in 0.6a1) Find a source distribution or Subversion
+checkout URL for a package, and extract it or check it out to
+``~/projects/sqlobject`` (the name will always be in all-lowercase), where it
+can be examined or edited.  (The package will not be installed, but it can
+easily be installed with ``easy_install ~/projects/sqlobject``.  See `Editing
+and Viewing Source Packages`_ below for more info.)::
+
+    easy_install --editable --build-directory ~/projects SQLObject
+
+**Example 7**. (New in 0.6.11) Install a distribution within your home dir::
+
+    easy_install --user SQLAlchemy
+
+Easy Install accepts URLs, filenames, PyPI package names (i.e., ``distutils``
+"distribution" names), and package+version specifiers.  In each case, it will
+attempt to locate the latest available version that meets your criteria.
+
+When downloading or processing downloaded files, Easy Install recognizes
+distutils source distribution files with extensions of .tgz, .tar, .tar.gz,
+.tar.bz2, or .zip.  And of course it handles already-built .egg
+distributions as well as ``.win32.exe`` installers built using distutils.
+
+By default, packages are installed to the running Python installation's
+``site-packages`` directory, unless you provide the ``-d`` or ``--install-dir``
+option to specify an alternative directory, or specify an alternate location
+using distutils configuration files.  (See `Configuration Files`_, below.)
+
+By default, any scripts included with the package are installed to the running
+Python installation's standard script installation location.  However, if you
+specify an installation directory via the command line or a config file, then
+the default directory for installing scripts will be the same as the package
+installation directory, to ensure that the script will have access to the
+installed package.  You can override this using the ``-s`` or ``--script-dir``
+option.
+
+Installed packages are added to an ``easy-install.pth`` file in the install
+directory, so that Python will always use the most-recently-installed version
+of the package.  If you would like to be able to select which version to use at
+runtime, you should use the ``-m`` or ``--multi-version`` option.
+
+
+Upgrading a Package
+-------------------
+
+You don't need to do anything special to upgrade a package: just install the
+new version, either by requesting a specific version, e.g.::
+
+    easy_install "SomePackage==2.0"
+
+a version greater than the one you have now::
+
+    easy_install "SomePackage>2.0"
+
+using the upgrade flag, to find the latest available version on PyPI::
+
+    easy_install --upgrade SomePackage
+
+or by using a download page, direct download URL, or package filename::
+
+    easy_install -f http://example.com/downloads ExamplePackage
+
+    easy_install http://example.com/downloads/ExamplePackage-2.0-py2.4.egg
+
+    easy_install my_downloads/ExamplePackage-2.0.tgz
+
+If you're using ``-m`` or ``--multi-version`` , using the ``require()``
+function at runtime automatically selects the newest installed version of a
+package that meets your version criteria.  So, installing a newer version is
+the only step needed to upgrade such packages.
+
+If you're installing to a directory on PYTHONPATH, or a configured "site"
+directory (and not using ``-m``), installing a package automatically replaces
+any previous version in the ``easy-install.pth`` file, so that Python will
+import the most-recently installed version by default.  So, again, installing
+the newer version is the only upgrade step needed.
+
+If you haven't suppressed script installation (using ``--exclude-scripts`` or
+``-x``), then the upgraded version's scripts will be installed, and they will
+be automatically patched to ``require()`` the corresponding version of the
+package, so that you can use them even if they are installed in multi-version
+mode.
+
+``easy_install`` never actually deletes packages (unless you're installing a
+package with the same name and version number as an existing package), so if
+you want to get rid of older versions of a package, please see `Uninstalling
+Packages`_, below.
+
+
+Changing the Active Version
+---------------------------
+
+If you've upgraded a package, but need to revert to a previously-installed
+version, you can do so like this::
+
+    easy_install PackageName==1.2.3
+
+Where ``1.2.3`` is replaced by the exact version number you wish to switch to.
+If a package matching the requested name and version is not already installed
+in a directory on ``sys.path``, it will be located via PyPI and installed.
+
+If you'd like to switch to the latest installed version of ``PackageName``, you
+can do so like this::
+
+    easy_install PackageName
+
+This will activate the latest installed version.  (Note: if you have set any
+``find_links`` via distutils configuration files, those download pages will be
+checked for the latest available version of the package, and it will be
+downloaded and installed if it is newer than your current version.)
+
+Note that changing the active version of a package will install the newly
+active version's scripts, unless the ``--exclude-scripts`` or ``-x`` option is
+specified.
+
+
+Uninstalling Packages
+---------------------
+
+If you have replaced a package with another version, then you can just delete
+the package(s) you don't need by deleting the PackageName-versioninfo.egg file
+or directory (found in the installation directory).
+
+If you want to delete the currently installed version of a package (or all
+versions of a package), you should first run::
+
+    easy_install -m PackageName
+
+This will ensure that Python doesn't continue to search for a package you're
+planning to remove. After you've done this, you can safely delete the .egg
+files or directories, along with any scripts you wish to remove.
+
+
+Managing Scripts
+----------------
+
+Whenever you install, upgrade, or change versions of a package, EasyInstall
+automatically installs the scripts for the selected package version, unless
+you tell it not to with ``-x`` or ``--exclude-scripts``.  If any scripts in
+the script directory have the same name, they are overwritten.
+
+Thus, you do not normally need to manually delete scripts for older versions of
+a package, unless the newer version of the package does not include a script
+of the same name.  However, if you are completely uninstalling a package, you
+may wish to manually delete its scripts.
+
+EasyInstall's default behavior means that you can normally only run scripts
+from one version of a package at a time.  If you want to keep multiple versions
+of a script available, however, you can simply use the ``--multi-version`` or
+``-m`` option, and rename the scripts that EasyInstall creates.  This works
+because EasyInstall installs scripts as short code stubs that ``require()`` the
+matching version of the package the script came from, so renaming the script
+has no effect on what it executes.
+
+For example, suppose you want to use two versions of the ``rst2html`` tool
+provided by the `docutils <http://docutils.sf.net/>`_ package.  You might
+first install one version::
+
+    easy_install -m docutils==0.3.9
+
+then rename the ``rst2html.py`` to ``r2h_039``, and install another version::
+
+    easy_install -m docutils==0.3.10
+
+This will create another ``rst2html.py`` script, this one using docutils
+version 0.3.10 instead of 0.3.9.  You now have two scripts, each using a
+different version of the package.  (Notice that we used ``-m`` for both
+installations, so that Python won't lock us out of using anything but the most
+recently-installed version of the package.)
+
+
+Executables and Launchers
+-------------------------
+
+On Unix systems, scripts are installed with as natural files with a "#!"
+header and no extension and they launch under the Python version indicated in
+the header.
+
+On Windows, there is no mechanism to "execute" files without extensions, so
+EasyInstall provides two techniques to mirror the Unix behavior. The behavior
+is indicated by the SETUPTOOLS_LAUNCHER environment variable, which may be
+"executable" (default) or "natural".
+
+Regardless of the technique used, the script(s) will be installed to a Scripts
+directory (by default in the Python installation directory). It is recommended
+for EasyInstall that you ensure this directory is in the PATH environment
+variable. The easiest way to ensure the Scripts directory is in the PATH is
+to run ``Tools\Scripts\win_add2path.py`` from the Python directory.
+
+Note that instead of changing your ``PATH`` to include the Python scripts
+directory, you can also retarget the installation location for scripts so they
+go on a directory that's already on the ``PATH``.  For more information see
+`Command-Line Options`_ and `Configuration Files`_.  During installation,
+pass command line options (such as ``--script-dir``) to control where
+scripts will be installed.
+
+
+Windows Executable Launcher
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If the "executable" launcher is used, EasyInstall will create a '.exe'
+launcher of the same name beside each installed script (including
+``easy_install`` itself). These small .exe files launch the script of the
+same name using the Python version indicated in the '#!' header.
+
+This behavior is currently default. To force
+the use of executable launchers, set ``SETUPTOOLS_LAUNCHER`` to "executable".
+
+Natural Script Launcher
+~~~~~~~~~~~~~~~~~~~~~~~
+
+EasyInstall also supports deferring to an external launcher such as
+`pylauncher <https://bitbucket.org/pypa/pylauncher>`_ for launching scripts.
+Enable this experimental functionality by setting the
+``SETUPTOOLS_LAUNCHER`` environment variable to "natural". EasyInstall will
+then install scripts as simple
+scripts with a .pya (or .pyw) extension appended. If these extensions are
+associated with the pylauncher and listed in the PATHEXT environment variable,
+these scripts can then be invoked simply and directly just like any other
+executable. This behavior may become default in a future version.
+
+EasyInstall uses the .pya extension instead of simply
+the typical '.py' extension. This distinct extension is necessary to prevent
+Python
+from treating the scripts as importable modules (where name conflicts exist).
+Current releases of pylauncher do not yet associate with .pya files by
+default, but future versions should do so.
+
+
+Tips & Techniques
+-----------------
+
+Multiple Python Versions
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+EasyInstall installs itself under two names:
+``easy_install`` and ``easy_install-N.N``, where ``N.N`` is the Python version
+used to install it.  Thus, if you install EasyInstall for both Python 3.2 and
+2.7, you can use the ``easy_install-3.2`` or ``easy_install-2.7`` scripts to
+install packages for the respective Python version.
+
+Setuptools also supplies easy_install as a runnable module which may be
+invoked using ``python -m easy_install`` for any Python with Setuptools
+installed.
+
+Restricting Downloads with ``--allow-hosts``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can use the ``--allow-hosts`` (``-H``) option to restrict what domains
+EasyInstall will look for links and downloads on.  ``--allow-hosts=None``
+prevents downloading altogether.  You can also use wildcards, for example
+to restrict downloading to hosts in your own intranet.  See the section below
+on `Command-Line Options`_ for more details on the ``--allow-hosts`` option.
+
+By default, there are no host restrictions in effect, but you can change this
+default by editing the appropriate `configuration files`_ and adding:
+
+.. code-block:: ini
+
+    [easy_install]
+    allow_hosts = *.myintranet.example.com,*.python.org
+
+The above example would then allow downloads only from hosts in the
+``python.org`` and ``myintranet.example.com`` domains, unless overridden on the
+command line.
+
+
+Installing on Un-networked Machines
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Just copy the eggs or source packages you need to a directory on the target
+machine, then use the ``-f`` or ``--find-links`` option to specify that
+directory's location.  For example::
+
+    easy_install -H None -f somedir SomePackage
+
+will attempt to install SomePackage using only eggs and source packages found
+in ``somedir`` and disallowing all remote access.  You should of course make
+sure you have all of SomePackage's dependencies available in somedir.
+
+If you have another machine of the same operating system and library versions
+(or if the packages aren't platform-specific), you can create the directory of
+eggs using a command like this::
+
+    easy_install -zmaxd somedir SomePackage
+
+This will tell EasyInstall to put zipped eggs or source packages for
+SomePackage and all its dependencies into ``somedir``, without creating any
+scripts or .pth files.  You can then copy the contents of ``somedir`` to the
+target machine.  (``-z`` means zipped eggs, ``-m`` means multi-version, which
+prevents .pth files from being used, ``-a`` means to copy all the eggs needed,
+even if they're installed elsewhere on the machine, and ``-d`` indicates the
+directory to place the eggs in.)
+
+You can also build the eggs from local development packages that were installed
+with the ``setup.py develop`` command, by including the ``-l`` option, e.g.::
+
+    easy_install -zmaxld somedir SomePackage
+
+This will use locally-available source distributions to build the eggs.
+
+
+Packaging Others' Projects As Eggs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Need to distribute a package that isn't published in egg form?  You can use
+EasyInstall to build eggs for a project.  You'll want to use the ``--zip-ok``,
+``--exclude-scripts``, and possibly ``--no-deps`` options (``-z``, ``-x`` and
+``-N``, respectively).  Use ``-d`` or ``--install-dir`` to specify the location
+where you'd like the eggs placed.  By placing them in a directory that is
+published to the web, you can then make the eggs available for download, either
+in an intranet or to the internet at large.
+
+If someone distributes a package in the form of a single ``.py`` file, you can
+wrap it in an egg by tacking an ``#egg=name-version`` suffix on the file's URL.
+So, something like this::
+
+    easy_install -f "http://some.example.com/downloads/foo.py#egg=foo-1.0" foo
+
+will install the package as an egg, and this::
+
+    easy_install -zmaxd. \
+        -f "http://some.example.com/downloads/foo.py#egg=foo-1.0" foo
+
+will create a ``.egg`` file in the current directory.
+
+
+Creating your own Package Index
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In addition to local directories and the Python Package Index, EasyInstall can
+find download links on most any web page whose URL is given to the ``-f``
+(``--find-links``) option.  In the simplest case, you can simply have a web
+page with links to eggs or Python source packages, even an automatically
+generated directory listing (such as the Apache web server provides).
+
+If you are setting up an intranet site for package downloads, you may want to
+configure the target machines to use your download site by default, adding
+something like this to their `configuration files`_:
+
+.. code-block:: ini
+
+    [easy_install]
+    find_links = http://mypackages.example.com/somedir/
+                 http://turbogears.org/download/
+                 http://peak.telecommunity.com/dist/
+
+As you can see, you can list multiple URLs separated by whitespace, continuing
+on multiple lines if necessary (as long as the subsequent lines are indented.
+
+If you are more ambitious, you can also create an entirely custom package index
+or PyPI mirror.  See the ``--index-url`` option under `Command-Line Options`_,
+below, and also the section on `Package Index "API"`_.
+
+
+Password-Protected Sites
+------------------------
+
+If a site you want to download from is password-protected using HTTP "Basic"
+authentication, you can specify your credentials in the URL, like so::
+
+    http://some_userid:some_password@some.example.com/some_path/
+
+You can do this with both index page URLs and direct download URLs.  As long
+as any HTML pages read by easy_install use *relative* links to point to the
+downloads, the same user ID and password will be used to do the downloading.
+
+Using .pypirc Credentials
+-------------------------
+
+In additional to supplying credentials in the URL, ``easy_install`` will also
+honor credentials if present in the .pypirc file. Teams maintaining a private
+repository of packages may already have defined access credentials for
+uploading packages according to the distutils documentation. ``easy_install``
+will attempt to honor those if present. Refer to the distutils documentation
+for Python 2.5 or later for details on the syntax.
+
+Controlling Build Options
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+EasyInstall respects standard distutils `Configuration Files`_, so you can use
+them to configure build options for packages that it installs from source.  For
+example, if you are on Windows using the MinGW compiler, you can configure the
+default compiler by putting something like this:
+
+.. code-block:: ini
+
+    [build]
+    compiler = mingw32
+
+into the appropriate distutils configuration file.  In fact, since this is just
+normal distutils configuration, it will affect any builds using that config
+file, not just ones done by EasyInstall.  For example, if you add those lines
+to ``distutils.cfg`` in the ``distutils`` package directory, it will be the
+default compiler for *all* packages you build.  See `Configuration Files`_
+below for a list of the standard configuration file locations, and links to
+more documentation on using distutils configuration files.
+
+
+Editing and Viewing Source Packages
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sometimes a package's source distribution  contains additional documentation,
+examples, configuration files, etc., that are not part of its actual code.  If
+you want to be able to examine these files, you can use the ``--editable``
+option to EasyInstall, and EasyInstall will look for a source distribution
+or Subversion URL for the package, then download and extract it or check it out
+as a subdirectory of the ``--build-directory`` you specify.  If you then wish
+to install the package after editing or configuring it, you can do so by
+rerunning EasyInstall with that directory as the target.
+
+Note that using ``--editable`` stops EasyInstall from actually building or
+installing the package; it just finds, obtains, and possibly unpacks it for
+you.  This allows you to make changes to the package if necessary, and to
+either install it in development mode using ``setup.py develop`` (if the
+package uses setuptools, that is), or by running ``easy_install projectdir``
+(where ``projectdir`` is the subdirectory EasyInstall created for the
+downloaded package.
+
+In order to use ``--editable`` (``-e`` for short), you *must* also supply a
+``--build-directory`` (``-b`` for short).  The project will be placed in a
+subdirectory of the build directory.  The subdirectory will have the same
+name as the project itself, but in all-lowercase.  If a file or directory of
+that name already exists, EasyInstall will print an error message and exit.
+
+Also, when using ``--editable``, you cannot use URLs or filenames as arguments.
+You *must* specify project names (and optional version requirements) so that
+EasyInstall knows what directory name(s) to create.  If you need to force
+EasyInstall to use a particular URL or filename, you should specify it as a
+``--find-links`` item (``-f`` for short), and then also specify
+the project name, e.g.::
+
+    easy_install -eb ~/projects \
+     -fhttp://prdownloads.sourceforge.net/ctypes/ctypes-0.9.6.tar.gz?download \
+     ctypes==0.9.6
+
+
+Dealing with Installation Conflicts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(NOTE: As of 0.6a11, this section is obsolete; it is retained here only so that
+people using older versions of EasyInstall can consult it.  As of version
+0.6a11, installation conflicts are handled automatically without deleting the
+old or system-installed packages, and without ignoring the issue.  Instead,
+eggs are automatically shifted to the front of ``sys.path`` using special
+code added to the ``easy-install.pth`` file.  So, if you are using version
+0.6a11 or better of setuptools, you do not need to worry about conflicts,
+and the following issues do not apply to you.)
+
+EasyInstall installs distributions in a "managed" way, such that each
+distribution can be independently activated or deactivated on ``sys.path``.
+However, packages that were not installed by EasyInstall are "unmanaged",
+in that they usually live all in one directory and cannot be independently
+activated or deactivated.
+
+As a result, if you are using EasyInstall to upgrade an existing package, or
+to install a package with the same name as an existing package, EasyInstall
+will warn you of the conflict.  (This is an improvement over ``setup.py
+install``, because the ``distutils`` just install new packages on top of old
+ones, possibly combining two unrelated packages or leaving behind modules that
+have been deleted in the newer version of the package.)
+
+EasyInstall will stop the installation if it detects a conflict
+between an existing, "unmanaged" package, and a module or package in any of
+the distributions you're installing.  It will display a list of all of the
+existing files and directories that would need to be deleted for the new
+package to be able to function correctly.  To proceed, you must manually
+delete these conflicting files and directories and re-run EasyInstall.
+
+Of course, once you've replaced all of your existing "unmanaged" packages with
+versions managed by EasyInstall, you won't have any more conflicts to worry
+about!
+
+
+Compressed Installation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+EasyInstall tries to install packages in zipped form, if it can.  Zipping
+packages can improve Python's overall import performance if you're not using
+the ``--multi-version`` option, because Python processes zipfile entries on
+``sys.path`` much faster than it does directories.
+
+As of version 0.5a9, EasyInstall analyzes packages to determine whether they
+can be safely installed as a zipfile, and then acts on its analysis.  (Previous
+versions would not install a package as a zipfile unless you used the
+``--zip-ok`` option.)
+
+The current analysis approach is fairly conservative; it currently looks for:
+
+ * Any use of the ``__file__`` or ``__path__`` variables (which should be
+   replaced with ``pkg_resources`` API calls)
+
+ * Possible use of ``inspect`` functions that expect to manipulate source files
+   (e.g. ``inspect.getsource()``)
+
+ * Top-level modules that might be scripts used with ``python -m`` (Python 2.4)
+
+If any of the above are found in the package being installed, EasyInstall will
+assume that the package cannot be safely run from a zipfile, and unzip it to
+a directory instead.  You can override this analysis with the ``-zip-ok`` flag,
+which will tell EasyInstall to install the package as a zipfile anyway.  Or,
+you can use the ``--always-unzip`` flag, in which case EasyInstall will always
+unzip, even if its analysis says the package is safe to run as a zipfile.
+
+Normally, however, it is simplest to let EasyInstall handle the determination
+of whether to zip or unzip, and only specify overrides when needed to work
+around a problem.  If you find you need to override EasyInstall's guesses, you
+may want to contact the package author and the EasyInstall maintainers, so that
+they can make appropriate changes in future versions.
+
+(Note: If a package uses ``setuptools`` in its setup script, the package author
+has the option to declare the package safe or unsafe for zipped usage via the
+``zip_safe`` argument to ``setup()``.  If the package author makes such a
+declaration, EasyInstall believes the package's author and does not perform its
+own analysis.  However, your command-line option, if any, will still override
+the package author's choice.)
+
+
+Reference Manual
+================
+
+Configuration Files
+-------------------
+
+(New in 0.4a2)
+
+You may specify default options for EasyInstall using the standard
+distutils configuration files, under the command heading ``easy_install``.
+EasyInstall will look first for a ``setup.cfg`` file in the current directory,
+then a ``~/.pydistutils.cfg`` or ``$HOME\\pydistutils.cfg`` (on Unix-like OSes
+and Windows, respectively), and finally a ``distutils.cfg`` file in the
+``distutils`` package directory.  Here's a simple example:
+
+.. code-block:: ini
+
+    [easy_install]
+
+    # set the default location to install packages
+    install_dir = /home/me/lib/python
+
+    # Notice that indentation can be used to continue an option
+    # value; this is especially useful for the "--find-links"
+    # option, which tells easy_install to use download links on
+    # these pages before consulting PyPI:
+    #
+    find_links = http://sqlobject.org/
+                 http://peak.telecommunity.com/dist/
+
+In addition to accepting configuration for its own options under
+``[easy_install]``, EasyInstall also respects defaults specified for other
+distutils commands.  For example, if you don't set an ``install_dir`` for
+``[easy_install]``, but *have* set an ``install_lib`` for the ``[install]``
+command, this will become EasyInstall's default installation directory.  Thus,
+if you are already using distutils configuration files to set default install
+locations, build options, etc., EasyInstall will respect your existing settings
+until and unless you override them explicitly in an ``[easy_install]`` section.
+
+For more information, see also the current Python documentation on the `use and
+location of distutils configuration files <https://docs.python.org/install/index.html#inst-config-files>`_.
+
+Notice that ``easy_install`` will use the ``setup.cfg`` from the current
+working directory only if it was triggered from ``setup.py`` through the
+``install_requires`` option. The standalone command will not use that file.
+
+Command-Line Options
+--------------------
+
+``--zip-ok, -z``
+    Install all packages as zip files, even if they are marked as unsafe for
+    running as a zipfile.  This can be useful when EasyInstall's analysis
+    of a non-setuptools package is too conservative, but keep in mind that
+    the package may not work correctly.  (Changed in 0.5a9; previously this
+    option was required in order for zipped installation to happen at all.)
+
+``--always-unzip, -Z``
+    Don't install any packages as zip files, even if the packages are marked
+    as safe for running as a zipfile.  This can be useful if a package does
+    something unsafe, but not in a way that EasyInstall can easily detect.
+    EasyInstall's default analysis is currently very conservative, however, so
+    you should only use this option if you've had problems with a particular
+    package, and *after* reporting the problem to the package's maintainer and
+    to the EasyInstall maintainers.
+
+    (Note: the ``-z/-Z`` options only affect the installation of newly-built
+    or downloaded packages that are not already installed in the target
+    directory; if you want to convert an existing installed version from
+    zipped to unzipped or vice versa, you'll need to delete the existing
+    version first, and re-run EasyInstall.)
+
+``--multi-version, -m``
+    "Multi-version" mode. Specifying this option prevents ``easy_install`` from
+    adding an ``easy-install.pth`` entry for the package being installed, and
+    if an entry for any version the package already exists, it will be removed
+    upon successful installation. In multi-version mode, no specific version of
+    the package is available for importing, unless you use
+    ``pkg_resources.require()`` to put it on ``sys.path``. This can be as
+    simple as::
+
+        from pkg_resources import require
+        require("SomePackage", "OtherPackage", "MyPackage")
+
+    which will put the latest installed version of the specified packages on
+    ``sys.path`` for you. (For more advanced uses, like selecting specific
+    versions and enabling optional dependencies, see the ``pkg_resources`` API
+    doc.)
+
+    Changed in 0.6a10: this option is no longer silently enabled when
+    installing to a non-PYTHONPATH, non-"site" directory.  You must always
+    explicitly use this option if you want it to be active.
+
+``--upgrade, -U``   (New in 0.5a4)
+    By default, EasyInstall only searches online if a project/version
+    requirement can't be met by distributions already installed
+    on sys.path or the installation directory.  However, if you supply the
+    ``--upgrade`` or ``-U`` flag, EasyInstall will always check the package
+    index and ``--find-links`` URLs before selecting a version to install.  In
+    this way, you can force EasyInstall to use the latest available version of
+    any package it installs (subject to any version requirements that might
+    exclude such later versions).
+
+``--install-dir=DIR, -d DIR``
+    Set the installation directory. It is up to you to ensure that this
+    directory is on ``sys.path`` at runtime, and to use
+    ``pkg_resources.require()`` to enable the installed package(s) that you
+    need.
+
+    (New in 0.4a2) If this option is not directly specified on the command line
+    or in a distutils configuration file, the distutils default installation
+    location is used.  Normally, this would be the ``site-packages`` directory,
+    but if you are using distutils configuration files, setting things like
+    ``prefix`` or ``install_lib``, then those settings are taken into
+    account when computing the default installation directory, as is the
+    ``--prefix`` option.
+
+``--script-dir=DIR, -s DIR``
+    Set the script installation directory.  If you don't supply this option
+    (via the command line or a configuration file), but you *have* supplied
+    an ``--install-dir`` (via command line or config file), then this option
+    defaults to the same directory, so that the scripts will be able to find
+    their associated package installation.  Otherwise, this setting defaults
+    to the location where the distutils would normally install scripts, taking
+    any distutils configuration file settings into account.
+
+``--exclude-scripts, -x``
+    Don't install scripts.  This is useful if you need to install multiple
+    versions of a package, but do not want to reset the version that will be
+    run by scripts that are already installed.
+
+``--user`` (New in 0.6.11)
+    Use the user-site-packages as specified in :pep:`370`
+    instead of the global site-packages.
+
+``--always-copy, -a``   (New in 0.5a4)
+    Copy all needed distributions to the installation directory, even if they
+    are already present in a directory on sys.path.  In older versions of
+    EasyInstall, this was the default behavior, but now you must explicitly
+    request it.  By default, EasyInstall will no longer copy such distributions
+    from other sys.path directories to the installation directory, unless you
+    explicitly gave the distribution's filename on the command line.
+
+    Note that as of 0.6a10, using this option excludes "system" and
+    "development" eggs from consideration because they can't be reliably
+    copied.  This may cause EasyInstall to choose an older version of a package
+    than what you expected, or it may cause downloading and installation of a
+    fresh copy of something that's already installed.  You will see warning
+    messages for any eggs that EasyInstall skips, before it falls back to an
+    older version or attempts to download a fresh copy.
+
+``--find-links=URLS_OR_FILENAMES, -f URLS_OR_FILENAMES``
+    Scan the specified "download pages" or directories for direct links to eggs
+    or other distributions.  Any existing file or directory names or direct
+    download URLs are immediately added to EasyInstall's search cache, and any
+    indirect URLs (ones that don't point to eggs or other recognized archive
+    formats) are added to a list of additional places to search for download
+    links.  As soon as EasyInstall has to go online to find a package (either
+    because it doesn't exist locally, or because ``--upgrade`` or ``-U`` was
+    used), the specified URLs will be downloaded and scanned for additional
+    direct links.
+
+    Eggs and archives found by way of ``--find-links`` are only downloaded if
+    they are needed to meet a requirement specified on the command line; links
+    to unneeded packages are ignored.
+
+    If all requested packages can be found using links on the specified
+    download pages, the Python Package Index will not be consulted unless you
+    also specified the ``--upgrade`` or ``-U`` option.
+
+    (Note: if you want to refer to a local HTML file containing links, you must
+    use a ``file:`` URL, as filenames that do not refer to a directory, egg, or
+    archive are ignored.)
+
+    You may specify multiple URLs or file/directory names with this option,
+    separated by whitespace.  Note that on the command line, you will probably
+    have to surround the URL list with quotes, so that it is recognized as a
+    single option value.  You can also specify URLs in a configuration file;
+    see `Configuration Files`_, above.
+
+    Changed in 0.6a10: previously all URLs and directories passed to this
+    option were scanned as early as possible, but from 0.6a10 on, only
+    directories and direct archive links are scanned immediately; URLs are not
+    retrieved unless a package search was already going to go online due to a
+    package not being available locally, or due to the use of the ``--update``
+    or ``-U`` option.
+
+``--no-find-links`` Blocks the addition of any link.
+    This parameter is useful if you want to avoid adding links defined in a
+    project easy_install is installing (whether it's a requested project or a
+    dependency). When used, ``--find-links`` is ignored.
+
+    Added in Distribute 0.6.11 and Setuptools 0.7.
+
+``--index-url=URL, -i URL`` (New in 0.4a1; default changed in 0.6c7)
+    Specifies the base URL of the Python Package Index.  The default is
+    https://pypi.org/simple/ if not specified.  When a package is requested
+    that is not locally available or linked from a ``--find-links`` download
+    page, the package index will be searched for download pages for the needed
+    package, and those download pages will be searched for links to download
+    an egg or source distribution.
+
+``--editable, -e`` (New in 0.6a1)
+    Only find and download source distributions for the specified projects,
+    unpacking them to subdirectories of the specified ``--build-directory``.
+    EasyInstall will not actually build or install the requested projects or
+    their dependencies; it will just find and extract them for you.  See
+    `Editing and Viewing Source Packages`_ above for more details.
+
+``--build-directory=DIR, -b DIR`` (UPDATED in 0.6a1)
+    Set the directory used to build source packages.  If a package is built
+    from a source distribution or checkout, it will be extracted to a
+    subdirectory of the specified directory.  The subdirectory will have the
+    same name as the extracted distribution's project, but in all-lowercase.
+    If a file or directory of that name already exists in the given directory,
+    a warning will be printed to the console, and the build will take place in
+    a temporary directory instead.
+
+    This option is most useful in combination with the ``--editable`` option,
+    which forces EasyInstall to *only* find and extract (but not build and
+    install) source distributions.  See `Editing and Viewing Source Packages`_,
+    above, for more information.
+
+``--verbose, -v, --quiet, -q`` (New in 0.4a4)
+    Control the level of detail of EasyInstall's progress messages.  The
+    default detail level is "info", which prints information only about
+    relatively time-consuming operations like running a setup script, unpacking
+    an archive, or retrieving a URL.  Using ``-q`` or ``--quiet`` drops the
+    detail level to "warn", which will only display installation reports,
+    warnings, and errors.  Using ``-v`` or ``--verbose`` increases the detail
+    level to include individual file-level operations, link analysis messages,
+    and distutils messages from any setup scripts that get run.  If you include
+    the ``-v`` option more than once, the second and subsequent uses are passed
+    down to any setup scripts, increasing the verbosity of their reporting as
+    well.
+
+``--dry-run, -n`` (New in 0.4a4)
+    Don't actually install the package or scripts.  This option is passed down
+    to any setup scripts run, so packages should not actually build either.
+    This does *not* skip downloading, nor does it skip extracting source
+    distributions to a temporary/build directory.
+
+``--optimize=LEVEL``, ``-O LEVEL`` (New in 0.4a4)
+    If you are installing from a source distribution, and are *not* using the
+    ``--zip-ok`` option, this option controls the optimization level for
+    compiling installed ``.py`` files to ``.pyo`` files.  It does not affect
+    the compilation of modules contained in ``.egg`` files, only those in
+    ``.egg`` directories.  The optimization level can be set to 0, 1, or 2;
+    the default is 0 (unless it's set under ``install`` or ``install_lib`` in
+    one of your distutils configuration files).
+
+``--record=FILENAME``  (New in 0.5a4)
+    Write a record of all installed files to FILENAME.  This is basically the
+    same as the same option for the standard distutils "install" command, and
+    is included for compatibility with tools that expect to pass this option
+    to "setup.py install".
+
+``--site-dirs=DIRLIST, -S DIRLIST``   (New in 0.6a1)
+    Specify one or more custom "site" directories (separated by commas).
+    "Site" directories are directories where ``.pth`` files are processed, such
+    as the main Python ``site-packages`` directory.  As of 0.6a10, EasyInstall
+    automatically detects whether a given directory processes ``.pth`` files
+    (or can be made to do so), so you should not normally need to use this
+    option.  It is is now only necessary if you want to override EasyInstall's
+    judgment and force an installation directory to be treated as if it
+    supported ``.pth`` files.
+
+``--no-deps, -N``  (New in 0.6a6)
+    Don't install any dependencies.  This is intended as a convenience for
+    tools that wrap eggs in a platform-specific packaging system.  (We don't
+    recommend that you use it for anything else.)
+
+``--allow-hosts=PATTERNS, -H PATTERNS``   (New in 0.6a6)
+    Restrict downloading and spidering to hosts matching the specified glob
+    patterns.  E.g. ``-H *.python.org`` restricts web access so that only
+    packages listed and downloadable from machines in the ``python.org``
+    domain.  The glob patterns must match the *entire* user/host/port section of
+    the target URL(s).  For example, ``*.python.org`` will NOT accept a URL
+    like ``http://python.org/foo`` or ``http://www.python.org:8080/``.
+    Multiple patterns can be specified by separating them with commas.  The
+    default pattern is ``*``, which matches anything.
+
+    In general, this option is mainly useful for blocking EasyInstall's web
+    access altogether (e.g. ``-Hlocalhost``), or to restrict it to an intranet
+    or other trusted site.  EasyInstall will do the best it can to satisfy
+    dependencies given your host restrictions, but of course can fail if it
+    can't find suitable packages.  EasyInstall displays all blocked URLs, so
+    that you can adjust your ``--allow-hosts`` setting if it is more strict
+    than you intended.  Some sites may wish to define a restrictive default
+    setting for this option in their `configuration files`_, and then manually
+    override the setting on the command line as needed.
+
+``--prefix=DIR`` (New in 0.6a10)
+    Use the specified directory as a base for computing the default
+    installation and script directories.  On Windows, the resulting default
+    directories will be ``prefix\\Lib\\site-packages`` and ``prefix\\Scripts``,
+    while on other platforms the defaults will be
+    ``prefix/lib/python2.X/site-packages`` (with the appropriate version
+    substituted) for libraries and ``prefix/bin`` for scripts.
+
+    Note that the ``--prefix`` option only sets the *default* installation and
+    script directories, and does not override the ones set on the command line
+    or in a configuration file.
+
+``--local-snapshots-ok, -l`` (New in 0.6c6)
+    Normally, EasyInstall prefers to only install *released* versions of
+    projects, not in-development ones, because such projects may not
+    have a currently-valid version number.  So, it usually only installs them
+    when their ``setup.py`` directory is explicitly passed on the command line.
+
+    However, if this option is used, then any in-development projects that were
+    installed using the ``setup.py develop`` command, will be used to build
+    eggs, effectively upgrading the "in-development" project to a snapshot
+    release.  Normally, this option is used only in conjunction with the
+    ``--always-copy`` option to create a distributable snapshot of every egg
+    needed to run an application.
+
+    Note that if you use this option, you must make sure that there is a valid
+    version number (such as an SVN revision number tag) for any in-development
+    projects that may be used, as otherwise EasyInstall may not be able to tell
+    what version of the project is "newer" when future installations or
+    upgrades are attempted.
+
+
+.. _non-root installation:
+
+Custom Installation Locations
+-----------------------------
+
+By default, EasyInstall installs python packages into Python's main ``site-packages`` directory,
+and manages them using a custom ``.pth`` file in that same directory.
+
+Very often though, a user or developer wants ``easy_install`` to install and manage python packages
+in an alternative location, usually for one of 3 reasons:
+
+1. They don't have access to write to the main Python site-packages directory.
+
+2. They want a user-specific stash of packages, that is not visible to other users.
+
+3. They want to isolate a set of packages to a specific python application, usually to minimize
+   the possibility of version conflicts.
+
+Historically, there have been many approaches to achieve custom installation.
+The following section lists only the easiest and most relevant approaches [1]_.
+
+`Use the "--user" option`_
+
+`Use the "--user" option and customize "PYTHONUSERBASE"`_
+
+`Use "virtualenv"`_
+
+.. [1] There are older ways to achieve custom installation using various ``easy_install`` and ``setup.py install`` options, combined with ``PYTHONPATH`` and/or ``PYTHONUSERBASE`` alterations, but all of these are effectively deprecated by the User scheme brought in by `PEP-370`_.
+
+.. _PEP-370: http://www.python.org/dev/peps/pep-0370/
+
+
+Use the "--user" option
+~~~~~~~~~~~~~~~~~~~~~~~
+Python provides a User scheme for installation, which means that all
+python distributions support an alternative install location that is specific to a user [3]_.
+The Default location for each OS is explained in the python documentation
+for the ``site.USER_BASE`` variable.  This mode of installation can be turned on by
+specifying the ``--user`` option to ``setup.py install`` or ``easy_install``.
+This approach serves the need to have a user-specific stash of packages.
+
+.. [3] Prior to the User scheme, there was the Home scheme, which is still available, but requires more effort than the User scheme to get packages recognized.
+
+Use the "--user" option and customize "PYTHONUSERBASE"
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The User scheme install location can be customized by setting the ``PYTHONUSERBASE`` environment
+variable, which updates the value of ``site.USER_BASE``.  To isolate packages to a specific
+application, simply set the OS environment of that application to a specific value of
+``PYTHONUSERBASE``, that contains just those packages.
+
+Use "virtualenv"
+~~~~~~~~~~~~~~~~
+"virtualenv" is a 3rd-party python package that effectively "clones" a python installation, thereby
+creating an isolated location to install packages.  The evolution of "virtualenv" started before the existence
+of the User installation scheme.  "virtualenv" provides a version of ``easy_install`` that is
+scoped to the cloned python install and is used in the normal way. "virtualenv" does offer various features
+that the User installation scheme alone does not provide, e.g. the ability to hide the main python site-packages.
+
+Please refer to the `virtualenv`_ documentation for more details.
+
+.. _virtualenv: https://pypi.org/project/virtualenv/
+
+
+
+Package Index "API"
+-------------------
+
+Custom package indexes (and PyPI) must follow the following rules for
+EasyInstall to be able to look up and download packages:
+
+1. Except where stated otherwise, "pages" are HTML or XHTML, and "links"
+   refer to ``href`` attributes.
+
+2. Individual project version pages' URLs must be of the form
+   ``base/projectname/version``, where ``base`` is the package index's base URL.
+
+3. Omitting the ``/version`` part of a project page's URL (but keeping the
+   trailing ``/``) should result in a page that is either:
+
+   a) The single active version of that project, as though the version had been
+      explicitly included, OR
+
+   b) A page with links to all of the active version pages for that project.
+
+4. Individual project version pages should contain direct links to downloadable
+   distributions where possible.  It is explicitly permitted for a project's
+   "long_description" to include URLs, and these should be formatted as HTML
+   links by the package index, as EasyInstall does no special processing to
+   identify what parts of a page are index-specific and which are part of the
+   project's supplied description.
+
+5. Where available, MD5 information should be added to download URLs by
+   appending a fragment identifier of the form ``#md5=...``, where ``...`` is
+   the 32-character hex MD5 digest.  EasyInstall will verify that the
+   downloaded file's MD5 digest matches the given value.
+
+6. Individual project version pages should identify any "homepage" or
+   "download" URLs using ``rel="homepage"`` and ``rel="download"`` attributes
+   on the HTML elements linking to those URLs. Use of these attributes will
+   cause EasyInstall to always follow the provided links, unless it can be
+   determined by inspection that they are downloadable distributions. If the
+   links are not to downloadable distributions, they are retrieved, and if they
+   are HTML, they are scanned for download links. They are *not* scanned for
+   additional "homepage" or "download" links, as these are only processed for
+   pages that are part of a package index site.
+
+7. The root URL of the index, if retrieved with a trailing ``/``, must result
+   in a page containing links to *all* projects' active version pages.
+
+   (Note: This requirement is a workaround for the absence of case-insensitive
+   ``safe_name()`` matching of project names in URL paths. If project names are
+   matched in this fashion (e.g. via the PyPI server, mod_rewrite, or a similar
+   mechanism), then it is not necessary to include this all-packages listing
+   page.)
+
+8. If a package index is accessed via a ``file://`` URL, then EasyInstall will
+   automatically use ``index.html`` files, if present, when trying to read a
+   directory with a trailing ``/`` on the URL.
diff --git a/docs/index.txt b/docs/index.txt
index c251260df..13a46e74e 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -21,4 +21,5 @@ Documentation content:
    python3
    development
    roadmap
+   Deprecated: Easy Install <easy_install>
    history
diff --git a/easy_install.py b/easy_install.py
new file mode 100644
index 000000000..d87e98403
--- /dev/null
+++ b/easy_install.py
@@ -0,0 +1,5 @@
+"""Run the EasyInstall command"""
+
+if __name__ == '__main__':
+    from setuptools.command.easy_install import main
+    main()
diff --git a/setup.cfg b/setup.cfg
index 385ba14df..42a3d86c6 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -51,6 +51,7 @@ classifiers =
 [options]
 zip_safe = True
 python_requires = >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*
+py_modules = easy_install
 packages = find:
 
 [options.packages.find]
diff --git a/setup.py b/setup.py
index 59efc2374..d97895fcc 100755
--- a/setup.py
+++ b/setup.py
@@ -31,6 +31,22 @@ def read_commands():
     return command_ns['__all__']
 
 
+def _gen_console_scripts():
+    yield "easy_install = setuptools.command.easy_install:main"
+
+    # Gentoo distributions manage the python-version-specific scripts
+    # themselves, so those platforms define an environment variable to
+    # suppress the creation of the version-specific scripts.
+    var_names = (
+        'SETUPTOOLS_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT',
+        'DISTRIBUTE_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT',
+    )
+    if any(os.environ.get(var) not in (None, "", "0") for var in var_names):
+        return
+    tmpl = "easy_install-{shortver} = setuptools.command.easy_install:main"
+    yield tmpl.format(shortver='{}.{}'.format(*sys.version_info))
+
+
 package_data = dict(
     setuptools=['script (dev).tmpl', 'script.tmpl', 'site-patch.py'],
 )
@@ -109,6 +125,9 @@ setup_params = dict(
             "depends.txt = setuptools.command.egg_info:warn_depends_obsolete",
             "dependency_links.txt = setuptools.command.egg_info:overwrite_arg",
         ],
+        "console_scripts": list(_gen_console_scripts()),
+        "setuptools.installation":
+            ['eggsecutable = setuptools.command.easy_install:bootstrap'],
     },
     dependency_links=[
         pypi_link(
diff --git a/setuptools/_vendor/packaging/__about__.py b/setuptools/_vendor/packaging/__about__.py
index dc95138d0..95d330ef8 100644
--- a/setuptools/_vendor/packaging/__about__.py
+++ b/setuptools/_vendor/packaging/__about__.py
@@ -4,24 +4,18 @@
 from __future__ import absolute_import, division, print_function
 
 __all__ = [
-    "__title__",
-    "__summary__",
-    "__uri__",
-    "__version__",
-    "__author__",
-    "__email__",
-    "__license__",
-    "__copyright__",
+    "__title__", "__summary__", "__uri__", "__version__", "__author__",
+    "__email__", "__license__", "__copyright__",
 ]
 
 __title__ = "packaging"
 __summary__ = "Core utilities for Python packages"
 __uri__ = "https://github.com/pypa/packaging"
 
-__version__ = "19.2"
+__version__ = "16.8"
 
 __author__ = "Donald Stufft and individual contributors"
 __email__ = "donald@stufft.io"
 
 __license__ = "BSD or Apache License, Version 2.0"
-__copyright__ = "Copyright 2014-2019 %s" % __author__
+__copyright__ = "Copyright 2014-2016 %s" % __author__
diff --git a/setuptools/_vendor/packaging/__init__.py b/setuptools/_vendor/packaging/__init__.py
index a0cf67df5..5ee622020 100644
--- a/setuptools/_vendor/packaging/__init__.py
+++ b/setuptools/_vendor/packaging/__init__.py
@@ -4,23 +4,11 @@
 from __future__ import absolute_import, division, print_function
 
 from .__about__ import (
-    __author__,
-    __copyright__,
-    __email__,
-    __license__,
-    __summary__,
-    __title__,
-    __uri__,
-    __version__,
+    __author__, __copyright__, __email__, __license__, __summary__, __title__,
+    __uri__, __version__
 )
 
 __all__ = [
-    "__title__",
-    "__summary__",
-    "__uri__",
-    "__version__",
-    "__author__",
-    "__email__",
-    "__license__",
-    "__copyright__",
+    "__title__", "__summary__", "__uri__", "__version__", "__author__",
+    "__email__", "__license__", "__copyright__",
 ]
diff --git a/setuptools/_vendor/packaging/_compat.py b/setuptools/_vendor/packaging/_compat.py
index 25da473c1..210bb80b7 100644
--- a/setuptools/_vendor/packaging/_compat.py
+++ b/setuptools/_vendor/packaging/_compat.py
@@ -12,9 +12,9 @@ PY3 = sys.version_info[0] == 3
 # flake8: noqa
 
 if PY3:
-    string_types = (str,)
+    string_types = str,
 else:
-    string_types = (basestring,)
+    string_types = basestring,
 
 
 def with_metaclass(meta, *bases):
@@ -27,5 +27,4 @@ def with_metaclass(meta, *bases):
     class metaclass(meta):
         def __new__(cls, name, this_bases, d):
             return meta(name, bases, d)
-
-    return type.__new__(metaclass, "temporary_class", (), {})
+    return type.__new__(metaclass, 'temporary_class', (), {})
diff --git a/setuptools/_vendor/packaging/_structures.py b/setuptools/_vendor/packaging/_structures.py
index 68dcca634..ccc27861c 100644
--- a/setuptools/_vendor/packaging/_structures.py
+++ b/setuptools/_vendor/packaging/_structures.py
@@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function
 
 
 class Infinity(object):
+
     def __repr__(self):
         return "Infinity"
 
@@ -32,11 +33,11 @@ class Infinity(object):
     def __neg__(self):
         return NegativeInfinity
 
-
 Infinity = Infinity()
 
 
 class NegativeInfinity(object):
+
     def __repr__(self):
         return "-Infinity"
 
@@ -64,5 +65,4 @@ class NegativeInfinity(object):
     def __neg__(self):
         return Infinity
 
-
 NegativeInfinity = NegativeInfinity()
diff --git a/setuptools/_vendor/packaging/markers.py b/setuptools/_vendor/packaging/markers.py
index 4bdfdb24f..031332a30 100644
--- a/setuptools/_vendor/packaging/markers.py
+++ b/setuptools/_vendor/packaging/markers.py
@@ -17,11 +17,8 @@ from .specifiers import Specifier, InvalidSpecifier
 
 
 __all__ = [
-    "InvalidMarker",
-    "UndefinedComparison",
-    "UndefinedEnvironmentName",
-    "Marker",
-    "default_environment",
+    "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName",
+    "Marker", "default_environment",
 ]
 
 
@@ -45,6 +42,7 @@ class UndefinedEnvironmentName(ValueError):
 
 
 class Node(object):
+
     def __init__(self, value):
         self.value = value
 
@@ -59,52 +57,62 @@ class Node(object):
 
 
 class Variable(Node):
+
     def serialize(self):
         return str(self)
 
 
 class Value(Node):
+
     def serialize(self):
         return '"{0}"'.format(self)
 
 
 class Op(Node):
+
     def serialize(self):
         return str(self)
 
 
 VARIABLE = (
-    L("implementation_version")
-    | L("platform_python_implementation")
-    | L("implementation_name")
-    | L("python_full_version")
-    | L("platform_release")
-    | L("platform_version")
-    | L("platform_machine")
-    | L("platform_system")
-    | L("python_version")
-    | L("sys_platform")
-    | L("os_name")
-    | L("os.name")
-    | L("sys.platform")  # PEP-345
-    | L("platform.version")  # PEP-345
-    | L("platform.machine")  # PEP-345
-    | L("platform.python_implementation")  # PEP-345
-    | L("python_implementation")  # PEP-345
-    | L("extra")  # undocumented setuptools legacy
+    L("implementation_version") |
+    L("platform_python_implementation") |
+    L("implementation_name") |
+    L("python_full_version") |
+    L("platform_release") |
+    L("platform_version") |
+    L("platform_machine") |
+    L("platform_system") |
+    L("python_version") |
+    L("sys_platform") |
+    L("os_name") |
+    L("os.name") |  # PEP-345
+    L("sys.platform") |  # PEP-345
+    L("platform.version") |  # PEP-345
+    L("platform.machine") |  # PEP-345
+    L("platform.python_implementation") |  # PEP-345
+    L("python_implementation") |  # undocumented setuptools legacy
+    L("extra")
 )
 ALIASES = {
-    "os.name": "os_name",
-    "sys.platform": "sys_platform",
-    "platform.version": "platform_version",
-    "platform.machine": "platform_machine",
-    "platform.python_implementation": "platform_python_implementation",
-    "python_implementation": "platform_python_implementation",
+    'os.name': 'os_name',
+    'sys.platform': 'sys_platform',
+    'platform.version': 'platform_version',
+    'platform.machine': 'platform_machine',
+    'platform.python_implementation': 'platform_python_implementation',
+    'python_implementation': 'platform_python_implementation'
 }
 VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0])))
 
 VERSION_CMP = (
-    L("===") | L("==") | L(">=") | L("<=") | L("!=") | L("~=") | L(">") | L("<")
+    L("===") |
+    L("==") |
+    L(">=") |
+    L("<=") |
+    L("!=") |
+    L("~=") |
+    L(">") |
+    L("<")
 )
 
 MARKER_OP = VERSION_CMP | L("not in") | L("in")
@@ -144,11 +152,8 @@ def _format_marker(marker, first=True):
     # where the single item is itself it's own list. In that case we want skip
     # the rest of this function so that we don't get extraneous () on the
     # outside.
-    if (
-        isinstance(marker, list)
-        and len(marker) == 1
-        and isinstance(marker[0], (list, tuple))
-    ):
+    if (isinstance(marker, list) and len(marker) == 1 and
+            isinstance(marker[0], (list, tuple))):
         return _format_marker(marker[0])
 
     if isinstance(marker, list):
@@ -234,20 +239,20 @@ def _evaluate_markers(markers, environment):
 
 
 def format_full_version(info):
-    version = "{0.major}.{0.minor}.{0.micro}".format(info)
+    version = '{0.major}.{0.minor}.{0.micro}'.format(info)
     kind = info.releaselevel
-    if kind != "final":
+    if kind != 'final':
         version += kind[0] + str(info.serial)
     return version
 
 
 def default_environment():
-    if hasattr(sys, "implementation"):
+    if hasattr(sys, 'implementation'):
         iver = format_full_version(sys.implementation.version)
         implementation_name = sys.implementation.name
     else:
-        iver = "0"
-        implementation_name = ""
+        iver = '0'
+        implementation_name = ''
 
     return {
         "implementation_name": implementation_name,
@@ -259,19 +264,19 @@ def default_environment():
         "platform_version": platform.version(),
         "python_full_version": platform.python_version(),
         "platform_python_implementation": platform.python_implementation(),
-        "python_version": ".".join(platform.python_version_tuple()[:2]),
+        "python_version": platform.python_version()[:3],
         "sys_platform": sys.platform,
     }
 
 
 class Marker(object):
+
     def __init__(self, marker):
         try:
             self._markers = _coerce_parse_result(MARKER.parseString(marker))
         except ParseException as e:
             err_str = "Invalid marker: {0!r}, parse error at {1!r}".format(
-                marker, marker[e.loc : e.loc + 8]
-            )
+                marker, marker[e.loc:e.loc + 8])
             raise InvalidMarker(err_str)
 
     def __str__(self):
diff --git a/setuptools/_vendor/packaging/requirements.py b/setuptools/_vendor/packaging/requirements.py
index 8a0c2cb9b..5b493416f 100644
--- a/setuptools/_vendor/packaging/requirements.py
+++ b/setuptools/_vendor/packaging/requirements.py
@@ -38,8 +38,8 @@ IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END))
 NAME = IDENTIFIER("name")
 EXTRA = IDENTIFIER
 
-URI = Regex(r"[^ ]+")("url")
-URL = AT + URI
+URI = Regex(r'[^ ]+')("url")
+URL = (AT + URI)
 
 EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA)
 EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras")
@@ -48,31 +48,28 @@ VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE)
 VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE)
 
 VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY
-VERSION_MANY = Combine(
-    VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=",", adjacent=False
-)("_raw_spec")
+VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE),
+                       joinString=",", adjacent=False)("_raw_spec")
 _VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY))
-_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or "")
+_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '')
 
 VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier")
 VERSION_SPEC.setParseAction(lambda s, l, t: t[1])
 
 MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
 MARKER_EXPR.setParseAction(
-    lambda s, l, t: Marker(s[t._original_start : t._original_end])
+    lambda s, l, t: Marker(s[t._original_start:t._original_end])
 )
-MARKER_SEPARATOR = SEMICOLON
-MARKER = MARKER_SEPARATOR + MARKER_EXPR
+MARKER_SEPERATOR = SEMICOLON
+MARKER = MARKER_SEPERATOR + MARKER_EXPR
 
 VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER)
 URL_AND_MARKER = URL + Optional(MARKER)
 
-NAMED_REQUIREMENT = NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)
+NAMED_REQUIREMENT = \
+    NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)
 
 REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd
-# setuptools.extern.pyparsing isn't thread safe during initialization, so we do it eagerly, see
-# issue #104
-REQUIREMENT.parseString("x[]")
 
 
 class Requirement(object):
@@ -93,21 +90,15 @@ class Requirement(object):
             req = REQUIREMENT.parseString(requirement_string)
         except ParseException as e:
             raise InvalidRequirement(
-                'Parse error at "{0!r}": {1}'.format(
-                    requirement_string[e.loc : e.loc + 8], e.msg
-                )
-            )
+                "Invalid requirement, parse error at \"{0!r}\"".format(
+                    requirement_string[e.loc:e.loc + 8]))
 
         self.name = req.name
         if req.url:
             parsed_url = urlparse.urlparse(req.url)
-            if parsed_url.scheme == "file":
-                if urlparse.urlunparse(parsed_url) != req.url:
-                    raise InvalidRequirement("Invalid URL given")
-            elif not (parsed_url.scheme and parsed_url.netloc) or (
-                not parsed_url.scheme and not parsed_url.netloc
-            ):
-                raise InvalidRequirement("Invalid URL: {0}".format(req.url))
+            if not (parsed_url.scheme and parsed_url.netloc) or (
+                    not parsed_url.scheme and not parsed_url.netloc):
+                raise InvalidRequirement("Invalid URL given")
             self.url = req.url
         else:
             self.url = None
@@ -126,8 +117,6 @@ class Requirement(object):
 
         if self.url:
             parts.append("@ {0}".format(self.url))
-            if self.marker:
-                parts.append(" ")
 
         if self.marker:
             parts.append("; {0}".format(self.marker))
diff --git a/setuptools/_vendor/packaging/specifiers.py b/setuptools/_vendor/packaging/specifiers.py
index 743576a08..7f5a76cfd 100644
--- a/setuptools/_vendor/packaging/specifiers.py
+++ b/setuptools/_vendor/packaging/specifiers.py
@@ -19,6 +19,7 @@ class InvalidSpecifier(ValueError):
 
 
 class BaseSpecifier(with_metaclass(abc.ABCMeta, object)):
+
     @abc.abstractmethod
     def __str__(self):
         """
@@ -83,7 +84,10 @@ class _IndividualSpecifier(BaseSpecifier):
         if not match:
             raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
 
-        self._spec = (match.group("operator").strip(), match.group("version").strip())
+        self._spec = (
+            match.group("operator").strip(),
+            match.group("version").strip(),
+        )
 
         # Store whether or not this Specifier should accept prereleases
         self._prereleases = prereleases
@@ -95,7 +99,11 @@ class _IndividualSpecifier(BaseSpecifier):
             else ""
         )
 
-        return "<{0}({1!r}{2})>".format(self.__class__.__name__, str(self), pre)
+        return "<{0}({1!r}{2})>".format(
+            self.__class__.__name__,
+            str(self),
+            pre,
+        )
 
     def __str__(self):
         return "{0}{1}".format(*self._spec)
@@ -186,12 +194,11 @@ class _IndividualSpecifier(BaseSpecifier):
                 # If our version is a prerelease, and we were not set to allow
                 # prereleases, then we'll store it for later incase nothing
                 # else matches this specifier.
-                if parsed_version.is_prerelease and not (
-                    prereleases or self.prereleases
-                ):
+                if (parsed_version.is_prerelease and not
+                        (prereleases or self.prereleases)):
                     found_prereleases.append(version)
                 # Either this is not a prerelease, or we should have been
-                # accepting prereleases from the beginning.
+                # accepting prereleases from the begining.
                 else:
                     yielded = True
                     yield version
@@ -206,7 +213,8 @@ class _IndividualSpecifier(BaseSpecifier):
 
 class LegacySpecifier(_IndividualSpecifier):
 
-    _regex_str = r"""
+    _regex_str = (
+        r"""
         (?P<operator>(==|!=|<=|>=|<|>))
         \s*
         (?P<version>
@@ -217,8 +225,10 @@ class LegacySpecifier(_IndividualSpecifier):
                       # them, and a comma since it's a version separator.
         )
         """
+    )
 
-    _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
+    _regex = re.compile(
+        r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
 
     _operators = {
         "==": "equal",
@@ -259,13 +269,13 @@ def _require_version_compare(fn):
         if not isinstance(prospective, Version):
             return False
         return fn(self, prospective, spec)
-
     return wrapped
 
 
 class Specifier(_IndividualSpecifier):
 
-    _regex_str = r"""
+    _regex_str = (
+        r"""
         (?P<operator>(~=|==|!=|<=|>=|<|>|===))
         (?P<version>
             (?:
@@ -357,8 +367,10 @@ class Specifier(_IndividualSpecifier):
             )
         )
         """
+    )
 
-    _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
+    _regex = re.compile(
+        r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
 
     _operators = {
         "~=": "compatible",
@@ -385,7 +397,8 @@ class Specifier(_IndividualSpecifier):
         prefix = ".".join(
             list(
                 itertools.takewhile(
-                    lambda x: (not x.startswith("post") and not x.startswith("dev")),
+                    lambda x: (not x.startswith("post") and not
+                               x.startswith("dev")),
                     _version_split(spec),
                 )
             )[:-1]
@@ -394,9 +407,8 @@ class Specifier(_IndividualSpecifier):
         # Add the prefix notation to the end of our string
         prefix += ".*"
 
-        return self._get_operator(">=")(prospective, spec) and self._get_operator("==")(
-            prospective, prefix
-        )
+        return (self._get_operator(">=")(prospective, spec) and
+                self._get_operator("==")(prospective, prefix))
 
     @_require_version_compare
     def _compare_equal(self, prospective, spec):
@@ -416,7 +428,7 @@ class Specifier(_IndividualSpecifier):
             # Shorten the prospective version to be the same length as the spec
             # so that we can determine if the specifier is a prefix of the
             # prospective version or not.
-            prospective = prospective[: len(spec)]
+            prospective = prospective[:len(spec)]
 
             # Pad out our two sides with zeros so that they both equal the same
             # length.
@@ -491,7 +503,7 @@ class Specifier(_IndividualSpecifier):
                 return False
 
         # Ensure that we do not allow a local version of the version mentioned
-        # in the specifier, which is technically greater than, to match.
+        # in the specifier, which is techincally greater than, to match.
         if prospective.local is not None:
             if Version(prospective.base_version) == Version(spec.base_version):
                 return False
@@ -555,17 +567,27 @@ def _pad_version(left, right):
     right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
 
     # Get the rest of our versions
-    left_split.append(left[len(left_split[0]) :])
-    right_split.append(right[len(right_split[0]) :])
+    left_split.append(left[len(left_split[0]):])
+    right_split.append(right[len(right_split[0]):])
 
     # Insert our padding
-    left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0])))
-    right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0])))
+    left_split.insert(
+        1,
+        ["0"] * max(0, len(right_split[0]) - len(left_split[0])),
+    )
+    right_split.insert(
+        1,
+        ["0"] * max(0, len(left_split[0]) - len(right_split[0])),
+    )
 
-    return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split)))
+    return (
+        list(itertools.chain(*left_split)),
+        list(itertools.chain(*right_split)),
+    )
 
 
 class SpecifierSet(BaseSpecifier):
+
     def __init__(self, specifiers="", prereleases=None):
         # Split on , to break each indidivual specifier into it's own item, and
         # strip each item to remove leading/trailing whitespace.
@@ -699,7 +721,10 @@ class SpecifierSet(BaseSpecifier):
         # given version is contained within all of them.
         # Note: This use of all() here means that an empty set of specifiers
         #       will always return True, this is an explicit design decision.
-        return all(s.contains(item, prereleases=prereleases) for s in self._specs)
+        return all(
+            s.contains(item, prereleases=prereleases)
+            for s in self._specs
+        )
 
     def filter(self, iterable, prereleases=None):
         # Determine if we're forcing a prerelease or not, if we're not forcing
diff --git a/setuptools/_vendor/packaging/tags.py b/setuptools/_vendor/packaging/tags.py
deleted file mode 100644
index ec9942f0f..000000000
--- a/setuptools/_vendor/packaging/tags.py
+++ /dev/null
@@ -1,404 +0,0 @@
-# This file is dual licensed under the terms of the Apache License, Version
-# 2.0, and the BSD License. See the LICENSE file in the root of this repository
-# for complete details.
-
-from __future__ import absolute_import
-
-import distutils.util
-
-try:
-    from importlib.machinery import EXTENSION_SUFFIXES
-except ImportError:  # pragma: no cover
-    import imp
-
-    EXTENSION_SUFFIXES = [x[0] for x in imp.get_suffixes()]
-    del imp
-import platform
-import re
-import sys
-import sysconfig
-import warnings
-
-
-INTERPRETER_SHORT_NAMES = {
-    "python": "py",  # Generic.
-    "cpython": "cp",
-    "pypy": "pp",
-    "ironpython": "ip",
-    "jython": "jy",
-}
-
-
-_32_BIT_INTERPRETER = sys.maxsize <= 2 ** 32
-
-
-class Tag(object):
-
-    __slots__ = ["_interpreter", "_abi", "_platform"]
-
-    def __init__(self, interpreter, abi, platform):
-        self._interpreter = interpreter.lower()
-        self._abi = abi.lower()
-        self._platform = platform.lower()
-
-    @property
-    def interpreter(self):
-        return self._interpreter
-
-    @property
-    def abi(self):
-        return self._abi
-
-    @property
-    def platform(self):
-        return self._platform
-
-    def __eq__(self, other):
-        return (
-            (self.platform == other.platform)
-            and (self.abi == other.abi)
-            and (self.interpreter == other.interpreter)
-        )
-
-    def __hash__(self):
-        return hash((self._interpreter, self._abi, self._platform))
-
-    def __str__(self):
-        return "{}-{}-{}".format(self._interpreter, self._abi, self._platform)
-
-    def __repr__(self):
-        return "<{self} @ {self_id}>".format(self=self, self_id=id(self))
-
-
-def parse_tag(tag):
-    tags = set()
-    interpreters, abis, platforms = tag.split("-")
-    for interpreter in interpreters.split("."):
-        for abi in abis.split("."):
-            for platform_ in platforms.split("."):
-                tags.add(Tag(interpreter, abi, platform_))
-    return frozenset(tags)
-
-
-def _normalize_string(string):
-    return string.replace(".", "_").replace("-", "_")
-
-
-def _cpython_interpreter(py_version):
-    # TODO: Is using py_version_nodot for interpreter version critical?
-    return "cp{major}{minor}".format(major=py_version[0], minor=py_version[1])
-
-
-def _cpython_abis(py_version):
-    abis = []
-    version = "{}{}".format(*py_version[:2])
-    debug = pymalloc = ucs4 = ""
-    with_debug = sysconfig.get_config_var("Py_DEBUG")
-    has_refcount = hasattr(sys, "gettotalrefcount")
-    # Windows doesn't set Py_DEBUG, so checking for support of debug-compiled
-    # extension modules is the best option.
-    # https://github.com/pypa/pip/issues/3383#issuecomment-173267692
-    has_ext = "_d.pyd" in EXTENSION_SUFFIXES
-    if with_debug or (with_debug is None and (has_refcount or has_ext)):
-        debug = "d"
-    if py_version < (3, 8):
-        with_pymalloc = sysconfig.get_config_var("WITH_PYMALLOC")
-        if with_pymalloc or with_pymalloc is None:
-            pymalloc = "m"
-        if py_version < (3, 3):
-            unicode_size = sysconfig.get_config_var("Py_UNICODE_SIZE")
-            if unicode_size == 4 or (
-                unicode_size is None and sys.maxunicode == 0x10FFFF
-            ):
-                ucs4 = "u"
-    elif debug:
-        # Debug builds can also load "normal" extension modules.
-        # We can also assume no UCS-4 or pymalloc requirement.
-        abis.append("cp{version}".format(version=version))
-    abis.insert(
-        0,
-        "cp{version}{debug}{pymalloc}{ucs4}".format(
-            version=version, debug=debug, pymalloc=pymalloc, ucs4=ucs4
-        ),
-    )
-    return abis
-
-
-def _cpython_tags(py_version, interpreter, abis, platforms):
-    for abi in abis:
-        for platform_ in platforms:
-            yield Tag(interpreter, abi, platform_)
-    for tag in (Tag(interpreter, "abi3", platform_) for platform_ in platforms):
-        yield tag
-    for tag in (Tag(interpreter, "none", platform_) for platform_ in platforms):
-        yield tag
-    # PEP 384 was first implemented in Python 3.2.
-    for minor_version in range(py_version[1] - 1, 1, -1):
-        for platform_ in platforms:
-            interpreter = "cp{major}{minor}".format(
-                major=py_version[0], minor=minor_version
-            )
-            yield Tag(interpreter, "abi3", platform_)
-
-
-def _pypy_interpreter():
-    return "pp{py_major}{pypy_major}{pypy_minor}".format(
-        py_major=sys.version_info[0],
-        pypy_major=sys.pypy_version_info.major,
-        pypy_minor=sys.pypy_version_info.minor,
-    )
-
-
-def _generic_abi():
-    abi = sysconfig.get_config_var("SOABI")
-    if abi:
-        return _normalize_string(abi)
-    else:
-        return "none"
-
-
-def _pypy_tags(py_version, interpreter, abi, platforms):
-    for tag in (Tag(interpreter, abi, platform) for platform in platforms):
-        yield tag
-    for tag in (Tag(interpreter, "none", platform) for platform in platforms):
-        yield tag
-
-
-def _generic_tags(interpreter, py_version, abi, platforms):
-    for tag in (Tag(interpreter, abi, platform) for platform in platforms):
-        yield tag
-    if abi != "none":
-        tags = (Tag(interpreter, "none", platform_) for platform_ in platforms)
-        for tag in tags:
-            yield tag
-
-
-def _py_interpreter_range(py_version):
-    """
-    Yield Python versions in descending order.
-
-    After the latest version, the major-only version will be yielded, and then
-    all following versions up to 'end'.
-    """
-    yield "py{major}{minor}".format(major=py_version[0], minor=py_version[1])
-    yield "py{major}".format(major=py_version[0])
-    for minor in range(py_version[1] - 1, -1, -1):
-        yield "py{major}{minor}".format(major=py_version[0], minor=minor)
-
-
-def _independent_tags(interpreter, py_version, platforms):
-    """
-    Return the sequence of tags that are consistent across implementations.
-
-    The tags consist of:
-    - py*-none-<platform>
-    - <interpreter>-none-any
-    - py*-none-any
-    """
-    for version in _py_interpreter_range(py_version):
-        for platform_ in platforms:
-            yield Tag(version, "none", platform_)
-    yield Tag(interpreter, "none", "any")
-    for version in _py_interpreter_range(py_version):
-        yield Tag(version, "none", "any")
-
-
-def _mac_arch(arch, is_32bit=_32_BIT_INTERPRETER):
-    if not is_32bit:
-        return arch
-
-    if arch.startswith("ppc"):
-        return "ppc"
-
-    return "i386"
-
-
-def _mac_binary_formats(version, cpu_arch):
-    formats = [cpu_arch]
-    if cpu_arch == "x86_64":
-        if version < (10, 4):
-            return []
-        formats.extend(["intel", "fat64", "fat32"])
-
-    elif cpu_arch == "i386":
-        if version < (10, 4):
-            return []
-        formats.extend(["intel", "fat32", "fat"])
-
-    elif cpu_arch == "ppc64":
-        # TODO: Need to care about 32-bit PPC for ppc64 through 10.2?
-        if version > (10, 5) or version < (10, 4):
-            return []
-        formats.append("fat64")
-
-    elif cpu_arch == "ppc":
-        if version > (10, 6):
-            return []
-        formats.extend(["fat32", "fat"])
-
-    formats.append("universal")
-    return formats
-
-
-def _mac_platforms(version=None, arch=None):
-    version_str, _, cpu_arch = platform.mac_ver()
-    if version is None:
-        version = tuple(map(int, version_str.split(".")[:2]))
-    if arch is None:
-        arch = _mac_arch(cpu_arch)
-    platforms = []
-    for minor_version in range(version[1], -1, -1):
-        compat_version = version[0], minor_version
-        binary_formats = _mac_binary_formats(compat_version, arch)
-        for binary_format in binary_formats:
-            platforms.append(
-                "macosx_{major}_{minor}_{binary_format}".format(
-                    major=compat_version[0],
-                    minor=compat_version[1],
-                    binary_format=binary_format,
-                )
-            )
-    return platforms
-
-
-# From PEP 513.
-def _is_manylinux_compatible(name, glibc_version):
-    # Check for presence of _manylinux module.
-    try:
-        import _manylinux
-
-        return bool(getattr(_manylinux, name + "_compatible"))
-    except (ImportError, AttributeError):
-        # Fall through to heuristic check below.
-        pass
-
-    return _have_compatible_glibc(*glibc_version)
-
-
-def _glibc_version_string():
-    # Returns glibc version string, or None if not using glibc.
-    import ctypes
-
-    # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
-    # manpage says, "If filename is NULL, then the returned handle is for the
-    # main program". This way we can let the linker do the work to figure out
-    # which libc our process is actually using.
-    process_namespace = ctypes.CDLL(None)
-    try:
-        gnu_get_libc_version = process_namespace.gnu_get_libc_version
-    except AttributeError:
-        # Symbol doesn't exist -> therefore, we are not linked to
-        # glibc.
-        return None
-
-    # Call gnu_get_libc_version, which returns a string like "2.5"
-    gnu_get_libc_version.restype = ctypes.c_char_p
-    version_str = gnu_get_libc_version()
-    # py2 / py3 compatibility:
-    if not isinstance(version_str, str):
-        version_str = version_str.decode("ascii")
-
-    return version_str
-
-
-# Separated out from have_compatible_glibc for easier unit testing.
-def _check_glibc_version(version_str, required_major, minimum_minor):
-    # Parse string and check against requested version.
-    #
-    # We use a regexp instead of str.split because we want to discard any
-    # random junk that might come after the minor version -- this might happen
-    # in patched/forked versions of glibc (e.g. Linaro's version of glibc
-    # uses version strings like "2.20-2014.11"). See gh-3588.
-    m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str)
-    if not m:
-        warnings.warn(
-            "Expected glibc version with 2 components major.minor,"
-            " got: %s" % version_str,
-            RuntimeWarning,
-        )
-        return False
-    return (
-        int(m.group("major")) == required_major
-        and int(m.group("minor")) >= minimum_minor
-    )
-
-
-def _have_compatible_glibc(required_major, minimum_minor):
-    version_str = _glibc_version_string()
-    if version_str is None:
-        return False
-    return _check_glibc_version(version_str, required_major, minimum_minor)
-
-
-def _linux_platforms(is_32bit=_32_BIT_INTERPRETER):
-    linux = _normalize_string(distutils.util.get_platform())
-    if linux == "linux_x86_64" and is_32bit:
-        linux = "linux_i686"
-    manylinux_support = (
-        ("manylinux2014", (2, 17)),  # CentOS 7 w/ glibc 2.17 (PEP 599)
-        ("manylinux2010", (2, 12)),  # CentOS 6 w/ glibc 2.12 (PEP 571)
-        ("manylinux1", (2, 5)),  # CentOS 5 w/ glibc 2.5 (PEP 513)
-    )
-    manylinux_support_iter = iter(manylinux_support)
-    for name, glibc_version in manylinux_support_iter:
-        if _is_manylinux_compatible(name, glibc_version):
-            platforms = [linux.replace("linux", name)]
-            break
-    else:
-        platforms = []
-    # Support for a later manylinux implies support for an earlier version.
-    platforms += [linux.replace("linux", name) for name, _ in manylinux_support_iter]
-    platforms.append(linux)
-    return platforms
-
-
-def _generic_platforms():
-    platform = _normalize_string(distutils.util.get_platform())
-    return [platform]
-
-
-def _interpreter_name():
-    name = platform.python_implementation().lower()
-    return INTERPRETER_SHORT_NAMES.get(name) or name
-
-
-def _generic_interpreter(name, py_version):
-    version = sysconfig.get_config_var("py_version_nodot")
-    if not version:
-        version = "".join(map(str, py_version[:2]))
-    return "{name}{version}".format(name=name, version=version)
-
-
-def sys_tags():
-    """
-    Returns the sequence of tag triples for the running interpreter.
-
-    The order of the sequence corresponds to priority order for the
-    interpreter, from most to least important.
-    """
-    py_version = sys.version_info[:2]
-    interpreter_name = _interpreter_name()
-    if platform.system() == "Darwin":
-        platforms = _mac_platforms()
-    elif platform.system() == "Linux":
-        platforms = _linux_platforms()
-    else:
-        platforms = _generic_platforms()
-
-    if interpreter_name == "cp":
-        interpreter = _cpython_interpreter(py_version)
-        abis = _cpython_abis(py_version)
-        for tag in _cpython_tags(py_version, interpreter, abis, platforms):
-            yield tag
-    elif interpreter_name == "pp":
-        interpreter = _pypy_interpreter()
-        abi = _generic_abi()
-        for tag in _pypy_tags(py_version, interpreter, abi, platforms):
-            yield tag
-    else:
-        interpreter = _generic_interpreter(interpreter_name, py_version)
-        abi = _generic_abi()
-        for tag in _generic_tags(interpreter, py_version, abi, platforms):
-            yield tag
-    for tag in _independent_tags(interpreter, py_version, platforms):
-        yield tag
diff --git a/setuptools/_vendor/packaging/utils.py b/setuptools/_vendor/packaging/utils.py
index 884187869..942387cef 100644
--- a/setuptools/_vendor/packaging/utils.py
+++ b/setuptools/_vendor/packaging/utils.py
@@ -5,8 +5,6 @@ from __future__ import absolute_import, division, print_function
 
 import re
 
-from .version import InvalidVersion, Version
-
 
 _canonicalize_regex = re.compile(r"[-_.]+")
 
@@ -14,44 +12,3 @@ _canonicalize_regex = re.compile(r"[-_.]+")
 def canonicalize_name(name):
     # This is taken from PEP 503.
     return _canonicalize_regex.sub("-", name).lower()
-
-
-def canonicalize_version(version):
-    """
-    This is very similar to Version.__str__, but has one subtle differences
-    with the way it handles the release segment.
-    """
-
-    try:
-        version = Version(version)
-    except InvalidVersion:
-        # Legacy versions cannot be normalized
-        return version
-
-    parts = []
-
-    # Epoch
-    if version.epoch != 0:
-        parts.append("{0}!".format(version.epoch))
-
-    # Release segment
-    # NB: This strips trailing '.0's to normalize
-    parts.append(re.sub(r"(\.0)+$", "", ".".join(str(x) for x in version.release)))
-
-    # Pre-release
-    if version.pre is not None:
-        parts.append("".join(str(x) for x in version.pre))
-
-    # Post-release
-    if version.post is not None:
-        parts.append(".post{0}".format(version.post))
-
-    # Development release
-    if version.dev is not None:
-        parts.append(".dev{0}".format(version.dev))
-
-    # Local version segment
-    if version.local is not None:
-        parts.append("+{0}".format(version.local))
-
-    return "".join(parts)
diff --git a/setuptools/_vendor/packaging/version.py b/setuptools/_vendor/packaging/version.py
index 95157a1f7..83b5ee8c5 100644
--- a/setuptools/_vendor/packaging/version.py
+++ b/setuptools/_vendor/packaging/version.py
@@ -10,11 +10,14 @@ import re
 from ._structures import Infinity
 
 
-__all__ = ["parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"]
+__all__ = [
+    "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"
+]
 
 
 _Version = collections.namedtuple(
-    "_Version", ["epoch", "release", "dev", "pre", "post", "local"]
+    "_Version",
+    ["epoch", "release", "dev", "pre", "post", "local"],
 )
 
 
@@ -37,6 +40,7 @@ class InvalidVersion(ValueError):
 
 
 class _BaseVersion(object):
+
     def __hash__(self):
         return hash(self._key)
 
@@ -66,6 +70,7 @@ class _BaseVersion(object):
 
 
 class LegacyVersion(_BaseVersion):
+
     def __init__(self, version):
         self._version = str(version)
         self._key = _legacy_cmpkey(self._version)
@@ -84,26 +89,6 @@ class LegacyVersion(_BaseVersion):
     def base_version(self):
         return self._version
 
-    @property
-    def epoch(self):
-        return -1
-
-    @property
-    def release(self):
-        return None
-
-    @property
-    def pre(self):
-        return None
-
-    @property
-    def post(self):
-        return None
-
-    @property
-    def dev(self):
-        return None
-
     @property
     def local(self):
         return None
@@ -116,19 +101,13 @@ class LegacyVersion(_BaseVersion):
     def is_postrelease(self):
         return False
 
-    @property
-    def is_devrelease(self):
-        return False
 
-
-_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE)
+_legacy_version_component_re = re.compile(
+    r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE,
+)
 
 _legacy_version_replacement_map = {
-    "pre": "c",
-    "preview": "c",
-    "-": "final-",
-    "rc": "c",
-    "dev": "@",
+    "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@",
 }
 
 
@@ -175,7 +154,6 @@ def _legacy_cmpkey(version):
 
     return epoch, parts
 
-
 # Deliberately not anchored to the start and end of the string, to make it
 # easier for 3rd party code to reuse
 VERSION_PATTERN = r"""
@@ -212,7 +190,10 @@ VERSION_PATTERN = r"""
 
 class Version(_BaseVersion):
 
-    _regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE)
+    _regex = re.compile(
+        r"^\s*" + VERSION_PATTERN + r"\s*$",
+        re.VERBOSE | re.IGNORECASE,
+    )
 
     def __init__(self, version):
         # Validate the version and parse it into pieces
@@ -224,11 +205,18 @@ class Version(_BaseVersion):
         self._version = _Version(
             epoch=int(match.group("epoch")) if match.group("epoch") else 0,
             release=tuple(int(i) for i in match.group("release").split(".")),
-            pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")),
+            pre=_parse_letter_version(
+                match.group("pre_l"),
+                match.group("pre_n"),
+            ),
             post=_parse_letter_version(
-                match.group("post_l"), match.group("post_n1") or match.group("post_n2")
+                match.group("post_l"),
+                match.group("post_n1") or match.group("post_n2"),
+            ),
+            dev=_parse_letter_version(
+                match.group("dev_l"),
+                match.group("dev_n"),
             ),
-            dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")),
             local=_parse_local_version(match.group("local")),
         )
 
@@ -249,57 +237,32 @@ class Version(_BaseVersion):
         parts = []
 
         # Epoch
-        if self.epoch != 0:
-            parts.append("{0}!".format(self.epoch))
+        if self._version.epoch != 0:
+            parts.append("{0}!".format(self._version.epoch))
 
         # Release segment
-        parts.append(".".join(str(x) for x in self.release))
+        parts.append(".".join(str(x) for x in self._version.release))
 
         # Pre-release
-        if self.pre is not None:
-            parts.append("".join(str(x) for x in self.pre))
+        if self._version.pre is not None:
+            parts.append("".join(str(x) for x in self._version.pre))
 
         # Post-release
-        if self.post is not None:
-            parts.append(".post{0}".format(self.post))
+        if self._version.post is not None:
+            parts.append(".post{0}".format(self._version.post[1]))
 
         # Development release
-        if self.dev is not None:
-            parts.append(".dev{0}".format(self.dev))
+        if self._version.dev is not None:
+            parts.append(".dev{0}".format(self._version.dev[1]))
 
         # Local version segment
-        if self.local is not None:
-            parts.append("+{0}".format(self.local))
+        if self._version.local is not None:
+            parts.append(
+                "+{0}".format(".".join(str(x) for x in self._version.local))
+            )
 
         return "".join(parts)
 
-    @property
-    def epoch(self):
-        return self._version.epoch
-
-    @property
-    def release(self):
-        return self._version.release
-
-    @property
-    def pre(self):
-        return self._version.pre
-
-    @property
-    def post(self):
-        return self._version.post[1] if self._version.post else None
-
-    @property
-    def dev(self):
-        return self._version.dev[1] if self._version.dev else None
-
-    @property
-    def local(self):
-        if self._version.local:
-            return ".".join(str(x) for x in self._version.local)
-        else:
-            return None
-
     @property
     def public(self):
         return str(self).split("+", 1)[0]
@@ -309,25 +272,27 @@ class Version(_BaseVersion):
         parts = []
 
         # Epoch
-        if self.epoch != 0:
-            parts.append("{0}!".format(self.epoch))
+        if self._version.epoch != 0:
+            parts.append("{0}!".format(self._version.epoch))
 
         # Release segment
-        parts.append(".".join(str(x) for x in self.release))
+        parts.append(".".join(str(x) for x in self._version.release))
 
         return "".join(parts)
 
     @property
-    def is_prerelease(self):
-        return self.dev is not None or self.pre is not None
+    def local(self):
+        version_string = str(self)
+        if "+" in version_string:
+            return version_string.split("+", 1)[1]
 
     @property
-    def is_postrelease(self):
-        return self.post is not None
+    def is_prerelease(self):
+        return bool(self._version.dev or self._version.pre)
 
     @property
-    def is_devrelease(self):
-        return self.dev is not None
+    def is_postrelease(self):
+        return bool(self._version.post)
 
 
 def _parse_letter_version(letter, number):
@@ -361,7 +326,7 @@ def _parse_letter_version(letter, number):
         return letter, int(number)
 
 
-_local_version_separators = re.compile(r"[\._-]")
+_local_version_seperators = re.compile(r"[\._-]")
 
 
 def _parse_local_version(local):
@@ -371,7 +336,7 @@ def _parse_local_version(local):
     if local is not None:
         return tuple(
             part.lower() if not part.isdigit() else int(part)
-            for part in _local_version_separators.split(local)
+            for part in _local_version_seperators.split(local)
         )
 
 
@@ -382,7 +347,12 @@ def _cmpkey(epoch, release, pre, post, dev, local):
     # re-reverse it back into the correct order and make it a tuple and use
     # that for our sorting key.
     release = tuple(
-        reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release))))
+        reversed(list(
+            itertools.dropwhile(
+                lambda x: x == 0,
+                reversed(release),
+            )
+        ))
     )
 
     # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
@@ -415,6 +385,9 @@ def _cmpkey(epoch, release, pre, post, dev, local):
         # - Numeric segments sort numerically
         # - Shorter versions sort before longer versions when the prefixes
         #   match exactly
-        local = tuple((i, "") if isinstance(i, int) else (-Infinity, i) for i in local)
+        local = tuple(
+            (i, "") if isinstance(i, int) else (-Infinity, i)
+            for i in local
+        )
 
     return epoch, release, pre, post, dev, local
diff --git a/setuptools/_vendor/vendored.txt b/setuptools/_vendor/vendored.txt
index 65183d9a2..5731b4244 100644
--- a/setuptools/_vendor/vendored.txt
+++ b/setuptools/_vendor/vendored.txt
@@ -1,4 +1,4 @@
-packaging==19.2
+packaging==16.8
 pyparsing==2.2.1
 six==1.10.0
 ordered-set==3.1.1
diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py
index d273bc101..09066f8c8 100644
--- a/setuptools/command/easy_install.py
+++ b/setuptools/command/easy_install.py
@@ -73,7 +73,7 @@ warnings.filterwarnings("default", category=pkg_resources.PEP440Warning)
 
 __all__ = [
     'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg',
-    'get_exe_prefixes',
+    'main', 'get_exe_prefixes',
 ]
 
 
@@ -2289,6 +2289,59 @@ def current_umask():
     return tmp
 
 
+def bootstrap():
+    # This function is called when setuptools*.egg is run using /bin/sh
+    import setuptools
+
+    argv0 = os.path.dirname(setuptools.__path__[0])
+    sys.argv[0] = argv0
+    sys.argv.append(argv0)
+    main()
+
+
+def main(argv=None, **kw):
+    from setuptools import setup
+    from setuptools.dist import Distribution
+
+    class DistributionWithoutHelpCommands(Distribution):
+        common_usage = ""
+
+        def _show_help(self, *args, **kw):
+            with _patch_usage():
+                Distribution._show_help(self, *args, **kw)
+
+    if argv is None:
+        argv = sys.argv[1:]
+
+    with _patch_usage():
+        setup(
+            script_args=['-q', 'easy_install', '-v'] + argv,
+            script_name=sys.argv[0] or 'easy_install',
+            distclass=DistributionWithoutHelpCommands,
+            **kw
+        )
+
+
+@contextlib.contextmanager
+def _patch_usage():
+    import distutils.core
+    USAGE = textwrap.dedent("""
+        usage: %(script)s [options] requirement_or_url ...
+           or: %(script)s --help
+        """).lstrip()
+
+    def gen_usage(script_name):
+        return USAGE % dict(
+            script=os.path.basename(script_name),
+        )
+
+    saved = distutils.core.gen_usage
+    distutils.core.gen_usage = gen_usage
+    try:
+        yield
+    finally:
+        distutils.core.gen_usage = saved
+
 class EasyInstallDeprecationWarning(SetuptoolsDeprecationWarning):
     """Class for warning about deprecations in EasyInstall in SetupTools. Not ignored by default, unlike DeprecationWarning."""
     
diff --git a/setuptools/glibc.py b/setuptools/glibc.py
new file mode 100644
index 000000000..a134591c3
--- /dev/null
+++ b/setuptools/glibc.py
@@ -0,0 +1,86 @@
+# This file originally from pip:
+# https://github.com/pypa/pip/blob/8f4f15a5a95d7d5b511ceaee9ed261176c181970/src/pip/_internal/utils/glibc.py
+from __future__ import absolute_import
+
+import ctypes
+import re
+import warnings
+
+
+def glibc_version_string():
+    "Returns glibc version string, or None if not using glibc."
+
+    # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
+    # manpage says, "If filename is NULL, then the returned handle is for the
+    # main program". This way we can let the linker do the work to figure out
+    # which libc our process is actually using.
+    process_namespace = ctypes.CDLL(None)
+    try:
+        gnu_get_libc_version = process_namespace.gnu_get_libc_version
+    except AttributeError:
+        # Symbol doesn't exist -> therefore, we are not linked to
+        # glibc.
+        return None
+
+    # Call gnu_get_libc_version, which returns a string like "2.5"
+    gnu_get_libc_version.restype = ctypes.c_char_p
+    version_str = gnu_get_libc_version()
+    # py2 / py3 compatibility:
+    if not isinstance(version_str, str):
+        version_str = version_str.decode("ascii")
+
+    return version_str
+
+
+# Separated out from have_compatible_glibc for easier unit testing
+def check_glibc_version(version_str, required_major, minimum_minor):
+    # Parse string and check against requested version.
+    #
+    # We use a regexp instead of str.split because we want to discard any
+    # random junk that might come after the minor version -- this might happen
+    # in patched/forked versions of glibc (e.g. Linaro's version of glibc
+    # uses version strings like "2.20-2014.11"). See gh-3588.
+    m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str)
+    if not m:
+        warnings.warn("Expected glibc version with 2 components major.minor,"
+                      " got: %s" % version_str, RuntimeWarning)
+        return False
+    return (int(m.group("major")) == required_major and
+            int(m.group("minor")) >= minimum_minor)
+
+
+def have_compatible_glibc(required_major, minimum_minor):
+    version_str = glibc_version_string()
+    if version_str is None:
+        return False
+    return check_glibc_version(version_str, required_major, minimum_minor)
+
+
+# platform.libc_ver regularly returns completely nonsensical glibc
+# versions. E.g. on my computer, platform says:
+#
+#   ~$ python2.7 -c 'import platform; print(platform.libc_ver())'
+#   ('glibc', '2.7')
+#   ~$ python3.5 -c 'import platform; print(platform.libc_ver())'
+#   ('glibc', '2.9')
+#
+# But the truth is:
+#
+#   ~$ ldd --version
+#   ldd (Debian GLIBC 2.22-11) 2.22
+#
+# This is unfortunate, because it means that the linehaul data on libc
+# versions that was generated by pip 8.1.2 and earlier is useless and
+# misleading. Solution: instead of using platform, use our code that actually
+# works.
+def libc_ver():
+    """Try to determine the glibc version
+
+    Returns a tuple of strings (lib, version) which default to empty strings
+    in case the lookup fails.
+    """
+    glibc_version = glibc_version_string()
+    if glibc_version is None:
+        return ("", "")
+    else:
+        return ("glibc", glibc_version)
diff --git a/setuptools/pep425tags.py b/setuptools/pep425tags.py
new file mode 100644
index 000000000..48745a290
--- /dev/null
+++ b/setuptools/pep425tags.py
@@ -0,0 +1,319 @@
+# This file originally from pip:
+# https://github.com/pypa/pip/blob/8f4f15a5a95d7d5b511ceaee9ed261176c181970/src/pip/_internal/pep425tags.py
+"""Generate and work with PEP 425 Compatibility Tags."""
+from __future__ import absolute_import
+
+import distutils.util
+from distutils import log
+import platform
+import re
+import sys
+import sysconfig
+import warnings
+from collections import OrderedDict
+
+from .extern import six
+
+from . import glibc
+
+_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)')
+
+
+def get_config_var(var):
+    try:
+        return sysconfig.get_config_var(var)
+    except IOError as e:  # Issue #1074
+        warnings.warn("{}".format(e), RuntimeWarning)
+        return None
+
+
+def get_abbr_impl():
+    """Return abbreviated implementation name."""
+    if hasattr(sys, 'pypy_version_info'):
+        pyimpl = 'pp'
+    elif sys.platform.startswith('java'):
+        pyimpl = 'jy'
+    elif sys.platform == 'cli':
+        pyimpl = 'ip'
+    else:
+        pyimpl = 'cp'
+    return pyimpl
+
+
+def get_impl_ver():
+    """Return implementation version."""
+    impl_ver = get_config_var("py_version_nodot")
+    if not impl_ver or get_abbr_impl() == 'pp':
+        impl_ver = ''.join(map(str, get_impl_version_info()))
+    return impl_ver
+
+
+def get_impl_version_info():
+    """Return sys.version_info-like tuple for use in decrementing the minor
+    version."""
+    if get_abbr_impl() == 'pp':
+        # as per https://github.com/pypa/pip/issues/2882
+        return (sys.version_info[0], sys.pypy_version_info.major,
+                sys.pypy_version_info.minor)
+    else:
+        return sys.version_info[0], sys.version_info[1]
+
+
+def get_impl_tag():
+    """
+    Returns the Tag for this specific implementation.
+    """
+    return "{}{}".format(get_abbr_impl(), get_impl_ver())
+
+
+def get_flag(var, fallback, expected=True, warn=True):
+    """Use a fallback method for determining SOABI flags if the needed config
+    var is unset or unavailable."""
+    val = get_config_var(var)
+    if val is None:
+        if warn:
+            log.debug("Config variable '%s' is unset, Python ABI tag may "
+                      "be incorrect", var)
+        return fallback()
+    return val == expected
+
+
+def get_abi_tag():
+    """Return the ABI tag based on SOABI (if available) or emulate SOABI
+    (CPython 2, PyPy)."""
+    soabi = get_config_var('SOABI')
+    impl = get_abbr_impl()
+    if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'):
+        d = ''
+        m = ''
+        u = ''
+        if get_flag('Py_DEBUG',
+                    lambda: hasattr(sys, 'gettotalrefcount'),
+                    warn=(impl == 'cp')):
+            d = 'd'
+        if get_flag('WITH_PYMALLOC',
+                    lambda: impl == 'cp',
+                    warn=(impl == 'cp')):
+            m = 'm'
+        if get_flag('Py_UNICODE_SIZE',
+                    lambda: sys.maxunicode == 0x10ffff,
+                    expected=4,
+                    warn=(impl == 'cp' and
+                          six.PY2)) \
+                and six.PY2:
+            u = 'u'
+        abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u)
+    elif soabi and soabi.startswith('cpython-'):
+        abi = 'cp' + soabi.split('-')[1]
+    elif soabi:
+        abi = soabi.replace('.', '_').replace('-', '_')
+    else:
+        abi = None
+    return abi
+
+
+def _is_running_32bit():
+    return sys.maxsize == 2147483647
+
+
+def get_platform():
+    """Return our platform name 'win32', 'linux_x86_64'"""
+    if sys.platform == 'darwin':
+        # distutils.util.get_platform() returns the release based on the value
+        # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may
+        # be significantly older than the user's current machine.
+        release, _, machine = platform.mac_ver()
+        split_ver = release.split('.')
+
+        if machine == "x86_64" and _is_running_32bit():
+            machine = "i386"
+        elif machine == "ppc64" and _is_running_32bit():
+            machine = "ppc"
+
+        return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine)
+
+    # XXX remove distutils dependency
+    result = distutils.util.get_platform().replace('.', '_').replace('-', '_')
+    if result == "linux_x86_64" and _is_running_32bit():
+        # 32 bit Python program (running on a 64 bit Linux): pip should only
+        # install and run 32 bit compiled extensions in that case.
+        result = "linux_i686"
+
+    return result
+
+
+def is_manylinux1_compatible():
+    # Only Linux, and only x86-64 / i686
+    if get_platform() not in {"linux_x86_64", "linux_i686"}:
+        return False
+
+    # Check for presence of _manylinux module
+    try:
+        import _manylinux
+        return bool(_manylinux.manylinux1_compatible)
+    except (ImportError, AttributeError):
+        # Fall through to heuristic check below
+        pass
+
+    # Check glibc version. CentOS 5 uses glibc 2.5.
+    return glibc.have_compatible_glibc(2, 5)
+
+
+def get_darwin_arches(major, minor, machine):
+    """Return a list of supported arches (including group arches) for
+    the given major, minor and machine architecture of a macOS machine.
+    """
+    arches = []
+
+    def _supports_arch(major, minor, arch):
+        # Looking at the application support for macOS versions in the chart
+        # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears
+        # our timeline looks roughly like:
+        #
+        # 10.0 - Introduces ppc support.
+        # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64
+        #        and x86_64 support is CLI only, and cannot be used for GUI
+        #        applications.
+        # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications.
+        # 10.6 - Drops support for ppc64
+        # 10.7 - Drops support for ppc
+        #
+        # Given that we do not know if we're installing a CLI or a GUI
+        # application, we must be conservative and assume it might be a GUI
+        # application and behave as if ppc64 and x86_64 support did not occur
+        # until 10.5.
+        #
+        # Note: The above information is taken from the "Application support"
+        #       column in the chart not the "Processor support" since I believe
+        #       that we care about what instruction sets an application can use
+        #       not which processors the OS supports.
+        if arch == 'ppc':
+            return (major, minor) <= (10, 5)
+        if arch == 'ppc64':
+            return (major, minor) == (10, 5)
+        if arch == 'i386':
+            return (major, minor) >= (10, 4)
+        if arch == 'x86_64':
+            return (major, minor) >= (10, 5)
+        if arch in groups:
+            for garch in groups[arch]:
+                if _supports_arch(major, minor, garch):
+                    return True
+        return False
+
+    groups = OrderedDict([
+        ("fat", ("i386", "ppc")),
+        ("intel", ("x86_64", "i386")),
+        ("fat64", ("x86_64", "ppc64")),
+        ("fat32", ("x86_64", "i386", "ppc")),
+    ])
+
+    if _supports_arch(major, minor, machine):
+        arches.append(machine)
+
+    for garch in groups:
+        if machine in groups[garch] and _supports_arch(major, minor, garch):
+            arches.append(garch)
+
+    arches.append('universal')
+
+    return arches
+
+
+def get_supported(versions=None, noarch=False, platform=None,
+                  impl=None, abi=None):
+    """Return a list of supported tags for each version specified in
+    `versions`.
+
+    :param versions: a list of string versions, of the form ["33", "32"],
+        or None. The first version will be assumed to support our ABI.
+    :param platform: specify the exact platform you want valid
+        tags for, or None. If None, use the local system platform.
+    :param impl: specify the exact implementation you want valid
+        tags for, or None. If None, use the local interpreter impl.
+    :param abi: specify the exact abi you want valid
+        tags for, or None. If None, use the local interpreter abi.
+    """
+    supported = []
+
+    # Versions must be given with respect to the preference
+    if versions is None:
+        versions = []
+        version_info = get_impl_version_info()
+        major = version_info[:-1]
+        # Support all previous minor Python versions.
+        for minor in range(version_info[-1], -1, -1):
+            versions.append(''.join(map(str, major + (minor,))))
+
+    impl = impl or get_abbr_impl()
+
+    abis = []
+
+    abi = abi or get_abi_tag()
+    if abi:
+        abis[0:0] = [abi]
+
+    abi3s = set()
+    import imp
+    for suffix in imp.get_suffixes():
+        if suffix[0].startswith('.abi'):
+            abi3s.add(suffix[0].split('.', 2)[1])
+
+    abis.extend(sorted(list(abi3s)))
+
+    abis.append('none')
+
+    if not noarch:
+        arch = platform or get_platform()
+        if arch.startswith('macosx'):
+            # support macosx-10.6-intel on macosx-10.9-x86_64
+            match = _osx_arch_pat.match(arch)
+            if match:
+                name, major, minor, actual_arch = match.groups()
+                tpl = '{}_{}_%i_%s'.format(name, major)
+                arches = []
+                for m in reversed(range(int(minor) + 1)):
+                    for a in get_darwin_arches(int(major), m, actual_arch):
+                        arches.append(tpl % (m, a))
+            else:
+                # arch pattern didn't match (?!)
+                arches = [arch]
+        elif platform is None and is_manylinux1_compatible():
+            arches = [arch.replace('linux', 'manylinux1'), arch]
+        else:
+            arches = [arch]
+
+        # Current version, current API (built specifically for our Python):
+        for abi in abis:
+            for arch in arches:
+                supported.append(('%s%s' % (impl, versions[0]), abi, arch))
+
+        # abi3 modules compatible with older version of Python
+        for version in versions[1:]:
+            # abi3 was introduced in Python 3.2
+            if version in {'31', '30'}:
+                break
+            for abi in abi3s:   # empty set if not Python 3
+                for arch in arches:
+                    supported.append(("%s%s" % (impl, version), abi, arch))
+
+        # Has binaries, does not use the Python API:
+        for arch in arches:
+            supported.append(('py%s' % (versions[0][0]), 'none', arch))
+
+    # No abi / arch, but requires our implementation:
+    supported.append(('%s%s' % (impl, versions[0]), 'none', 'any'))
+    # Tagged specifically as being cross-version compatible
+    # (with just the major version specified)
+    supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any'))
+
+    # No abi / arch, generic Python
+    for i, version in enumerate(versions):
+        supported.append(('py%s' % (version,), 'none', 'any'))
+        if i == 0:
+            supported.append(('py%s' % (version[0]), 'none', 'any'))
+
+    return supported
+
+
+implementation_tag = get_impl_tag()
diff --git a/setuptools/wheel.py b/setuptools/wheel.py
index 3effd79b3..22eec05ec 100644
--- a/setuptools/wheel.py
+++ b/setuptools/wheel.py
@@ -12,9 +12,9 @@ import zipfile
 import pkg_resources
 import setuptools
 from pkg_resources import parse_version
-from setuptools.extern.packaging.tags import sys_tags
 from setuptools.extern.packaging.utils import canonicalize_name
 from setuptools.extern.six import PY3
+from setuptools import pep425tags
 from setuptools.command.egg_info import write_requirements
 
 
@@ -77,7 +77,7 @@ class Wheel:
 
     def is_compatible(self):
         '''Is the wheel is compatible with the current platform?'''
-        supported_tags = set(map(str, sys_tags()))
+        supported_tags = pep425tags.get_supported()
         return next((True for t in self.tags() if t in supported_tags), False)
 
     def egg_name(self):


Test patch:
diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py
index 68319c2fb..aa75899a0 100644
--- a/setuptools/tests/test_easy_install.py
+++ b/setuptools/tests/test_easy_install.py
@@ -467,24 +467,22 @@ class TestSetupRequires:
         """
         monkeypatch.setenv(str('PIP_RETRIES'), str('0'))
         monkeypatch.setenv(str('PIP_TIMEOUT'), str('0'))
-        monkeypatch.setenv(str('PIP_VERBOSE'), str('1'))
-        # create an sdist that has a build-time dependency.
-        with TestSetupRequires.create_sdist() as dist_file:
-            with contexts.tempdir() as temp_dir:
-                setup_py = os.path.join(temp_dir, 'setup.py')
-                with open(setup_py, 'w') as fp:
-                    fp.write('__import__("setuptools").setup()')
-                temp_install_dir = os.path.join(temp_dir, 'target')
-                os.mkdir(temp_install_dir)
-                with contexts.environment(PYTHONPATH=temp_install_dir):
-                    # attempt to install the dist. It should
-                    # fail because it doesn't exist.
-                    with pytest.raises(SystemExit):
-                        run_setup(setup_py, ['easy_install',
-                                             '--exclude-scripts',
-                                             '--index-url', mock_index.url,
-                                             '--install-dir', temp_install_dir,
-                                             dist_file])
+        with contexts.quiet():
+            # create an sdist that has a build-time dependency.
+            with TestSetupRequires.create_sdist() as dist_file:
+                with contexts.tempdir() as temp_install_dir:
+                    with contexts.environment(PYTHONPATH=temp_install_dir):
+                        ei_params = [
+                            '--index-url', mock_index.url,
+                            '--exclude-scripts',
+                            '--install-dir', temp_install_dir,
+                            dist_file,
+                        ]
+                        with sandbox.save_argv(['easy_install']):
+                            # attempt to install the dist. It should
+                            # fail because it doesn't exist.
+                            with pytest.raises(SystemExit):
+                                easy_install_pkg.main(ei_params)
         # there should have been one requests to the server
         assert [r.path for r in mock_index.requests] == ['/does-not-exist/']
 
diff --git a/setuptools/tests/test_glibc.py b/setuptools/tests/test_glibc.py
new file mode 100644
index 000000000..795fdc566
--- /dev/null
+++ b/setuptools/tests/test_glibc.py
@@ -0,0 +1,52 @@
+import warnings
+
+import pytest
+
+from setuptools.glibc import check_glibc_version
+
+__metaclass__ = type
+
+
+@pytest.fixture(params=[
+    "2.20",
+    # used by "linaro glibc", see gh-3588
+    "2.20-2014.11",
+    # weird possibilities that I just made up
+    "2.20+dev",
+    "2.20-custom",
+    "2.20.1",
+    ])
+def two_twenty(request):
+    return request.param
+
+
+@pytest.fixture(params=["asdf", "", "foo.bar"])
+def bad_string(request):
+    return request.param
+
+
+class TestGlibc:
+    def test_manylinux1_check_glibc_version(self, two_twenty):
+        """
+        Test that the check_glibc_version function is robust against weird
+        glibc version strings.
+        """
+        assert check_glibc_version(two_twenty, 2, 15)
+        assert check_glibc_version(two_twenty, 2, 20)
+        assert not check_glibc_version(two_twenty, 2, 21)
+        assert not check_glibc_version(two_twenty, 3, 15)
+        assert not check_glibc_version(two_twenty, 1, 15)
+
+    def test_bad_versions(self, bad_string):
+        """
+        For unparseable strings, warn and return False
+        """
+        with warnings.catch_warnings(record=True) as ws:
+            warnings.filterwarnings("always")
+            assert not check_glibc_version(bad_string, 2, 5)
+            for w in ws:
+                if "Expected glibc version with" in str(w.message):
+                    break
+            else:
+                # Didn't find the warning we were expecting
+                assert False
diff --git a/setuptools/tests/test_namespaces.py b/setuptools/tests/test_namespaces.py
index 3c5df68a3..f937d9818 100644
--- a/setuptools/tests/test_namespaces.py
+++ b/setuptools/tests/test_namespaces.py
@@ -64,8 +64,9 @@ class TestNamespaces:
         target.mkdir()
         install_cmd = [
             sys.executable,
-            '-m', 'pip.__main__', 'install',
-            '-t', str(target), str(pkg),
+            '-m', 'easy_install',
+            '-d', str(target),
+            str(pkg),
         ]
         with test.test.paths_on_pythonpath([str(target)]):
             subprocess.check_call(install_cmd)
diff --git a/setuptools/tests/test_pep425tags.py b/setuptools/tests/test_pep425tags.py
new file mode 100644
index 000000000..30afdec7d
--- /dev/null
+++ b/setuptools/tests/test_pep425tags.py
@@ -0,0 +1,170 @@
+import sys
+
+import pytest
+from mock import patch
+
+from setuptools import pep425tags
+
+__metaclass__ = type
+
+
+class TestPEP425Tags:
+
+    def mock_get_config_var(self, **kwd):
+        """
+        Patch sysconfig.get_config_var for arbitrary keys.
+        """
+        get_config_var = pep425tags.sysconfig.get_config_var
+
+        def _mock_get_config_var(var):
+            if var in kwd:
+                return kwd[var]
+            return get_config_var(var)
+        return _mock_get_config_var
+
+    def abi_tag_unicode(self, flags, config_vars):
+        """
+        Used to test ABI tags, verify correct use of the `u` flag
+        """
+        config_vars.update({'SOABI': None})
+        base = pep425tags.get_abbr_impl() + pep425tags.get_impl_ver()
+
+        if sys.version_info < (3, 3):
+            config_vars.update({'Py_UNICODE_SIZE': 2})
+            mock_gcf = self.mock_get_config_var(**config_vars)
+            with patch(
+                    'setuptools.pep425tags.sysconfig.get_config_var',
+                    mock_gcf):
+                abi_tag = pep425tags.get_abi_tag()
+                assert abi_tag == base + flags
+
+            config_vars.update({'Py_UNICODE_SIZE': 4})
+            mock_gcf = self.mock_get_config_var(**config_vars)
+            with patch('setuptools.pep425tags.sysconfig.get_config_var',
+                       mock_gcf):
+                abi_tag = pep425tags.get_abi_tag()
+                assert abi_tag == base + flags + 'u'
+
+        else:
+            # On Python >= 3.3, UCS-4 is essentially permanently enabled, and
+            # Py_UNICODE_SIZE is None. SOABI on these builds does not include
+            # the 'u' so manual SOABI detection should not do so either.
+            config_vars.update({'Py_UNICODE_SIZE': None})
+            mock_gcf = self.mock_get_config_var(**config_vars)
+            with patch('setuptools.pep425tags.sysconfig.get_config_var',
+                       mock_gcf):
+                abi_tag = pep425tags.get_abi_tag()
+                assert abi_tag == base + flags
+
+    def test_broken_sysconfig(self):
+        """
+        Test that pep425tags still works when sysconfig is broken.
+        Can be a problem on Python 2.7
+        Issue #1074.
+        """
+        def raises_ioerror(var):
+            raise IOError("I have the wrong path!")
+
+        with patch('setuptools.pep425tags.sysconfig.get_config_var',
+                   raises_ioerror):
+            with pytest.warns(RuntimeWarning):
+                assert len(pep425tags.get_supported())
+
+    def test_no_hyphen_tag(self):
+        """
+        Test that no tag contains a hyphen.
+        """
+        mock_gcf = self.mock_get_config_var(SOABI='cpython-35m-darwin')
+
+        with patch('setuptools.pep425tags.sysconfig.get_config_var',
+                   mock_gcf):
+            supported = pep425tags.get_supported()
+
+        for (py, abi, plat) in supported:
+            assert '-' not in py
+            assert '-' not in abi
+            assert '-' not in plat
+
+    def test_manual_abi_noflags(self):
+        """
+        Test that no flags are set on a non-PyDebug, non-Pymalloc ABI tag.
+        """
+        self.abi_tag_unicode('', {'Py_DEBUG': False, 'WITH_PYMALLOC': False})
+
+    def test_manual_abi_d_flag(self):
+        """
+        Test that the `d` flag is set on a PyDebug, non-Pymalloc ABI tag.
+        """
+        self.abi_tag_unicode('d', {'Py_DEBUG': True, 'WITH_PYMALLOC': False})
+
+    def test_manual_abi_m_flag(self):
+        """
+        Test that the `m` flag is set on a non-PyDebug, Pymalloc ABI tag.
+        """
+        self.abi_tag_unicode('m', {'Py_DEBUG': False, 'WITH_PYMALLOC': True})
+
+    def test_manual_abi_dm_flags(self):
+        """
+        Test that the `dm` flags are set on a PyDebug, Pymalloc ABI tag.
+        """
+        self.abi_tag_unicode('dm', {'Py_DEBUG': True, 'WITH_PYMALLOC': True})
+
+
+class TestManylinux1Tags:
+
+    @patch('setuptools.pep425tags.get_platform', lambda: 'linux_x86_64')
+    @patch('setuptools.glibc.have_compatible_glibc',
+           lambda major, minor: True)
+    def test_manylinux1_compatible_on_linux_x86_64(self):
+        """
+        Test that manylinux1 is enabled on linux_x86_64
+        """
+        assert pep425tags.is_manylinux1_compatible()
+
+    @patch('setuptools.pep425tags.get_platform', lambda: 'linux_i686')
+    @patch('setuptools.glibc.have_compatible_glibc',
+           lambda major, minor: True)
+    def test_manylinux1_compatible_on_linux_i686(self):
+        """
+        Test that manylinux1 is enabled on linux_i686
+        """
+        assert pep425tags.is_manylinux1_compatible()
+
+    @patch('setuptools.pep425tags.get_platform', lambda: 'linux_x86_64')
+    @patch('setuptools.glibc.have_compatible_glibc',
+           lambda major, minor: False)
+    def test_manylinux1_2(self):
+        """
+        Test that manylinux1 is disabled with incompatible glibc
+        """
+        assert not pep425tags.is_manylinux1_compatible()
+
+    @patch('setuptools.pep425tags.get_platform', lambda: 'arm6vl')
+    @patch('setuptools.glibc.have_compatible_glibc',
+           lambda major, minor: True)
+    def test_manylinux1_3(self):
+        """
+        Test that manylinux1 is disabled on arm6vl
+        """
+        assert not pep425tags.is_manylinux1_compatible()
+
+    @patch('setuptools.pep425tags.get_platform', lambda: 'linux_x86_64')
+    @patch('setuptools.glibc.have_compatible_glibc',
+           lambda major, minor: True)
+    @patch('sys.platform', 'linux2')
+    def test_manylinux1_tag_is_first(self):
+        """
+        Test that the more specific tag manylinux1 comes first.
+        """
+        groups = {}
+        for pyimpl, abi, arch in pep425tags.get_supported():
+            groups.setdefault((pyimpl, abi), []).append(arch)
+
+        for arches in groups.values():
+            if arches == ['any']:
+                continue
+            # Expect the most specific arch first:
+            if len(arches) == 3:
+                assert arches == ['manylinux1_x86_64', 'linux_x86_64', 'any']
+            else:
+                assert arches == ['manylinux1_x86_64', 'linux_x86_64']