From 84c9006110e53c84296a05741edb7b9edd305f12 Mon Sep 17 00:00:00 2001 From: Donald Stufft Date: Thu, 4 Sep 2014 20:27:48 -0400 Subject: Add a vendored copy of packaging --- Makefile | 7 + setuptools/_vendor/packaging/__about__.py | 31 ++ setuptools/_vendor/packaging/__init__.py | 24 + setuptools/_vendor/packaging/_compat.py | 27 + setuptools/_vendor/packaging/_structures.py | 78 +++ setuptools/_vendor/packaging/version.py | 786 ++++++++++++++++++++++++++++ setuptools/_vendor/vendored.txt | 1 + 7 files changed, 954 insertions(+) create mode 100644 Makefile create mode 100644 setuptools/_vendor/packaging/__about__.py create mode 100644 setuptools/_vendor/packaging/__init__.py create mode 100644 setuptools/_vendor/packaging/_compat.py create mode 100644 setuptools/_vendor/packaging/_structures.py create mode 100644 setuptools/_vendor/packaging/version.py create mode 100644 setuptools/_vendor/vendored.txt diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..ab60b882 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +empty: + exit 1 + +update-vendored: + rm -rf setuptools/_vendor/packaging + pip install -r setuptools/_vendor/vendored.txt -t setuptools/_vendor/ + rm -rf setuptools/_vendor/*.{egg,dist}-info diff --git a/setuptools/_vendor/packaging/__about__.py b/setuptools/_vendor/packaging/__about__.py new file mode 100644 index 00000000..b64681e4 --- /dev/null +++ b/setuptools/_vendor/packaging/__about__.py @@ -0,0 +1,31 @@ +# Copyright 2014 Donald Stufft +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from __future__ import absolute_import, division, print_function + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] + +__title__ = "packaging" +__summary__ = "Core utilities for Python packages" +__uri__ = "https://github.com/pypa/packaging" + +__version__ = "14.2" + +__author__ = "Donald Stufft" +__email__ = "donald@stufft.io" + +__license__ = "Apache License, Version 2.0" +__copyright__ = "Copyright 2014 %s" % __author__ diff --git a/setuptools/_vendor/packaging/__init__.py b/setuptools/_vendor/packaging/__init__.py new file mode 100644 index 00000000..c39a8eab --- /dev/null +++ b/setuptools/_vendor/packaging/__init__.py @@ -0,0 +1,24 @@ +# Copyright 2014 Donald Stufft +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from __future__ import absolute_import, division, print_function + +from .__about__ import ( + __author__, __copyright__, __email__, __license__, __summary__, __title__, + __uri__, __version__ +) + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] diff --git a/setuptools/_vendor/packaging/_compat.py b/setuptools/_vendor/packaging/_compat.py new file mode 100644 index 00000000..f2ff3834 --- /dev/null +++ b/setuptools/_vendor/packaging/_compat.py @@ -0,0 +1,27 @@ +# Copyright 2014 Donald Stufft +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from __future__ import absolute_import, division, print_function + +import sys + + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +# flake8: noqa + +if PY3: + string_types = str, +else: + string_types = basestring, diff --git a/setuptools/_vendor/packaging/_structures.py b/setuptools/_vendor/packaging/_structures.py new file mode 100644 index 00000000..0ae9bb52 --- /dev/null +++ b/setuptools/_vendor/packaging/_structures.py @@ -0,0 +1,78 @@ +# Copyright 2014 Donald Stufft +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from __future__ import absolute_import, division, print_function + + +class Infinity(object): + + def __repr__(self): + return "Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return False + + def __le__(self, other): + return False + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return True + + def __ge__(self, other): + return True + + def __neg__(self): + return NegativeInfinity + +Infinity = Infinity() + + +class NegativeInfinity(object): + + def __repr__(self): + return "-Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return True + + def __le__(self, other): + return True + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return False + + def __ge__(self, other): + return False + + def __neg__(self): + return Infinity + +NegativeInfinity = NegativeInfinity() diff --git a/setuptools/_vendor/packaging/version.py b/setuptools/_vendor/packaging/version.py new file mode 100644 index 00000000..0affe899 --- /dev/null +++ b/setuptools/_vendor/packaging/version.py @@ -0,0 +1,786 @@ +# Copyright 2014 Donald Stufft +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from __future__ import absolute_import, division, print_function + +import collections +import itertools +import re + +from ._compat import string_types +from ._structures import Infinity + + +__all__ = [ + "parse", "Version", "LegacyVersion", "InvalidVersion", "Specifier", + "InvalidSpecifier", +] + + +_Version = collections.namedtuple( + "_Version", + ["epoch", "release", "dev", "pre", "post", "local"], +) + + +def parse(version): + """ + Parse the given version string and return either a :class:`Version` object + or a :class:`LegacyVersion` object depending on if the given version is + a valid PEP 440 version or a legacy version. + """ + try: + return Version(version) + except InvalidVersion: + return LegacyVersion(version) + + +class InvalidVersion(ValueError): + """ + An invalid version was found, users should refer to PEP 440. + """ + + +class _BaseVersion(object): + + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, _BaseVersion): + return NotImplemented + + return method(self._key, other._key) + + +class LegacyVersion(_BaseVersion): + + def __init__(self, version): + self._version = str(version) + self._key = _legacy_cmpkey(self._version) + + def __str__(self): + return self._version + + def __repr__(self): + return "".format(repr(str(self))) + + @property + def public(self): + return self._version + + @property + def local(self): + return None + + @property + def is_prerelease(self): + return False + + +_legacy_version_component_re = re.compile( + r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, +) + +_legacy_version_replacement_map = { + "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", +} + + +def _parse_version_parts(s): + for part in _legacy_version_component_re.split(s): + part = _legacy_version_replacement_map.get(part, part) + + if not part or part == ".": + continue + + if part[:1] in "0123456789": + # pad for numeric comparison + yield part.zfill(8) + else: + yield "*" + part + + # ensure that alpha/beta/candidate are before final + yield "*final" + + +def _legacy_cmpkey(version): + # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch + # greater than or equal to 0. This will effectively put the LegacyVersion, + # which uses the defacto standard originally implemented by setuptools, + # as before all PEP 440 versions. + epoch = -1 + + # This scheme is taken from pkg_resources.parse_version setuptools prior to + # it's adoption of the packaging library. + parts = [] + for part in _parse_version_parts(version.lower()): + if part.startswith("*"): + # remove "-" before a prerelease tag + if part < "*final": + while parts and parts[-1] == "*final-": + parts.pop() + + # remove trailing zeros from each series of numeric parts + while parts and parts[-1] == "00000000": + parts.pop() + + parts.append(part) + parts = tuple(parts) + + return epoch, parts + + +class Version(_BaseVersion): + + _regex = re.compile( + r""" + ^ + \s* + v? + (?: + (?:(?P[0-9]+)!)? # epoch + (?P[0-9]+(?:\.[0-9]+)*) # release segment + (?P
                                          # pre-release
+                [-_\.]?
+                (?P(a|b|c|rc|alpha|beta|pre|preview))
+                [-_\.]?
+                (?P[0-9]+)?
+            )?
+            (?P                                         # post release
+                (?:-(?P[0-9]+))
+                |
+                (?:
+                    [-_\.]?
+                    (?Ppost|rev|r)
+                    [-_\.]?
+                    (?P[0-9]+)?
+                )
+            )?
+            (?P                                          # dev release
+                [-_\.]?
+                (?Pdev)
+                [-_\.]?
+                (?P[0-9]+)?
+            )?
+        )
+        (?:\+(?P[a-z0-9]+(?:[-_\.][a-z0-9]+)*))?       # local version
+        \s*
+        $
+        """,
+        re.VERBOSE | re.IGNORECASE,
+    )
+
+    def __init__(self, version):
+        # Validate the version and parse it into pieces
+        match = self._regex.search(version)
+        if not match:
+            raise InvalidVersion("Invalid version: '{0}'".format(version))
+
+        # Store the parsed out pieces of the version
+        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"),
+            ),
+            post=_parse_letter_version(
+                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"),
+            ),
+            local=_parse_local_version(match.group("local")),
+        )
+
+        # Generate a key which will be used for sorting
+        self._key = _cmpkey(
+            self._version.epoch,
+            self._version.release,
+            self._version.pre,
+            self._version.post,
+            self._version.dev,
+            self._version.local,
+        )
+
+    def __repr__(self):
+        return "".format(repr(str(self)))
+
+    def __str__(self):
+        parts = []
+
+        # Epoch
+        if self._version.epoch != 0:
+            parts.append("{0}!".format(self._version.epoch))
+
+        # Release segment
+        parts.append(".".join(str(x) for x in self._version.release))
+
+        # Pre-release
+        if self._version.pre is not None:
+            parts.append("".join(str(x) for x in self._version.pre))
+
+        # Post-release
+        if self._version.post is not None:
+            parts.append(".post{0}".format(self._version.post[1]))
+
+        # Development release
+        if self._version.dev is not None:
+            parts.append(".dev{0}".format(self._version.dev[1]))
+
+        # Local version segment
+        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 public(self):
+        return str(self).split("+", 1)[0]
+
+    @property
+    def local(self):
+        version_string = str(self)
+        if "+" in version_string:
+            return version_string.split("+", 1)[1]
+
+    @property
+    def is_prerelease(self):
+        return bool(self._version.dev or self._version.pre)
+
+
+def _parse_letter_version(letter, number):
+    if letter:
+        # We consider there to be an implicit 0 in a pre-release if there is
+        # not a numeral associated with it.
+        if number is None:
+            number = 0
+
+        # We normalize any letters to their lower case form
+        letter = letter.lower()
+
+        # We consider some words to be alternate spellings of other words and
+        # in those cases we want to normalize the spellings to our preferred
+        # spelling.
+        if letter == "alpha":
+            letter = "a"
+        elif letter == "beta":
+            letter = "b"
+        elif letter in ["rc", "pre", "preview"]:
+            letter = "c"
+
+        return letter, int(number)
+    if not letter and number:
+        # We assume if we are given a number, but we are not given a letter
+        # then this is using the implicit post release syntax (e.g. 1.0-1)
+        letter = "post"
+
+        return letter, int(number)
+
+
+_local_version_seperators = re.compile(r"[\._-]")
+
+
+def _parse_local_version(local):
+    """
+    Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
+    """
+    if local is not None:
+        return tuple(
+            part.lower() if not part.isdigit() else int(part)
+            for part in _local_version_seperators.split(local)
+        )
+
+
+def _cmpkey(epoch, release, pre, post, dev, local):
+    # When we compare a release version, we want to compare it with all of the
+    # trailing zeros removed. So we'll use a reverse the list, drop all the now
+    # leading zeros until we come to something non zero, then take the rest
+    # 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),
+            )
+        ))
+    )
+
+    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
+    # We'll do this by abusing the pre segment, but we _only_ want to do this
+    # if there is not a pre or a post segment. If we have one of those then
+    # the normal sorting rules will handle this case correctly.
+    if pre is None and post is None and dev is not None:
+        pre = -Infinity
+    # Versions without a pre-release (except as noted above) should sort after
+    # those with one.
+    elif pre is None:
+        pre = Infinity
+
+    # Versions without a post segment should sort before those with one.
+    if post is None:
+        post = -Infinity
+
+    # Versions without a development segment should sort after those with one.
+    if dev is None:
+        dev = Infinity
+
+    if local is None:
+        # Versions without a local segment should sort before those with one.
+        local = -Infinity
+    else:
+        # Versions with a local segment need that segment parsed to implement
+        # the sorting rules in PEP440.
+        # - Alpha numeric segments sort before numeric segments
+        # - Alpha numeric segments sort lexicographically
+        # - 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
+        )
+
+    return epoch, release, pre, post, dev, local
+
+
+class InvalidSpecifier(ValueError):
+    """
+    An invalid specifier was found, users should refer to PEP 440.
+    """
+
+
+class Specifier(object):
+
+    _regex = re.compile(
+        r"""
+        ^
+        \s*
+        (?P(~=|==|!=|<=|>=|<|>|===))
+        (?P
+            (?:
+                # The identity operators allow for an escape hatch that will
+                # do an exact string match of the version you wish to install.
+                # This will not be parsed by PEP 440 and we cannot determine
+                # any semantic meaning from it. This operator is discouraged
+                # but included entirely as an escape hatch.
+                (?<====)  # Only match for the identity operator
+                \s*
+                [^\s]*    # We just match everything, except for whitespace
+                          # since we are only testing for strict identity.
+            )
+            |
+            (?:
+                # The (non)equality operators allow for wild card and local
+                # versions to be specified so we have to define these two
+                # operators separately to enable that.
+                (?<===|!=)            # Only match for equals and not equals
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)*   # release
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+
+                # You cannot use a wild card and a dev or local version
+                # together so group them with a | and make them optional.
+                (?:
+                    (?:[-_\.]?dev[-_\.]?[0-9]*)?         # dev release
+                    (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
+                    |
+                    \.\*  # Wild card syntax of .*
+                )?
+            )
+            |
+            (?:
+                # The compatible operator requires at least two digits in the
+                # release segment.
+                (?<=~=)               # Only match for the compatible operator
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)+   # release  (We have a + instead of a *)
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
+            )
+            |
+            (?:
+                # All other operators only allow a sub set of what the
+                # (non)equality operators do. Specifically they do not allow
+                # local versions to be specified nor do they allow the prefix
+                # matching wild cards.
+                (?=": "greater_than_equal",
+        "<": "less_than",
+        ">": "greater_than",
+        "===": "arbitrary",
+    }
+
+    def __init__(self, specs="", prereleases=None):
+        # Split on comma to get each individual specification
+        _specs = set()
+        for spec in (s for s in specs.split(",") if s):
+            match = self._regex.search(spec)
+            if not match:
+                raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
+
+            _specs.add(
+                (
+                    match.group("operator").strip(),
+                    match.group("version").strip(),
+                )
+            )
+
+        # Set a frozen set for our specifications
+        self._specs = frozenset(_specs)
+
+        # Store whether or not this Specifier should accept prereleases
+        self._prereleases = prereleases
+
+    def __repr__(self):
+        return "".format(repr(str(self)))
+
+    def __str__(self):
+        return ",".join(["".join(s) for s in sorted(self._specs)])
+
+    def __hash__(self):
+        return hash(self._specs)
+
+    def __and__(self, other):
+        if isinstance(other, string_types):
+            other = Specifier(other)
+        elif not isinstance(other, Specifier):
+            return NotImplemented
+
+        return self.__class__(",".join([str(self), str(other)]))
+
+    def __eq__(self, other):
+        if isinstance(other, string_types):
+            other = Specifier(other)
+        elif not isinstance(other, Specifier):
+            return NotImplemented
+
+        return self._specs == other._specs
+
+    def __ne__(self, other):
+        if isinstance(other, string_types):
+            other = Specifier(other)
+        elif not isinstance(other, Specifier):
+            return NotImplemented
+
+        return self._specs != other._specs
+
+    def _get_operator(self, op):
+        return getattr(self, "_compare_{0}".format(self._operators[op]))
+
+    def _compare_compatible(self, prospective, spec):
+        # Compatible releases have an equivalent combination of >= and ==. That
+        # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to
+        # implement this in terms of the other specifiers instead of
+        # implementing it ourselves. The only thing we need to do is construct
+        # the other specifiers.
+
+        # We want everything but the last item in the version, but we want to
+        # ignore post and dev releases and we want to treat the pre-release as
+        # it's own separate segment.
+        prefix = ".".join(
+            list(
+                itertools.takewhile(
+                    lambda x: (not x.startswith("post")
+                               and not x.startswith("dev")),
+                    _version_split(spec),
+                )
+            )[:-1]
+        )
+
+        # Add the prefix notation to the end of our string
+        prefix += ".*"
+
+        return (self._get_operator(">=")(prospective, spec)
+                and self._get_operator("==")(prospective, prefix))
+
+    def _compare_equal(self, prospective, spec):
+        # We need special logic to handle prefix matching
+        if spec.endswith(".*"):
+            # Split the spec out by dots, and pretend that there is an implicit
+            # dot in between a release segment and a pre-release segment.
+            spec = _version_split(spec[:-2])  # Remove the trailing .*
+
+            # Split the prospective version out by dots, and pretend that there
+            # is an implicit dot in between a release segment and a pre-release
+            # segment.
+            prospective = _version_split(str(prospective))
+
+            # 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)]
+
+            # Pad out our two sides with zeros so that they both equal the same
+            # length.
+            spec, prospective = _pad_version(spec, prospective)
+        else:
+            # Convert our spec string into a Version
+            spec = Version(spec)
+
+            # If the specifier does not have a local segment, then we want to
+            # act as if the prospective version also does not have a local
+            # segment.
+            if not spec.local:
+                prospective = Version(prospective.public)
+
+        return prospective == spec
+
+    def _compare_not_equal(self, prospective, spec):
+        return not self._compare_equal(prospective, spec)
+
+    def _compare_less_than_equal(self, prospective, spec):
+        return prospective <= Version(spec)
+
+    def _compare_greater_than_equal(self, prospective, spec):
+        return prospective >= Version(spec)
+
+    def _compare_less_than(self, prospective, spec):
+        # Less than are defined as exclusive operators, this implies that
+        # pre-releases do not match for the same series as the spec. This is
+        # implemented by making V imply !=V.*.
+        return (prospective > Version(spec)
+                and self._get_operator("!=")(prospective, spec + ".*"))
+
+    def _compare_arbitrary(self, prospective, spec):
+        return str(prospective).lower() == str(spec).lower()
+
+    @property
+    def prereleases(self):
+        # If there is an explicit prereleases set for this, then we'll just
+        # blindly use that.
+        if self._prereleases is not None:
+            return self._prereleases
+
+        # Look at all of our specifiers and determine if they are inclusive
+        # operators, and if they are if they are including an explicit
+        # prerelease.
+        for spec, version in self._specs:
+            if spec in ["==", ">=", "<=", "~="]:
+                # The == specifier can include a trailing .*, if it does we
+                # want to remove before parsing.
+                if spec == "==" and version.endswith(".*"):
+                    version = version[:-2]
+
+                # Parse the version, and if it is a pre-release than this
+                # specifier allows pre-releases.
+                if parse(version).is_prerelease:
+                    return True
+
+        return False
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+    def contains(self, item, prereleases=None):
+        # Determine if prereleases are to be allowed or not.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # Normalize item to a Version or LegacyVersion, this allows us to have
+        # a shortcut for ``"2.0" in Specifier(">=2")
+        if isinstance(item, (Version, LegacyVersion)):
+            version_item = item
+        else:
+            try:
+                version_item = Version(item)
+            except ValueError:
+                version_item = LegacyVersion(item)
+
+        # Determine if we should be supporting prereleases in this specifier
+        # or not, if we do not support prereleases than we can short circuit
+        # logic if this version is a prereleases.
+        if version_item.is_prerelease and not prereleases:
+            return False
+
+        # Detect if we have any specifiers, if we do not then anything matches
+        # and we can short circuit all this logic.
+        if not self._specs:
+            return True
+
+        # If we're operating on a LegacyVersion, then we can only support
+        # arbitrary comparison so do a quick check to see if the spec contains
+        # any non arbitrary specifiers
+        if isinstance(version_item, LegacyVersion):
+            if any(op != "===" for op, _ in self._specs):
+                return False
+
+        # Ensure that the passed in version matches all of our version
+        # specifiers
+        return all(
+            self._get_operator(op)(
+                version_item if op != "===" else item,
+                spec,
+            )
+            for op, spec, in self._specs
+        )
+
+    def filter(self, iterable, prereleases=None):
+        iterable = list(iterable)
+        yielded = False
+        found_prereleases = []
+
+        kw = {"prereleases": prereleases if prereleases is not None else True}
+
+        # Attempt to iterate over all the values in the iterable and if any of
+        # them match, yield them.
+        for version in iterable:
+            if not isinstance(version, (Version, LegacyVersion)):
+                parsed_version = parse(version)
+            else:
+                parsed_version = version
+
+            if self.contains(parsed_version, **kw):
+                # 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)):
+                    found_prereleases.append(version)
+                # Either this is not a prerelease, or we should have been
+                # accepting prereleases from the begining.
+                else:
+                    yielded = True
+                    yield version
+
+        # Now that we've iterated over everything, determine if we've yielded
+        # any values, and if we have not and we have any prereleases stored up
+        # then we will go ahead and yield the prereleases.
+        if not yielded and found_prereleases:
+            for version in found_prereleases:
+                yield version
+
+
+_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")
+
+
+def _version_split(version):
+    result = []
+    for item in version.split("."):
+        match = _prefix_regex.search(item)
+        if match:
+            result.extend(match.groups())
+        else:
+            result.append(item)
+    return result
+
+
+def _pad_version(left, right):
+    left_split, right_split = [], []
+
+    # Get the release segment of our versions
+    left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left)))
+    right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
+
+    # Get the rest of our versions
+    left_split.append(left[len(left_split):])
+    right_split.append(left[len(right_split):])
+
+    # 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])),
+    )
+
+    return (
+        list(itertools.chain(*left_split)),
+        list(itertools.chain(*right_split)),
+    )
diff --git a/setuptools/_vendor/vendored.txt b/setuptools/_vendor/vendored.txt
new file mode 100644
index 00000000..df383d8b
--- /dev/null
+++ b/setuptools/_vendor/vendored.txt
@@ -0,0 +1 @@
+packaging==14.2
-- 
cgit v1.2.3


From 9382fa0c05e533400613e1c7c0a777cabb463390 Mon Sep 17 00:00:00 2001
From: Donald Stufft 
Date: Thu, 4 Sep 2014 21:04:06 -0400
Subject: Implement PEP 440 by using the packaging library

---
 CHANGES.txt                        |   4 +-
 docs/pkg_resources.txt             |  66 ++++-----------
 pkg_resources.py                   | 161 ++++++++++---------------------------
 setuptools/_vendor/__init__.py     |   0
 setuptools/command/egg_info.py     |   8 +-
 setuptools/dist.py                 |  21 +++++
 setuptools/tests/test_egg_info.py  |   6 +-
 setuptools/tests/test_resources.py |  34 +++-----
 8 files changed, 105 insertions(+), 195 deletions(-)
 create mode 100644 setuptools/_vendor/__init__.py

diff --git a/CHANGES.txt b/CHANGES.txt
index a6e27372..e458d76c 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -2,7 +2,6 @@
 CHANGES
 =======
 
----
 6.0
 ---
 
@@ -24,6 +23,9 @@ CHANGES
   case-insensitively, but not case-sensitively, should rename those files in
   their repository for better portability.
 
+* Implement PEP 440 within pkg_resources and setuptools. This will cause some
+  versions to no longer be installable without using the ``===`` escape hatch.
+
 ---
 5.8
 ---
diff --git a/docs/pkg_resources.txt b/docs/pkg_resources.txt
index f4a768e4..6c6405a8 100644
--- a/docs/pkg_resources.txt
+++ b/docs/pkg_resources.txt
@@ -594,7 +594,7 @@ Requirements Parsing
 
         requirement  ::= project_name versionspec? extras?
         versionspec  ::= comparison version (',' comparison version)*
-        comparison   ::= '<' | '<=' | '!=' | '==' | '>=' | '>'
+        comparison   ::= '<' | '<=' | '!=' | '==' | '>=' | '>' | '~=' | '==='
         extras       ::= '[' extralist? ']'
         extralist    ::= identifier (',' identifier)*
         project_name ::= identifier
@@ -646,13 +646,10 @@ Requirements Parsing
     The ``Requirement`` object's version specifiers (``.specs``) are internally
     sorted into ascending version order, and used to establish what ranges of
     versions are acceptable.  Adjacent redundant conditions are effectively
-    consolidated (e.g. ``">1, >2"`` produces the same results as ``">1"``, and
-    ``"<2,<3"`` produces the same results as``"<3"``). ``"!="`` versions are
+    consolidated (e.g. ``">1, >2"`` produces the same results as ``">2"``, and
+    ``"<2,<3"`` produces the same results as``"<2"``). ``"!="`` versions are
     excised from the ranges they fall within.  The version being tested for
     acceptability is then checked for membership in the resulting ranges.
-    (Note that providing conflicting conditions for the same version (e.g.
-    ``"<2,>=2"`` or ``"==2,!=2"``) is meaningless and may therefore produce
-    bizarre results when compared with actual version number(s).)
 
 ``__eq__(other_requirement)``
     A requirement compares equal to another requirement if they have
@@ -681,10 +678,7 @@ Requirements Parsing
 ``specs``
     A list of ``(op,version)`` tuples, sorted in ascending parsed-version
     order.  The `op` in each tuple is a comparison operator, represented as
-    a string.  The `version` is the (unparsed) version number.  The relative
-    order of tuples containing the same version numbers is undefined, since
-    having more than one operator for a given version is either redundant or
-    self-contradictory.
+    a string.  The `version` is the (unparsed) version number.
 
 
 Entry Points
@@ -967,7 +961,7 @@ version
     ``ValueError`` is raised.
 
 parsed_version
-    The ``parsed_version`` is a tuple representing a "parsed" form of the
+    The ``parsed_version`` is an object representing a "parsed" form of the
     distribution's ``version``.  ``dist.parsed_version`` is a shortcut for
     calling ``parse_version(dist.version)``.  It is used to compare or sort
     distributions by version.  (See the `Parsing Utilities`_ section below for
@@ -1541,40 +1535,12 @@ Parsing Utilities
 -----------------
 
 ``parse_version(version)``
-    Parse a project's version string, returning a value that can be used to
-    compare versions by chronological order.  Semantically, the format is a
-    rough cross between distutils' ``StrictVersion`` and ``LooseVersion``
-    classes; if you give it versions that would work with ``StrictVersion``,
-    then they will compare the same way.  Otherwise, comparisons are more like
-    a "smarter" form of ``LooseVersion``.  It is *possible* to create
-    pathological version coding schemes that will fool this parser, but they
-    should be very rare in practice.
-
-    The returned value will be a tuple of strings.  Numeric portions of the
-    version are padded to 8 digits so they will compare numerically, but
-    without relying on how numbers compare relative to strings.  Dots are
-    dropped, but dashes are retained.  Trailing zeros between alpha segments
-    or dashes are suppressed, so that e.g. "2.4.0" is considered the same as
-    "2.4". Alphanumeric parts are lower-cased.
-
-    The algorithm assumes that strings like "-" and any alpha string that
-    alphabetically follows "final"  represents a "patch level".  So, "2.4-1"
-    is assumed to be a branch or patch of "2.4", and therefore "2.4.1" is
-    considered newer than "2.4-1", which in turn is newer than "2.4".
-
-    Strings like "a", "b", "c", "alpha", "beta", "candidate" and so on (that
-    come before "final" alphabetically) are assumed to be pre-release versions,
-    so that the version "2.4" is considered newer than "2.4a1".  Any "-"
-    characters preceding a pre-release indicator are removed.  (In versions of
-    setuptools prior to 0.6a9, "-" characters were not removed, leading to the
-    unintuitive result that "0.2-rc1" was considered a newer version than
-    "0.2".)
-
-    Finally, to handle miscellaneous cases, the strings "pre", "preview", and
-    "rc" are treated as if they were "c", i.e. as though they were release
-    candidates, and therefore are not as new as a version string that does not
-    contain them.  And the string "dev" is treated as if it were an "@" sign;
-    that is, a version coming before even "a" or "alpha".
+    Parsed a project's version string as defined by PEP 440. The returned
+    value will be an object that represents the version. These objects may
+    be compared to each other and sorted. The sorting algorithm is as defined
+    by PEP 440 with the addition that any version which is not a valid PEP 440
+    version will be considered less than any valid PEP 440 version and the
+    invalid versions will continue sorting using the original algorithm.
 
 .. _yield_lines():
 
@@ -1629,10 +1595,12 @@ Parsing Utilities
     See ``to_filename()``.
 
 ``safe_version(version)``
-    Similar to ``safe_name()`` except that spaces in the input become dots, and
-    dots are allowed to exist in the output.  As with ``safe_name()``, if you
-    are generating a filename from this you should replace any "-" characters
-    in the output with underscores.
+    This will return the normalized form of any PEP 440 version, if the version
+    string is not PEP 440 compatible than it is similar to ``safe_name()``
+    except that spaces in the input become dots, and dots are allowed to exist
+    in the output.  As with ``safe_name()``, if you are generating a filename
+    from this you should replace any "-" characters in the output with
+    underscores.
 
 ``safe_extra(extra)``
     Return a "safe" form of an extra's name, suitable for use in a requirement
diff --git a/pkg_resources.py b/pkg_resources.py
index 517298c9..b59ec523 100644
--- a/pkg_resources.py
+++ b/pkg_resources.py
@@ -73,6 +73,14 @@ try:
 except ImportError:
     pass
 
+# Import packaging.version.parse as parse_version for a compat shim with the
+# old parse_version that used to be defined in this file.
+from setuptools._vendor.packaging.version import parse as parse_version
+
+from setuptools._vendor.packaging.version import (
+    Version, InvalidVersion, Specifier,
+)
+
 
 _state_vars = {}
 
@@ -1143,13 +1151,14 @@ def safe_name(name):
 
 
 def safe_version(version):
-    """Convert an arbitrary string to a standard version string
-
-    Spaces become dots, and all other non-alphanumeric characters become
-    dashes, with runs of multiple dashes condensed to a single dash.
     """
-    version = version.replace(' ','.')
-    return re.sub('[^A-Za-z0-9.]+', '-', version)
+    Convert an arbitrary string to a standard version string
+    """
+    try:
+        return str(Version(version))  # this will normalize the version
+    except InvalidVersion:
+        version = version.replace(' ','.')
+        return re.sub('[^A-Za-z0-9.]+', '-', version)
 
 
 def safe_extra(extra):
@@ -2067,7 +2076,7 @@ CONTINUE = re.compile(r"\s*\\\s*(#.*)?$").match
 # Distribution or extra
 DISTRO = re.compile(r"\s*((\w|[-.])+)").match
 # ver. info
-VERSION = re.compile(r"\s*(<=?|>=?|==|!=)\s*((\w|[-.])+)").match
+VERSION = re.compile(r"\s*(<=?|>=?|===?|!=|~=)\s*((\w|[-.*_!+])+)").match
 # comma between items
 COMMA = re.compile(r"\s*,").match
 OBRACKET = re.compile(r"\s*\[").match
@@ -2079,67 +2088,6 @@ EGG_NAME = re.compile(
     re.VERBOSE | re.IGNORECASE
 ).match
 
-component_re = re.compile(r'(\d+ | [a-z]+ | \.| -)', re.VERBOSE)
-replace = {'pre':'c', 'preview':'c','-':'final-','rc':'c','dev':'@'}.get
-
-def _parse_version_parts(s):
-    for part in component_re.split(s):
-        part = replace(part, part)
-        if not part or part=='.':
-            continue
-        if part[:1] in '0123456789':
-            # pad for numeric comparison
-            yield part.zfill(8)
-        else:
-            yield '*'+part
-
-    # ensure that alpha/beta/candidate are before final
-    yield '*final'
-
-def parse_version(s):
-    """Convert a version string to a chronologically-sortable key
-
-    This is a rough cross between distutils' StrictVersion and LooseVersion;
-    if you give it versions that would work with StrictVersion, then it behaves
-    the same; otherwise it acts like a slightly-smarter LooseVersion. It is
-    *possible* to create pathological version coding schemes that will fool
-    this parser, but they should be very rare in practice.
-
-    The returned value will be a tuple of strings.  Numeric portions of the
-    version are padded to 8 digits so they will compare numerically, but
-    without relying on how numbers compare relative to strings.  Dots are
-    dropped, but dashes are retained.  Trailing zeros between alpha segments
-    or dashes are suppressed, so that e.g. "2.4.0" is considered the same as
-    "2.4". Alphanumeric parts are lower-cased.
-
-    The algorithm assumes that strings like "-" and any alpha string that
-    alphabetically follows "final"  represents a "patch level".  So, "2.4-1"
-    is assumed to be a branch or patch of "2.4", and therefore "2.4.1" is
-    considered newer than "2.4-1", which in turn is newer than "2.4".
-
-    Strings like "a", "b", "c", "alpha", "beta", "candidate" and so on (that
-    come before "final" alphabetically) are assumed to be pre-release versions,
-    so that the version "2.4" is considered newer than "2.4a1".
-
-    Finally, to handle miscellaneous cases, the strings "pre", "preview", and
-    "rc" are treated as if they were "c", i.e. as though they were release
-    candidates, and therefore are not as new as a version string that does not
-    contain them, and "dev" is replaced with an '@' so that it sorts lower than
-    than any other pre-release tag.
-    """
-    parts = []
-    for part in _parse_version_parts(s.lower()):
-        if part.startswith('*'):
-            # remove '-' before a prerelease tag
-            if part < '*final':
-                while parts and parts[-1] == '*final-':
-                    parts.pop()
-            # remove trailing zeros from each series of numeric parts
-            while parts and parts[-1]=='00000000':
-                parts.pop()
-        parts.append(part)
-    return tuple(parts)
-
 
 class EntryPoint(object):
     """Object representing an advertised importable object"""
@@ -2292,7 +2240,7 @@ class Distribution(object):
     @property
     def hashcmp(self):
         return (
-            getattr(self, 'parsed_version', ()),
+            self.parsed_version,
             self.precedence,
             self.key,
             _remove_md5_fragment(self.location),
@@ -2338,11 +2286,10 @@ class Distribution(object):
 
     @property
     def parsed_version(self):
-        try:
-            return self._parsed_version
-        except AttributeError:
-            self._parsed_version = pv = parse_version(self.version)
-            return pv
+        if not hasattr(self, "_parsed_version"):
+            self._parsed_version = parse_version(self.version)
+
+        return self._parsed_version
 
     @property
     def version(self):
@@ -2447,7 +2394,12 @@ class Distribution(object):
 
     def as_requirement(self):
         """Return a ``Requirement`` that matches this distribution exactly"""
-        return Requirement.parse('%s==%s' % (self.project_name, self.version))
+        if isinstance(self.parsed_version, Version):
+            spec = "%s==%s" % (self.project_name, self.parsed_version)
+        else:
+            spec = "%s===%s" % (self.project_name, self.parsed_version)
+
+        return Requirement.parse(spec)
 
     def load_entry_point(self, group, name):
         """Return the `name` entry point of `group` or raise ImportError"""
@@ -2699,7 +2651,7 @@ def parse_requirements(strs):
 
         line, p, specs = scan_list(VERSION, LINE_END, line, p, (1, 2),
             "version spec")
-        specs = [(op, safe_version(val)) for op, val in specs]
+        specs = [(op, val) for op, val in specs]
         yield Requirement(project_name, specs, extras)
 
 
@@ -2708,26 +2660,23 @@ class Requirement:
         """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
         self.unsafe_name, project_name = project_name, safe_name(project_name)
         self.project_name, self.key = project_name, project_name.lower()
-        index = [
-            (parse_version(v), state_machine[op], op, v)
-            for op, v in specs
-        ]
-        index.sort()
-        self.specs = [(op, ver) for parsed, trans, op, ver in index]
-        self.index, self.extras = index, tuple(map(safe_extra, extras))
+        self.specifier = Specifier(
+            ",".join(["".join([x, y]) for x, y in specs])
+        )
+        self.specs = specs
+        self.extras = tuple(map(safe_extra, extras))
         self.hashCmp = (
             self.key,
-            tuple((op, parsed) for parsed, trans, op, ver in index),
+            self.specifier,
             frozenset(self.extras),
         )
         self.__hash = hash(self.hashCmp)
 
     def __str__(self):
-        specs = ','.join([''.join(s) for s in self.specs])
         extras = ','.join(self.extras)
         if extras:
             extras = '[%s]' % extras
-        return '%s%s%s' % (self.project_name, extras, specs)
+        return '%s%s%s' % (self.project_name, extras, self.specifier)
 
     def __eq__(self, other):
         return (
@@ -2739,29 +2688,13 @@ class Requirement:
         if isinstance(item, Distribution):
             if item.key != self.key:
                 return False
-            # only get if we need it
-            if self.index:
-                item = item.parsed_version
-        elif isinstance(item, string_types):
-            item = parse_version(item)
-        last = None
-        # -1, 0, 1
-        compare = lambda a, b: (a > b) - (a < b)
-        for parsed, trans, op, ver in self.index:
-            # Indexing: 0, 1, -1
-            action = trans[compare(item, parsed)]
-            if action == 'F':
-                return False
-            elif action == 'T':
-                return True
-            elif action == '+':
-                last = True
-            elif action == '-' or last is None:
-                last = False
-        # no rules encountered
-        if last is None:
-            last = True
-        return last
+
+            item = item.version
+
+        # Allow prereleases always in order to match the previous behavior of
+        # this method. In the future this should be smarter and follow PEP 440
+        # more accurately.
+        return self.specifier.contains(item, prereleases=True)
 
     def __hash__(self):
         return self.__hash
@@ -2777,16 +2710,6 @@ class Requirement:
             raise ValueError("Expected only one requirement", s)
         raise ValueError("No requirements found", s)
 
-state_machine = {
-    #       =><
-    '<': '--T',
-    '<=': 'T-T',
-    '>': 'F+F',
-    '>=': 'T+F',
-    '==': 'T..',
-    '!=': 'F++',
-}
-
 
 def _get_mro(cls):
     """Get an mro for a type or classic class"""
diff --git a/setuptools/_vendor/__init__.py b/setuptools/_vendor/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py
index 72493d0b..cb67255b 100755
--- a/setuptools/command/egg_info.py
+++ b/setuptools/command/egg_info.py
@@ -15,6 +15,7 @@ from setuptools.command.sdist import sdist
 from setuptools.compat import basestring, PY3, StringIO
 from setuptools import svn_utils
 from setuptools.command.sdist import walk_revctrl
+from setuptools._vendor.packaging.version import Version
 from pkg_resources import (
     parse_requirements, safe_name, parse_version,
     safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename)
@@ -68,9 +69,14 @@ class egg_info(Command):
         self.vtags = self.tags()
         self.egg_version = self.tagged_version()
 
+        parsed_version = parse_version(self.egg_version)
+
         try:
+            spec = (
+                "%s==%s" if isinstance(parsed_version, Version) else "%s===%s"
+            )
             list(
-                parse_requirements('%s==%s' % (self.egg_name,
+                parse_requirements(spec % (self.egg_name,
                                                self.egg_version))
             )
         except ValueError:
diff --git a/setuptools/dist.py b/setuptools/dist.py
index 8b36f67c..ae4ff554 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -15,6 +15,7 @@ from distutils.errors import (DistutilsOptionError, DistutilsPlatformError,
 
 from setuptools.depends import Require
 from setuptools.compat import basestring, PY2
+from setuptools._vendor.packaging.version import Version, InvalidVersion
 import pkg_resources
 
 def _get_unpatched(cls):
@@ -268,6 +269,26 @@ class Distribution(_Distribution):
             # Some people apparently take "version number" too literally :)
             self.metadata.version = str(self.metadata.version)
 
+        if self.metadata.version is not None:
+            try:
+                normalized_version = str(Version(self.metadata.version))
+                if self.metadata.version != normalized_version:
+                    warnings.warn(
+                        "The version specified requires normalization, "
+                        "consider using '%s' instead of '%s'." % (
+                            normalized_version,
+                            self.metadata.version,
+                        )
+                    )
+                    self.metadata.version = normalized_version
+            except (InvalidVersion, TypeError):
+                warnings.warn(
+                    "The version specified (%r) is an invalid version, this "
+                    "may not work as expected with newer versions of "
+                    "setuptools, pip, and PyPI. Please see PEP 440 for more "
+                    "details." % self.metadata.version
+                )
+
     def parse_command_line(self):
         """Process features after parsing command line options"""
         result = _Distribution.parse_command_line(self)
diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py
index 7531e37c..4c4f9456 100644
--- a/setuptools/tests/test_egg_info.py
+++ b/setuptools/tests/test_egg_info.py
@@ -34,7 +34,7 @@ class TestEggInfo(unittest.TestCase):
         entries_f = open(fn, 'wb')
         entries_f.write(entries)
         entries_f.close()
-   
+
     @skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
     def test_version_10_format(self):
         """
@@ -140,7 +140,7 @@ class TestSvnDummy(environment.ZippedEnvironment):
 
     @skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
     def test_svn_tags(self):
-        code, data = environment.run_setup_py(["egg_info", 
+        code, data = environment.run_setup_py(["egg_info",
                                                "--tag-svn-revision"],
                                               pypath=self.old_cwd,
                                               data_stream=1)
@@ -155,7 +155,7 @@ class TestSvnDummy(environment.ZippedEnvironment):
             infile.close()
             del infile
 
-        self.assertTrue("Version: 0.1.1-r1\n" in read_contents)
+        self.assertTrue("Version: 0.1.1.post1\n" in read_contents)
 
     @skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
     def test_no_tags(self):
diff --git a/setuptools/tests/test_resources.py b/setuptools/tests/test_resources.py
index 3baa3ab1..9051b414 100644
--- a/setuptools/tests/test_resources.py
+++ b/setuptools/tests/test_resources.py
@@ -16,6 +16,7 @@ from pkg_resources import (parse_requirements, VersionConflict, parse_version,
 from setuptools.command.easy_install import (get_script_header, is_sh,
     nt_quote_arg)
 from setuptools.compat import StringIO, iteritems, PY3
+from setuptools._vendor.packaging.version import Specifier
 from .py26compat import skipIf
 
 def safe_repr(obj, short=False):
@@ -103,7 +104,7 @@ class DistroTests(TestCase):
     def checkFooPkg(self,d):
         self.assertEqual(d.project_name, "FooPkg")
         self.assertEqual(d.key, "foopkg")
-        self.assertEqual(d.version, "1.3-1")
+        self.assertEqual(d.version, "1.3.post1")
         self.assertEqual(d.py_version, "2.4")
         self.assertEqual(d.platform, "win32")
         self.assertEqual(d.parsed_version, parse_version("1.3-1"))
@@ -120,9 +121,9 @@ class DistroTests(TestCase):
         self.assertEqual(d.platform, None)
 
     def testDistroParse(self):
-        d = dist_from_fn("FooPkg-1.3_1-py2.4-win32.egg")
+        d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg")
         self.checkFooPkg(d)
-        d = dist_from_fn("FooPkg-1.3_1-py2.4-win32.egg-info")
+        d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg-info")
         self.checkFooPkg(d)
 
     def testDistroMetadata(self):
@@ -330,24 +331,15 @@ class RequirementsTests(TestCase):
         self.assertTrue(twist11 not in r)
         self.assertTrue(twist12 in r)
 
-    def testAdvancedContains(self):
-        r, = parse_requirements("Foo>=1.2,<=1.3,==1.9,>2.0,!=2.5,<3.0,==4.5")
-        for v in ('1.2','1.2.2','1.3','1.9','2.0.1','2.3','2.6','3.0c1','4.5'):
-            self.assertTrue(v in r, (v,r))
-        for v in ('1.2c1','1.3.1','1.5','1.9.1','2.0','2.5','3.0','4.0'):
-            self.assertTrue(v not in r, (v,r))
-
     def testOptionsAndHashing(self):
         r1 = Requirement.parse("Twisted[foo,bar]>=1.2")
         r2 = Requirement.parse("Twisted[bar,FOO]>=1.2")
-        r3 = Requirement.parse("Twisted[BAR,FOO]>=1.2.0")
         self.assertEqual(r1,r2)
-        self.assertEqual(r1,r3)
         self.assertEqual(r1.extras, ("foo","bar"))
         self.assertEqual(r2.extras, ("bar","foo"))  # extras are normalized
         self.assertEqual(hash(r1), hash(r2))
         self.assertEqual(
-            hash(r1), hash(("twisted", ((">=",parse_version("1.2")),),
+            hash(r1), hash(("twisted", Specifier(">=1.2"),
                             frozenset(["foo","bar"])))
         )
 
@@ -420,7 +412,7 @@ class ParseTests(TestCase):
         self.assertNotEqual(safe_name("peak.web"), "peak-web")
 
     def testSafeVersion(self):
-        self.assertEqual(safe_version("1.2-1"), "1.2-1")
+        self.assertEqual(safe_version("1.2-1"), "1.2.post1")
         self.assertEqual(safe_version("1.2 alpha"),  "1.2.alpha")
         self.assertEqual(safe_version("2.3.4 20050521"), "2.3.4.20050521")
         self.assertEqual(safe_version("Money$$$Maker"), "Money-Maker")
@@ -454,12 +446,12 @@ class ParseTests(TestCase):
         c('0.4', '0.4.0')
         c('0.4.0.0', '0.4.0')
         c('0.4.0-0', '0.4-0')
-        c('0pl1', '0.0pl1')
+        c('0post1', '0.0post1')
         c('0pre1', '0.0c1')
         c('0.0.0preview1', '0c1')
         c('0.0c1', '0-rc1')
         c('1.2a1', '1.2.a.1')
-        c('1.2...a', '1.2a')
+        c('1.2.a', '1.2a')
 
     def testVersionOrdering(self):
         def c(s1,s2):
@@ -472,16 +464,14 @@ class ParseTests(TestCase):
         c('2.3a1', '2.3')
         c('2.1-1', '2.1-2')
         c('2.1-1', '2.1.1')
-        c('2.1', '2.1pl4')
+        c('2.1', '2.1post4')
         c('2.1a0-20040501', '2.1')
         c('1.1', '02.1')
-        c('A56','B27')
-        c('3.2', '3.2.pl0')
-        c('3.2-1', '3.2pl1')
-        c('3.2pl1', '3.2pl1-1')
+        c('3.2', '3.2.post0')
+        c('3.2post1', '3.2post2')
         c('0.4', '4.0')
         c('0.0.4', '0.4.0')
-        c('0pl1', '0.4pl1')
+        c('0post1', '0.4post1')
         c('2.1.0-rc1','2.1.0')
         c('2.1dev','2.1a0')
 
-- 
cgit v1.2.3


From 13823cb975590687902edd3c4c073b2c1671cebc Mon Sep 17 00:00:00 2001
From: "Jason R. Coombs" 
Date: Sat, 27 Sep 2014 15:54:14 -0400
Subject: Update changelog with references to changes.

---
 CHANGES.txt | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 3cba6353..19d8095f 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -6,8 +6,14 @@ CHANGES
 7.0
 ---
 
-* Implement PEP 440 within pkg_resources and setuptools. This will cause some
-  versions to no longer be installable without using the ``===`` escape hatch.
+* Implement `PEP 440 `_ within
+  pkg_resources and setuptools. This change
+  deprecates some version numbers such that they will no longer be installable
+  without using the ``===`` escape hatch. See `the changes to test_resources
+  `_
+  for specific examples of version numbers and specifiers that are no longer
+  supported. Setuptools now "vendors" the `packaging
+  `_ library.
 
 -----
 6.0.1
-- 
cgit v1.2.3


From 6f6ee4f28ec5ceb95594264746da3676947aaa08 Mon Sep 17 00:00:00 2001
From: "Jason R. Coombs" 
Date: Sat, 27 Sep 2014 16:05:06 -0400
Subject: Avoid trailing comments

---
 pkg_resources.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/pkg_resources.py b/pkg_resources.py
index b59ec523..f2e8b850 100644
--- a/pkg_resources.py
+++ b/pkg_resources.py
@@ -1155,7 +1155,8 @@ def safe_version(version):
     Convert an arbitrary string to a standard version string
     """
     try:
-        return str(Version(version))  # this will normalize the version
+        # normalize the version
+        return str(Version(version))
     except InvalidVersion:
         version = version.replace(' ','.')
         return re.sub('[^A-Za-z0-9.]+', '-', version)
-- 
cgit v1.2.3


From a9541756f6a12c91704feffec4ddfee859f12c30 Mon Sep 17 00:00:00 2001
From: "Jason R. Coombs" 
Date: Sat, 27 Sep 2014 16:10:17 -0400
Subject: Fix indent

---
 setuptools/command/egg_info.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py
index 9ba719fe..de43bf0c 100755
--- a/setuptools/command/egg_info.py
+++ b/setuptools/command/egg_info.py
@@ -76,8 +76,7 @@ class egg_info(Command):
                 "%s==%s" if isinstance(parsed_version, Version) else "%s===%s"
             )
             list(
-                parse_requirements(spec % (self.egg_name,
-                                               self.egg_version))
+                parse_requirements(spec % (self.egg_name, self.egg_version))
             )
         except ValueError:
             raise distutils.errors.DistutilsOptionError(
-- 
cgit v1.2.3


From 7d9c21a893431798ba77edd62b5490ff4ce47ecf Mon Sep 17 00:00:00 2001
From: "Jason R. Coombs" 
Date: Sat, 27 Sep 2014 16:13:48 -0400
Subject: Prefer packaging library if available.

---
 pkg_resources.py                   | 24 ++++++++++++++----------
 setup.py                           |  3 +++
 setuptools/command/egg_info.py     | 11 +++++++++--
 setuptools/dist.py                 | 14 +++++++++++---
 setuptools/tests/test_resources.py | 10 ++++++++--
 5 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/pkg_resources.py b/pkg_resources.py
index f2e8b850..6f21b0bf 100644
--- a/pkg_resources.py
+++ b/pkg_resources.py
@@ -14,6 +14,8 @@ The package resource API is designed to work with normal filesystem packages,
 method.
 """
 
+from __future__ import absolute_import
+
 import sys
 import os
 import io
@@ -73,13 +75,15 @@ try:
 except ImportError:
     pass
 
-# Import packaging.version.parse as parse_version for a compat shim with the
-# old parse_version that used to be defined in this file.
-from setuptools._vendor.packaging.version import parse as parse_version
+try:
+    import packaging.version
+except ImportError:
+    # fallback to vendored version
+    import setuptools._vendor.packaging.version
+    packaging = setuptools._vendor.packaging
 
-from setuptools._vendor.packaging.version import (
-    Version, InvalidVersion, Specifier,
-)
+# For compatibility, expose packaging.version.parse as parse_version
+parse_version = packaging.version.parse
 
 
 _state_vars = {}
@@ -1156,8 +1160,8 @@ def safe_version(version):
     """
     try:
         # normalize the version
-        return str(Version(version))
-    except InvalidVersion:
+        return str(packaging.version.Version(version))
+    except packaging.version.InvalidVersion:
         version = version.replace(' ','.')
         return re.sub('[^A-Za-z0-9.]+', '-', version)
 
@@ -2395,7 +2399,7 @@ class Distribution(object):
 
     def as_requirement(self):
         """Return a ``Requirement`` that matches this distribution exactly"""
-        if isinstance(self.parsed_version, Version):
+        if isinstance(self.parsed_version, packaging.version.Version):
             spec = "%s==%s" % (self.project_name, self.parsed_version)
         else:
             spec = "%s===%s" % (self.project_name, self.parsed_version)
@@ -2661,7 +2665,7 @@ class Requirement:
         """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
         self.unsafe_name, project_name = project_name, safe_name(project_name)
         self.project_name, self.key = project_name, project_name.lower()
-        self.specifier = Specifier(
+        self.specifier = packaging.version.Specifier(
             ",".join(["".join([x, y]) for x, y in specs])
         )
         self.specs = specs
diff --git a/setup.py b/setup.py
index bac4e29d..cc0e4684 100755
--- a/setup.py
+++ b/setup.py
@@ -198,6 +198,9 @@ setup_params = dict(
         Topic :: System :: Systems Administration
         Topic :: Utilities
         """).strip().splitlines(),
+    install_requires=[
+        "packaging>=14.2,<15.0.dev0",
+    ],
     extras_require={
         "ssl:sys_platform=='win32'": "wincertstore==0.2",
         "certs": "certifi==1.0.1",
diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py
index de43bf0c..43df87dc 100755
--- a/setuptools/command/egg_info.py
+++ b/setuptools/command/egg_info.py
@@ -10,12 +10,18 @@ import os
 import re
 import sys
 
+try:
+    import packaging.version
+except ImportError:
+    # fallback to vendored version
+    import setuptools._vendor.packaging.version
+    packaging = setuptools._vendor.packaging
+
 from setuptools import Command
 from setuptools.command.sdist import sdist
 from setuptools.compat import basestring, PY3, StringIO
 from setuptools import svn_utils
 from setuptools.command.sdist import walk_revctrl
-from setuptools._vendor.packaging.version import Version
 from pkg_resources import (
     parse_requirements, safe_name, parse_version,
     safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename)
@@ -72,8 +78,9 @@ class egg_info(Command):
         parsed_version = parse_version(self.egg_version)
 
         try:
+            is_version = isinstance(parsed_version, packaging.version.Version)
             spec = (
-                "%s==%s" if isinstance(parsed_version, Version) else "%s===%s"
+                "%s==%s" if is_version else "%s===%s"
             )
             list(
                 parse_requirements(spec % (self.egg_name, self.egg_version))
diff --git a/setuptools/dist.py b/setuptools/dist.py
index ae4ff554..a3a37ee4 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -13,11 +13,18 @@ from distutils.core import Distribution as _Distribution
 from distutils.errors import (DistutilsOptionError, DistutilsPlatformError,
     DistutilsSetupError)
 
+try:
+    import packaging.version
+except ImportError:
+    # fallback to vendored version
+    import setuptools._vendor.packaging.version
+    packaging = setuptools._vendor.packaging
+
 from setuptools.depends import Require
 from setuptools.compat import basestring, PY2
-from setuptools._vendor.packaging.version import Version, InvalidVersion
 import pkg_resources
 
+
 def _get_unpatched(cls):
     """Protect against re-patching the distutils if reloaded
 
@@ -271,7 +278,8 @@ class Distribution(_Distribution):
 
         if self.metadata.version is not None:
             try:
-                normalized_version = str(Version(self.metadata.version))
+                ver = packaging.version.Version(self.metadata.version)
+                normalized_version = str(ver)
                 if self.metadata.version != normalized_version:
                     warnings.warn(
                         "The version specified requires normalization, "
@@ -281,7 +289,7 @@ class Distribution(_Distribution):
                         )
                     )
                     self.metadata.version = normalized_version
-            except (InvalidVersion, TypeError):
+            except (packaging.version.InvalidVersion, TypeError):
                 warnings.warn(
                     "The version specified (%r) is an invalid version, this "
                     "may not work as expected with newer versions of "
diff --git a/setuptools/tests/test_resources.py b/setuptools/tests/test_resources.py
index 9051b414..8336a85d 100644
--- a/setuptools/tests/test_resources.py
+++ b/setuptools/tests/test_resources.py
@@ -8,6 +8,13 @@ import tempfile
 import shutil
 from unittest import TestCase
 
+try:
+    import packaging.version
+except ImportError:
+    # fallback to vendored version
+    import setuptools._vendor.packaging.version
+    packaging = setuptools._vendor.packaging
+
 import pkg_resources
 from pkg_resources import (parse_requirements, VersionConflict, parse_version,
     Distribution, EntryPoint, Requirement, safe_version, safe_name,
@@ -16,7 +23,6 @@ from pkg_resources import (parse_requirements, VersionConflict, parse_version,
 from setuptools.command.easy_install import (get_script_header, is_sh,
     nt_quote_arg)
 from setuptools.compat import StringIO, iteritems, PY3
-from setuptools._vendor.packaging.version import Specifier
 from .py26compat import skipIf
 
 def safe_repr(obj, short=False):
@@ -339,7 +345,7 @@ class RequirementsTests(TestCase):
         self.assertEqual(r2.extras, ("bar","foo"))  # extras are normalized
         self.assertEqual(hash(r1), hash(r2))
         self.assertEqual(
-            hash(r1), hash(("twisted", Specifier(">=1.2"),
+            hash(r1), hash(("twisted", packaging.version.Specifier(">=1.2"),
                             frozenset(["foo","bar"])))
         )
 
-- 
cgit v1.2.3


From c2e9f2ad32978620037bfbcc792e94e8e32f8097 Mon Sep 17 00:00:00 2001
From: "Jason R. Coombs" 
Date: Sat, 27 Sep 2014 16:16:22 -0400
Subject: Update requirements

---
 setuptools.egg-info/requires.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/setuptools.egg-info/requires.txt b/setuptools.egg-info/requires.txt
index 4fa66c71..f3f4471e 100644
--- a/setuptools.egg-info/requires.txt
+++ b/setuptools.egg-info/requires.txt
@@ -1,3 +1,4 @@
+packaging>=14.2,<15.0.dev0
 
 [certs]
 certifi==1.0.1
-- 
cgit v1.2.3


From aa87355981a6475855116f1b663ba654e332b5a7 Mon Sep 17 00:00:00 2001
From: "Jason R. Coombs" 
Date: Sat, 27 Sep 2014 16:24:55 -0400
Subject: Bump to 7.0 in preparation for next release.

---
 ez_setup.py           | 2 +-
 setuptools/version.py | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/ez_setup.py b/ez_setup.py
index c5d85d37..a523401e 100644
--- a/ez_setup.py
+++ b/ez_setup.py
@@ -36,7 +36,7 @@ try:
 except ImportError:
     USER_SITE = None
 
-DEFAULT_VERSION = "6.0.2"
+DEFAULT_VERSION = "7.0"
 DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
 
 def _python_cmd(*args):
diff --git a/setuptools/version.py b/setuptools/version.py
index c974945d..29524eba 100644
--- a/setuptools/version.py
+++ b/setuptools/version.py
@@ -1 +1 @@
-__version__ = '6.0.2'
+__version__ = '7.0'
-- 
cgit v1.2.3


From 5e62aa3b59398252faef0d638a0f087d6c682800 Mon Sep 17 00:00:00 2001
From: "Jason R. Coombs" 
Date: Sat, 27 Sep 2014 16:25:13 -0400
Subject: Added tag 7.0b1 for changeset 8b8a52665803

---
 .hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.hgtags b/.hgtags
index ff59322b..d3538875 100644
--- a/.hgtags
+++ b/.hgtags
@@ -156,3 +156,4 @@ a1fc0220bfa3581158688789f6dfdc00672eb99b 5.6
 67550a8ed9f4ef49ee5a31f433adbf5a0eaeccf9 5.8
 755cbfd3743ffb186cdf7e20be8e61dbdaa22503 6.0
 bc6655b4acf205dd9f25c702955645656077398a 6.0.1
+8b8a52665803abf0bc2d2e892fc59ce5416f4bf7 7.0b1
-- 
cgit v1.2.3


From 4b8fbbf7f064f170b0e0040f44bb528147ddedc9 Mon Sep 17 00:00:00 2001
From: Donald Stufft 
Date: Wed, 19 Nov 2014 13:14:19 -0500
Subject: Upgrade packaging to 14.3

---
 pkg_resources.py                           |   4 +-
 setuptools/_vendor/packaging/__about__.py  |   2 +-
 setuptools/_vendor/packaging/_compat.py    |  13 +
 setuptools/_vendor/packaging/specifiers.py | 732 +++++++++++++++++++++++++++++
 setuptools/_vendor/packaging/version.py    | 412 +---------------
 setuptools/_vendor/vendored.txt            |   2 +-
 6 files changed, 751 insertions(+), 414 deletions(-)
 create mode 100644 setuptools/_vendor/packaging/specifiers.py

diff --git a/pkg_resources.py b/pkg_resources.py
index daf7732c..422b31b5 100644
--- a/pkg_resources.py
+++ b/pkg_resources.py
@@ -77,9 +77,11 @@ except ImportError:
 
 try:
     import packaging.version
+    import packaging.specifiers
 except ImportError:
     # fallback to vendored version
     import setuptools._vendor.packaging.version
+    import setuptools._vendor.packaging.specifiers
     packaging = setuptools._vendor.packaging
 
 # For compatibility, expose packaging.version.parse as parse_version
@@ -2678,7 +2680,7 @@ class Requirement:
         """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
         self.unsafe_name, project_name = project_name, safe_name(project_name)
         self.project_name, self.key = project_name, project_name.lower()
-        self.specifier = packaging.version.Specifier(
+        self.specifier = packaging.specifiers.SpecifierSet(
             ",".join(["".join([x, y]) for x, y in specs])
         )
         self.specs = specs
diff --git a/setuptools/_vendor/packaging/__about__.py b/setuptools/_vendor/packaging/__about__.py
index b64681e4..481589e7 100644
--- a/setuptools/_vendor/packaging/__about__.py
+++ b/setuptools/_vendor/packaging/__about__.py
@@ -22,7 +22,7 @@ __title__ = "packaging"
 __summary__ = "Core utilities for Python packages"
 __uri__ = "https://github.com/pypa/packaging"
 
-__version__ = "14.2"
+__version__ = "14.3"
 
 __author__ = "Donald Stufft"
 __email__ = "donald@stufft.io"
diff --git a/setuptools/_vendor/packaging/_compat.py b/setuptools/_vendor/packaging/_compat.py
index f2ff3834..5c396cea 100644
--- a/setuptools/_vendor/packaging/_compat.py
+++ b/setuptools/_vendor/packaging/_compat.py
@@ -25,3 +25,16 @@ if PY3:
     string_types = str,
 else:
     string_types = basestring,
+
+
+def with_metaclass(meta, *bases):
+    """
+    Create a base class with a metaclass.
+    """
+    # This requires a bit of explanation: the basic idea is to make a dummy
+    # metaclass for one level of class instantiation that replaces itself with
+    # the actual metaclass.
+    class metaclass(meta):
+        def __new__(cls, name, this_bases, d):
+            return meta(name, bases, d)
+    return type.__new__(metaclass, 'temporary_class', (), {})
diff --git a/setuptools/_vendor/packaging/specifiers.py b/setuptools/_vendor/packaging/specifiers.py
new file mode 100644
index 00000000..bea4a398
--- /dev/null
+++ b/setuptools/_vendor/packaging/specifiers.py
@@ -0,0 +1,732 @@
+# Copyright 2014 Donald Stufft
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from __future__ import absolute_import, division, print_function
+
+import abc
+import functools
+import itertools
+import re
+
+from ._compat import string_types, with_metaclass
+from .version import Version, LegacyVersion, parse
+
+
+class InvalidSpecifier(ValueError):
+    """
+    An invalid specifier was found, users should refer to PEP 440.
+    """
+
+
+class BaseSpecifier(with_metaclass(abc.ABCMeta, object)):
+
+    @abc.abstractmethod
+    def __str__(self):
+        """
+        Returns the str representation of this Specifier like object. This
+        should be representative of the Specifier itself.
+        """
+
+    @abc.abstractmethod
+    def __hash__(self):
+        """
+        Returns a hash value for this Specifier like object.
+        """
+
+    @abc.abstractmethod
+    def __eq__(self, other):
+        """
+        Returns a boolean representing whether or not the two Specifier like
+        objects are equal.
+        """
+
+    @abc.abstractmethod
+    def __ne__(self, other):
+        """
+        Returns a boolean representing whether or not the two Specifier like
+        objects are not equal.
+        """
+
+    @abc.abstractproperty
+    def prereleases(self):
+        """
+        Returns whether or not pre-releases as a whole are allowed by this
+        specifier.
+        """
+
+    @prereleases.setter
+    def prereleases(self, value):
+        """
+        Sets whether or not pre-releases as a whole are allowed by this
+        specifier.
+        """
+
+    @abc.abstractmethod
+    def contains(self, item, prereleases=None):
+        """
+        Determines if the given item is contained within this specifier.
+        """
+
+    @abc.abstractmethod
+    def filter(self, iterable, prereleases=None):
+        """
+        Takes an iterable of items and filters them so that only items which
+        are contained within this specifier are allowed in it.
+        """
+
+
+class _IndividualSpecifier(BaseSpecifier):
+
+    _operators = {}
+
+    def __init__(self, spec="", prereleases=None):
+        match = self._regex.search(spec)
+        if not match:
+            raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
+
+        self._spec = (
+            match.group("operator").strip(),
+            match.group("version").strip(),
+        )
+
+        # Store whether or not this Specifier should accept prereleases
+        self._prereleases = prereleases
+
+    def __repr__(self):
+        pre = (
+            ", prereleases={0!r}".format(self.prereleases)
+            if self._prereleases is not None
+            else ""
+        )
+
+        return "<{0}({1!r}{2})>".format(
+            self.__class__.__name__,
+            str(self),
+            pre,
+        )
+
+    def __str__(self):
+        return "{0}{1}".format(*self._spec)
+
+    def __hash__(self):
+        return hash(self._spec)
+
+    def __eq__(self, other):
+        if isinstance(other, string_types):
+            try:
+                other = self.__class__(other)
+            except InvalidSpecifier:
+                return NotImplemented
+        elif not isinstance(other, self.__class__):
+            return NotImplemented
+
+        return self._spec == other._spec
+
+    def __ne__(self, other):
+        if isinstance(other, string_types):
+            try:
+                other = self.__class__(other)
+            except InvalidSpecifier:
+                return NotImplemented
+        elif not isinstance(other, self.__class__):
+            return NotImplemented
+
+        return self._spec != other._spec
+
+    def _get_operator(self, op):
+        return getattr(self, "_compare_{0}".format(self._operators[op]))
+
+    def _coerce_version(self, version):
+        if not isinstance(version, (LegacyVersion, Version)):
+            version = parse(version)
+        return version
+
+    @property
+    def prereleases(self):
+        return self._prereleases
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+    def contains(self, item, prereleases=None):
+        # Determine if prereleases are to be allowed or not.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # Normalize item to a Version or LegacyVersion, this allows us to have
+        # a shortcut for ``"2.0" in Specifier(">=2")
+        item = self._coerce_version(item)
+
+        # Determine if we should be supporting prereleases in this specifier
+        # or not, if we do not support prereleases than we can short circuit
+        # logic if this version is a prereleases.
+        if item.is_prerelease and not prereleases:
+            return False
+
+        # Actually do the comparison to determine if this item is contained
+        # within this Specifier or not.
+        return self._get_operator(self._spec[0])(item, self._spec[1])
+
+    def filter(self, iterable, prereleases=None):
+        yielded = False
+        found_prereleases = []
+
+        kw = {"prereleases": prereleases if prereleases is not None else True}
+
+        # Attempt to iterate over all the values in the iterable and if any of
+        # them match, yield them.
+        for version in iterable:
+            parsed_version = self._coerce_version(version)
+
+            if self.contains(parsed_version, **kw):
+                # 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)):
+                    found_prereleases.append(version)
+                # Either this is not a prerelease, or we should have been
+                # accepting prereleases from the begining.
+                else:
+                    yielded = True
+                    yield version
+
+        # Now that we've iterated over everything, determine if we've yielded
+        # any values, and if we have not and we have any prereleases stored up
+        # then we will go ahead and yield the prereleases.
+        if not yielded and found_prereleases:
+            for version in found_prereleases:
+                yield version
+
+
+class LegacySpecifier(_IndividualSpecifier):
+
+    _regex = re.compile(
+        r"""
+        ^
+        \s*
+        (?P(==|!=|<=|>=|<|>))
+        \s*
+        (?P
+            [^\s]* # We just match everything, except for whitespace since this
+                   # is a "legacy" specifier and the version string can be just
+                   # about anything.
+        )
+        \s*
+        $
+        """,
+        re.VERBOSE | re.IGNORECASE,
+    )
+
+    _operators = {
+        "==": "equal",
+        "!=": "not_equal",
+        "<=": "less_than_equal",
+        ">=": "greater_than_equal",
+        "<": "less_than",
+        ">": "greater_than",
+    }
+
+    def _coerce_version(self, version):
+        if not isinstance(version, LegacyVersion):
+            version = LegacyVersion(str(version))
+        return version
+
+    def _compare_equal(self, prospective, spec):
+        return prospective == self._coerce_version(spec)
+
+    def _compare_not_equal(self, prospective, spec):
+        return prospective != self._coerce_version(spec)
+
+    def _compare_less_than_equal(self, prospective, spec):
+        return prospective <= self._coerce_version(spec)
+
+    def _compare_greater_than_equal(self, prospective, spec):
+        return prospective >= self._coerce_version(spec)
+
+    def _compare_less_than(self, prospective, spec):
+        return prospective < self._coerce_version(spec)
+
+    def _compare_greater_than(self, prospective, spec):
+        return prospective > self._coerce_version(spec)
+
+
+def _require_version_compare(fn):
+    @functools.wraps(fn)
+    def wrapped(self, prospective, spec):
+        if not isinstance(prospective, Version):
+            return False
+        return fn(self, prospective, spec)
+    return wrapped
+
+
+class Specifier(_IndividualSpecifier):
+
+    _regex = re.compile(
+        r"""
+        ^
+        \s*
+        (?P(~=|==|!=|<=|>=|<|>|===))
+        (?P
+            (?:
+                # The identity operators allow for an escape hatch that will
+                # do an exact string match of the version you wish to install.
+                # This will not be parsed by PEP 440 and we cannot determine
+                # any semantic meaning from it. This operator is discouraged
+                # but included entirely as an escape hatch.
+                (?<====)  # Only match for the identity operator
+                \s*
+                [^\s]*    # We just match everything, except for whitespace
+                          # since we are only testing for strict identity.
+            )
+            |
+            (?:
+                # The (non)equality operators allow for wild card and local
+                # versions to be specified so we have to define these two
+                # operators separately to enable that.
+                (?<===|!=)            # Only match for equals and not equals
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)*   # release
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+
+                # You cannot use a wild card and a dev or local version
+                # together so group them with a | and make them optional.
+                (?:
+                    (?:[-_\.]?dev[-_\.]?[0-9]*)?         # dev release
+                    (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
+                    |
+                    \.\*  # Wild card syntax of .*
+                )?
+            )
+            |
+            (?:
+                # The compatible operator requires at least two digits in the
+                # release segment.
+                (?<=~=)               # Only match for the compatible operator
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)+   # release  (We have a + instead of a *)
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
+            )
+            |
+            (?:
+                # All other operators only allow a sub set of what the
+                # (non)equality operators do. Specifically they do not allow
+                # local versions to be specified nor do they allow the prefix
+                # matching wild cards.
+                (?=": "greater_than_equal",
+        "<": "less_than",
+        ">": "greater_than",
+        "===": "arbitrary",
+    }
+
+    @_require_version_compare
+    def _compare_compatible(self, prospective, spec):
+        # Compatible releases have an equivalent combination of >= and ==. That
+        # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to
+        # implement this in terms of the other specifiers instead of
+        # implementing it ourselves. The only thing we need to do is construct
+        # the other specifiers.
+
+        # We want everything but the last item in the version, but we want to
+        # ignore post and dev releases and we want to treat the pre-release as
+        # it's own separate segment.
+        prefix = ".".join(
+            list(
+                itertools.takewhile(
+                    lambda x: (not x.startswith("post")
+                               and not x.startswith("dev")),
+                    _version_split(spec),
+                )
+            )[:-1]
+        )
+
+        # Add the prefix notation to the end of our string
+        prefix += ".*"
+
+        return (self._get_operator(">=")(prospective, spec)
+                and self._get_operator("==")(prospective, prefix))
+
+    @_require_version_compare
+    def _compare_equal(self, prospective, spec):
+        # We need special logic to handle prefix matching
+        if spec.endswith(".*"):
+            # Split the spec out by dots, and pretend that there is an implicit
+            # dot in between a release segment and a pre-release segment.
+            spec = _version_split(spec[:-2])  # Remove the trailing .*
+
+            # Split the prospective version out by dots, and pretend that there
+            # is an implicit dot in between a release segment and a pre-release
+            # segment.
+            prospective = _version_split(str(prospective))
+
+            # 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)]
+
+            # Pad out our two sides with zeros so that they both equal the same
+            # length.
+            spec, prospective = _pad_version(spec, prospective)
+        else:
+            # Convert our spec string into a Version
+            spec = Version(spec)
+
+            # If the specifier does not have a local segment, then we want to
+            # act as if the prospective version also does not have a local
+            # segment.
+            if not spec.local:
+                prospective = Version(prospective.public)
+
+        return prospective == spec
+
+    @_require_version_compare
+    def _compare_not_equal(self, prospective, spec):
+        return not self._compare_equal(prospective, spec)
+
+    @_require_version_compare
+    def _compare_less_than_equal(self, prospective, spec):
+        return prospective <= Version(spec)
+
+    @_require_version_compare
+    def _compare_greater_than_equal(self, prospective, spec):
+        return prospective >= Version(spec)
+
+    @_require_version_compare
+    def _compare_less_than(self, prospective, spec):
+        # Less than are defined as exclusive operators, this implies that
+        # pre-releases do not match for the same series as the spec. This is
+        # implemented by making V imply !=V.*.
+        return (prospective > Version(spec)
+                and self._get_operator("!=")(prospective, spec + ".*"))
+
+    def _compare_arbitrary(self, prospective, spec):
+        return str(prospective).lower() == str(spec).lower()
+
+    @property
+    def prereleases(self):
+        # If there is an explicit prereleases set for this, then we'll just
+        # blindly use that.
+        if self._prereleases is not None:
+            return self._prereleases
+
+        # Look at all of our specifiers and determine if they are inclusive
+        # operators, and if they are if they are including an explicit
+        # prerelease.
+        operator, version = self._spec
+        if operator in ["==", ">=", "<=", "~="]:
+            # The == specifier can include a trailing .*, if it does we
+            # want to remove before parsing.
+            if operator == "==" and version.endswith(".*"):
+                version = version[:-2]
+
+            # Parse the version, and if it is a pre-release than this
+            # specifier allows pre-releases.
+            if parse(version).is_prerelease:
+                return True
+
+        return False
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+
+_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")
+
+
+def _version_split(version):
+    result = []
+    for item in version.split("."):
+        match = _prefix_regex.search(item)
+        if match:
+            result.extend(match.groups())
+        else:
+            result.append(item)
+    return result
+
+
+def _pad_version(left, right):
+    left_split, right_split = [], []
+
+    # Get the release segment of our versions
+    left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left)))
+    right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
+
+    # Get the rest of our versions
+    left_split.append(left[len(left_split):])
+    right_split.append(left[len(right_split):])
+
+    # 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])),
+    )
+
+    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.
+        specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
+
+        # Parsed each individual specifier, attempting first to make it a
+        # Specifier and falling back to a LegacySpecifier.
+        parsed = set()
+        for specifier in specifiers:
+            try:
+                parsed.add(Specifier(specifier))
+            except InvalidSpecifier:
+                parsed.add(LegacySpecifier(specifier))
+
+        # Turn our parsed specifiers into a frozen set and save them for later.
+        self._specs = frozenset(parsed)
+
+        # Store our prereleases value so we can use it later to determine if
+        # we accept prereleases or not.
+        self._prereleases = prereleases
+
+    def __repr__(self):
+        pre = (
+            ", prereleases={0!r}".format(self.prereleases)
+            if self._prereleases is not None
+            else ""
+        )
+
+        return "".format(str(self), pre)
+
+    def __str__(self):
+        return ",".join(sorted(str(s) for s in self._specs))
+
+    def __hash__(self):
+        return hash(self._specs)
+
+    def __and__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        specifier = SpecifierSet()
+        specifier._specs = frozenset(self._specs | other._specs)
+
+        if self._prereleases is None and other._prereleases is not None:
+            specifier._prereleases = other._prereleases
+        elif self._prereleases is not None and other._prereleases is None:
+            specifier._prereleases = self._prereleases
+        elif self._prereleases == other._prereleases:
+            specifier._prereleases = self._prereleases
+        else:
+            raise ValueError(
+                "Cannot combine SpecifierSets with True and False prerelease "
+                "overrides."
+            )
+
+        return specifier
+
+    def __eq__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif isinstance(other, _IndividualSpecifier):
+            other = SpecifierSet(str(other))
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        return self._specs == other._specs
+
+    def __ne__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif isinstance(other, _IndividualSpecifier):
+            other = SpecifierSet(str(other))
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        return self._specs != other._specs
+
+    @property
+    def prereleases(self):
+        # If we have been given an explicit prerelease modifier, then we'll
+        # pass that through here.
+        if self._prereleases is not None:
+            return self._prereleases
+
+        # Otherwise we'll see if any of the given specifiers accept
+        # prereleases, if any of them do we'll return True, otherwise False.
+        # Note: The use of any() here means that an empty set of specifiers
+        #       will always return False, this is an explicit design decision.
+        return any(s.prereleases for s in self._specs)
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+    def contains(self, item, prereleases=None):
+        # Ensure that our item is a Version or LegacyVersion instance.
+        if not isinstance(item, (LegacyVersion, Version)):
+            item = parse(item)
+
+        # We can determine if we're going to allow pre-releases by looking to
+        # see if any of the underlying items supports them. If none of them do
+        # and this item is a pre-release then we do not allow it and we can
+        # short circuit that here.
+        # Note: This means that 1.0.dev1 would not be contained in something
+        #       like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0
+        if (not (self.prereleases or prereleases)) and item.is_prerelease:
+            return False
+
+        # Determine if we're forcing a prerelease or not, we bypass
+        # self.prereleases here and use self._prereleases because we want to
+        # only take into consideration actual *forced* values. The underlying
+        # specifiers will handle the other logic.
+        # The logic here is: If prereleases is anything but None, we'll just
+        #                    go aheand and continue to use that. However if
+        #                    prereleases is None, then we'll use whatever the
+        #                    value of self._prereleases is as long as it is not
+        #                    None itself.
+        if prereleases is None and self._prereleases is not None:
+            prereleases = self._prereleases
+
+        # We simply dispatch to the underlying specs here to make sure that the
+        # 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
+        )
+
+    def filter(self, iterable, prereleases=None):
+        # Determine if we're forcing a prerelease or not, we bypass
+        # self.prereleases here and use self._prereleases because we want to
+        # only take into consideration actual *forced* values. The underlying
+        # specifiers will handle the other logic.
+        # The logic here is: If prereleases is anything but None, we'll just
+        #                    go aheand and continue to use that. However if
+        #                    prereleases is None, then we'll use whatever the
+        #                    value of self._prereleases is as long as it is not
+        #                    None itself.
+        if prereleases is None and self._prereleases is not None:
+            prereleases = self._prereleases
+
+        # If we have any specifiers, then we want to wrap our iterable in the
+        # filter method for each one, this will act as a logical AND amongst
+        # each specifier.
+        if self._specs:
+            for spec in self._specs:
+                iterable = spec.filter(iterable, prereleases=prereleases)
+            return iterable
+        # If we do not have any specifiers, then we need to have a rough filter
+        # which will filter out any pre-releases, unless there are no final
+        # releases, and which will filter out LegacyVersion in general.
+        else:
+            filtered = []
+            found_prereleases = []
+
+            for item in iterable:
+                # Ensure that we some kind of Version class for this item.
+                if not isinstance(item, (LegacyVersion, Version)):
+                    parsed_version = parse(item)
+                else:
+                    parsed_version = item
+
+                # Filter out any item which is parsed as a LegacyVersion
+                if isinstance(parsed_version, LegacyVersion):
+                    continue
+
+                # Store any item which is a pre-release for later unless we've
+                # already found a final version or we are accepting prereleases
+                if parsed_version.is_prerelease and not prereleases:
+                    if not filtered:
+                        found_prereleases.append(item)
+                else:
+                    filtered.append(item)
+
+            # If we've found no items except for pre-releases, then we'll go
+            # ahead and use the pre-releases
+            if not filtered and found_prereleases and prereleases is None:
+                return found_prereleases
+
+            return filtered
diff --git a/setuptools/_vendor/packaging/version.py b/setuptools/_vendor/packaging/version.py
index 0affe899..e76e9607 100644
--- a/setuptools/_vendor/packaging/version.py
+++ b/setuptools/_vendor/packaging/version.py
@@ -17,13 +17,11 @@ import collections
 import itertools
 import re
 
-from ._compat import string_types
 from ._structures import Infinity
 
 
 __all__ = [
-    "parse", "Version", "LegacyVersion", "InvalidVersion", "Specifier",
-    "InvalidSpecifier",
+    "parse", "Version", "LegacyVersion", "InvalidVersion",
 ]
 
 
@@ -376,411 +374,3 @@ def _cmpkey(epoch, release, pre, post, dev, local):
         )
 
     return epoch, release, pre, post, dev, local
-
-
-class InvalidSpecifier(ValueError):
-    """
-    An invalid specifier was found, users should refer to PEP 440.
-    """
-
-
-class Specifier(object):
-
-    _regex = re.compile(
-        r"""
-        ^
-        \s*
-        (?P(~=|==|!=|<=|>=|<|>|===))
-        (?P
-            (?:
-                # The identity operators allow for an escape hatch that will
-                # do an exact string match of the version you wish to install.
-                # This will not be parsed by PEP 440 and we cannot determine
-                # any semantic meaning from it. This operator is discouraged
-                # but included entirely as an escape hatch.
-                (?<====)  # Only match for the identity operator
-                \s*
-                [^\s]*    # We just match everything, except for whitespace
-                          # since we are only testing for strict identity.
-            )
-            |
-            (?:
-                # The (non)equality operators allow for wild card and local
-                # versions to be specified so we have to define these two
-                # operators separately to enable that.
-                (?<===|!=)            # Only match for equals and not equals
-
-                \s*
-                v?
-                (?:[0-9]+!)?          # epoch
-                [0-9]+(?:\.[0-9]+)*   # release
-                (?:                   # pre release
-                    [-_\.]?
-                    (a|b|c|rc|alpha|beta|pre|preview)
-                    [-_\.]?
-                    [0-9]*
-                )?
-                (?:                   # post release
-                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
-                )?
-
-                # You cannot use a wild card and a dev or local version
-                # together so group them with a | and make them optional.
-                (?:
-                    (?:[-_\.]?dev[-_\.]?[0-9]*)?         # dev release
-                    (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
-                    |
-                    \.\*  # Wild card syntax of .*
-                )?
-            )
-            |
-            (?:
-                # The compatible operator requires at least two digits in the
-                # release segment.
-                (?<=~=)               # Only match for the compatible operator
-
-                \s*
-                v?
-                (?:[0-9]+!)?          # epoch
-                [0-9]+(?:\.[0-9]+)+   # release  (We have a + instead of a *)
-                (?:                   # pre release
-                    [-_\.]?
-                    (a|b|c|rc|alpha|beta|pre|preview)
-                    [-_\.]?
-                    [0-9]*
-                )?
-                (?:                                   # post release
-                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
-                )?
-                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
-            )
-            |
-            (?:
-                # All other operators only allow a sub set of what the
-                # (non)equality operators do. Specifically they do not allow
-                # local versions to be specified nor do they allow the prefix
-                # matching wild cards.
-                (?=": "greater_than_equal",
-        "<": "less_than",
-        ">": "greater_than",
-        "===": "arbitrary",
-    }
-
-    def __init__(self, specs="", prereleases=None):
-        # Split on comma to get each individual specification
-        _specs = set()
-        for spec in (s for s in specs.split(",") if s):
-            match = self._regex.search(spec)
-            if not match:
-                raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
-
-            _specs.add(
-                (
-                    match.group("operator").strip(),
-                    match.group("version").strip(),
-                )
-            )
-
-        # Set a frozen set for our specifications
-        self._specs = frozenset(_specs)
-
-        # Store whether or not this Specifier should accept prereleases
-        self._prereleases = prereleases
-
-    def __repr__(self):
-        return "".format(repr(str(self)))
-
-    def __str__(self):
-        return ",".join(["".join(s) for s in sorted(self._specs)])
-
-    def __hash__(self):
-        return hash(self._specs)
-
-    def __and__(self, other):
-        if isinstance(other, string_types):
-            other = Specifier(other)
-        elif not isinstance(other, Specifier):
-            return NotImplemented
-
-        return self.__class__(",".join([str(self), str(other)]))
-
-    def __eq__(self, other):
-        if isinstance(other, string_types):
-            other = Specifier(other)
-        elif not isinstance(other, Specifier):
-            return NotImplemented
-
-        return self._specs == other._specs
-
-    def __ne__(self, other):
-        if isinstance(other, string_types):
-            other = Specifier(other)
-        elif not isinstance(other, Specifier):
-            return NotImplemented
-
-        return self._specs != other._specs
-
-    def _get_operator(self, op):
-        return getattr(self, "_compare_{0}".format(self._operators[op]))
-
-    def _compare_compatible(self, prospective, spec):
-        # Compatible releases have an equivalent combination of >= and ==. That
-        # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to
-        # implement this in terms of the other specifiers instead of
-        # implementing it ourselves. The only thing we need to do is construct
-        # the other specifiers.
-
-        # We want everything but the last item in the version, but we want to
-        # ignore post and dev releases and we want to treat the pre-release as
-        # it's own separate segment.
-        prefix = ".".join(
-            list(
-                itertools.takewhile(
-                    lambda x: (not x.startswith("post")
-                               and not x.startswith("dev")),
-                    _version_split(spec),
-                )
-            )[:-1]
-        )
-
-        # Add the prefix notation to the end of our string
-        prefix += ".*"
-
-        return (self._get_operator(">=")(prospective, spec)
-                and self._get_operator("==")(prospective, prefix))
-
-    def _compare_equal(self, prospective, spec):
-        # We need special logic to handle prefix matching
-        if spec.endswith(".*"):
-            # Split the spec out by dots, and pretend that there is an implicit
-            # dot in between a release segment and a pre-release segment.
-            spec = _version_split(spec[:-2])  # Remove the trailing .*
-
-            # Split the prospective version out by dots, and pretend that there
-            # is an implicit dot in between a release segment and a pre-release
-            # segment.
-            prospective = _version_split(str(prospective))
-
-            # 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)]
-
-            # Pad out our two sides with zeros so that they both equal the same
-            # length.
-            spec, prospective = _pad_version(spec, prospective)
-        else:
-            # Convert our spec string into a Version
-            spec = Version(spec)
-
-            # If the specifier does not have a local segment, then we want to
-            # act as if the prospective version also does not have a local
-            # segment.
-            if not spec.local:
-                prospective = Version(prospective.public)
-
-        return prospective == spec
-
-    def _compare_not_equal(self, prospective, spec):
-        return not self._compare_equal(prospective, spec)
-
-    def _compare_less_than_equal(self, prospective, spec):
-        return prospective <= Version(spec)
-
-    def _compare_greater_than_equal(self, prospective, spec):
-        return prospective >= Version(spec)
-
-    def _compare_less_than(self, prospective, spec):
-        # Less than are defined as exclusive operators, this implies that
-        # pre-releases do not match for the same series as the spec. This is
-        # implemented by making V imply !=V.*.
-        return (prospective > Version(spec)
-                and self._get_operator("!=")(prospective, spec + ".*"))
-
-    def _compare_arbitrary(self, prospective, spec):
-        return str(prospective).lower() == str(spec).lower()
-
-    @property
-    def prereleases(self):
-        # If there is an explicit prereleases set for this, then we'll just
-        # blindly use that.
-        if self._prereleases is not None:
-            return self._prereleases
-
-        # Look at all of our specifiers and determine if they are inclusive
-        # operators, and if they are if they are including an explicit
-        # prerelease.
-        for spec, version in self._specs:
-            if spec in ["==", ">=", "<=", "~="]:
-                # The == specifier can include a trailing .*, if it does we
-                # want to remove before parsing.
-                if spec == "==" and version.endswith(".*"):
-                    version = version[:-2]
-
-                # Parse the version, and if it is a pre-release than this
-                # specifier allows pre-releases.
-                if parse(version).is_prerelease:
-                    return True
-
-        return False
-
-    @prereleases.setter
-    def prereleases(self, value):
-        self._prereleases = value
-
-    def contains(self, item, prereleases=None):
-        # Determine if prereleases are to be allowed or not.
-        if prereleases is None:
-            prereleases = self.prereleases
-
-        # Normalize item to a Version or LegacyVersion, this allows us to have
-        # a shortcut for ``"2.0" in Specifier(">=2")
-        if isinstance(item, (Version, LegacyVersion)):
-            version_item = item
-        else:
-            try:
-                version_item = Version(item)
-            except ValueError:
-                version_item = LegacyVersion(item)
-
-        # Determine if we should be supporting prereleases in this specifier
-        # or not, if we do not support prereleases than we can short circuit
-        # logic if this version is a prereleases.
-        if version_item.is_prerelease and not prereleases:
-            return False
-
-        # Detect if we have any specifiers, if we do not then anything matches
-        # and we can short circuit all this logic.
-        if not self._specs:
-            return True
-
-        # If we're operating on a LegacyVersion, then we can only support
-        # arbitrary comparison so do a quick check to see if the spec contains
-        # any non arbitrary specifiers
-        if isinstance(version_item, LegacyVersion):
-            if any(op != "===" for op, _ in self._specs):
-                return False
-
-        # Ensure that the passed in version matches all of our version
-        # specifiers
-        return all(
-            self._get_operator(op)(
-                version_item if op != "===" else item,
-                spec,
-            )
-            for op, spec, in self._specs
-        )
-
-    def filter(self, iterable, prereleases=None):
-        iterable = list(iterable)
-        yielded = False
-        found_prereleases = []
-
-        kw = {"prereleases": prereleases if prereleases is not None else True}
-
-        # Attempt to iterate over all the values in the iterable and if any of
-        # them match, yield them.
-        for version in iterable:
-            if not isinstance(version, (Version, LegacyVersion)):
-                parsed_version = parse(version)
-            else:
-                parsed_version = version
-
-            if self.contains(parsed_version, **kw):
-                # 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)):
-                    found_prereleases.append(version)
-                # Either this is not a prerelease, or we should have been
-                # accepting prereleases from the begining.
-                else:
-                    yielded = True
-                    yield version
-
-        # Now that we've iterated over everything, determine if we've yielded
-        # any values, and if we have not and we have any prereleases stored up
-        # then we will go ahead and yield the prereleases.
-        if not yielded and found_prereleases:
-            for version in found_prereleases:
-                yield version
-
-
-_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")
-
-
-def _version_split(version):
-    result = []
-    for item in version.split("."):
-        match = _prefix_regex.search(item)
-        if match:
-            result.extend(match.groups())
-        else:
-            result.append(item)
-    return result
-
-
-def _pad_version(left, right):
-    left_split, right_split = [], []
-
-    # Get the release segment of our versions
-    left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left)))
-    right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
-
-    # Get the rest of our versions
-    left_split.append(left[len(left_split):])
-    right_split.append(left[len(right_split):])
-
-    # 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])),
-    )
-
-    return (
-        list(itertools.chain(*left_split)),
-        list(itertools.chain(*right_split)),
-    )
diff --git a/setuptools/_vendor/vendored.txt b/setuptools/_vendor/vendored.txt
index df383d8b..b86bba00 100644
--- a/setuptools/_vendor/vendored.txt
+++ b/setuptools/_vendor/vendored.txt
@@ -1 +1 @@
-packaging==14.2
+packaging==14.3
-- 
cgit v1.2.3


From a15a276e1a7425ae884352958f87c9e506d2a1c8 Mon Sep 17 00:00:00 2001
From: Donald Stufft 
Date: Wed, 19 Nov 2014 13:15:01 -0500
Subject: Remove packaging from setup.py

---
 setup.py | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/setup.py b/setup.py
index cc0e4684..bac4e29d 100755
--- a/setup.py
+++ b/setup.py
@@ -198,9 +198,6 @@ setup_params = dict(
         Topic :: System :: Systems Administration
         Topic :: Utilities
         """).strip().splitlines(),
-    install_requires=[
-        "packaging>=14.2,<15.0.dev0",
-    ],
     extras_require={
         "ssl:sys_platform=='win32'": "wincertstore==0.2",
         "certs": "certifi==1.0.1",
-- 
cgit v1.2.3


From 4ae526d52609fe2a7515d87e4c0d047a826411a7 Mon Sep 17 00:00:00 2001
From: Donald Stufft 
Date: Wed, 19 Nov 2014 13:38:16 -0500
Subject: Always use the vendored copy of packaging

---
 pkg_resources.py                   | 11 +++--------
 setuptools/tests/test_resources.py |  9 +++------
 2 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/pkg_resources.py b/pkg_resources.py
index 422b31b5..a3eef28f 100644
--- a/pkg_resources.py
+++ b/pkg_resources.py
@@ -75,14 +75,9 @@ try:
 except ImportError:
     pass
 
-try:
-    import packaging.version
-    import packaging.specifiers
-except ImportError:
-    # fallback to vendored version
-    import setuptools._vendor.packaging.version
-    import setuptools._vendor.packaging.specifiers
-    packaging = setuptools._vendor.packaging
+import setuptools._vendor.packaging.version
+import setuptools._vendor.packaging.specifiers
+packaging = setuptools._vendor.packaging
 
 # For compatibility, expose packaging.version.parse as parse_version
 parse_version = packaging.version.parse
diff --git a/setuptools/tests/test_resources.py b/setuptools/tests/test_resources.py
index 8336a85d..a8520e12 100644
--- a/setuptools/tests/test_resources.py
+++ b/setuptools/tests/test_resources.py
@@ -8,12 +8,9 @@ import tempfile
 import shutil
 from unittest import TestCase
 
-try:
-    import packaging.version
-except ImportError:
-    # fallback to vendored version
-    import setuptools._vendor.packaging.version
-    packaging = setuptools._vendor.packaging
+import setuptools._vendor.packaging.version
+import setuptools._vendor.packaging.specifiers
+packaging = setuptools._vendor.packaging
 
 import pkg_resources
 from pkg_resources import (parse_requirements, VersionConflict, parse_version,
-- 
cgit v1.2.3


From 6f74eb003ba0df2049a92c60e2ebd6eaa4aba030 Mon Sep 17 00:00:00 2001
From: Donald Stufft 
Date: Wed, 19 Nov 2014 13:38:32 -0500
Subject: Fix the use of pacakging.version.Specifier

---
 setuptools/tests/test_resources.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/setuptools/tests/test_resources.py b/setuptools/tests/test_resources.py
index a8520e12..356e1ed4 100644
--- a/setuptools/tests/test_resources.py
+++ b/setuptools/tests/test_resources.py
@@ -342,7 +342,7 @@ class RequirementsTests(TestCase):
         self.assertEqual(r2.extras, ("bar","foo"))  # extras are normalized
         self.assertEqual(hash(r1), hash(r2))
         self.assertEqual(
-            hash(r1), hash(("twisted", packaging.version.Specifier(">=1.2"),
+            hash(r1), hash(("twisted", packaging.specifiers.SpecifierSet(">=1.2"),
                             frozenset(["foo","bar"])))
         )
 
-- 
cgit v1.2.3


From 5fa2a4519fc0521ee15b0ce0cad136afe304eb37 Mon Sep 17 00:00:00 2001
From: Donald Stufft 
Date: Wed, 19 Nov 2014 21:40:21 -0500
Subject: fix left over merge indicator

---
 CHANGES.txt | 1 -
 1 file changed, 1 deletion(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index f4d8019a..cc2423b6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -45,7 +45,6 @@ CHANGES
 
 * Issue #262: Fixed regression in pip install due to egg-info directories
   being omitted. Re-opens Issue #118.
->>>>>>> master
 
 -----
 6.0.1
-- 
cgit v1.2.3


From 2439ceb80430a4201efac7370c90474e429ab41b Mon Sep 17 00:00:00 2001
From: "Jason R. Coombs" 
Date: Sun, 7 Dec 2014 13:20:22 -0500
Subject: Added tag 8.0b1 for changeset 850a5c155c48

---
 .hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.hgtags b/.hgtags
index 7e995132..5d8d2873 100644
--- a/.hgtags
+++ b/.hgtags
@@ -160,3 +160,4 @@ bc6655b4acf205dd9f25c702955645656077398a 6.0.1
 01271e84e5125fcc4f0f368a6e21116a5722953c 6.0.2
 7ea80190d494a766c6356fce85c844703964b6cc 6.1
 df26609c2f614f5fc9110342e4003ee8bd95cf84 7.0
+850a5c155c48b6ecfbb83b961586ea359b561522 8.0b1
-- 
cgit v1.2.3