Merge pull request #2301 from dstufft/upgrade-setuptools

Upgrade setuptools and packaging
This commit is contained in:
Donald Stufft 2015-01-02 23:01:25 -05:00
commit 7228a6a1fa
6 changed files with 116 additions and 40 deletions

View File

@ -15,10 +15,10 @@ Modifications
* progress has been modified to not use unicode literals for support for Python 3.2
Markerlib and pkg_resources
===========================
_markerlib and pkg_resources
============================
Markerlib and pkg_resources has been pulled in from setuptools 8.2.1
_markerlib and pkg_resources has been pulled in from setuptools 11.0
Note to Downstream Distributors

View File

@ -22,7 +22,7 @@ __title__ = "packaging"
__summary__ = "Core utilities for Python packages"
__uri__ = "https://github.com/pypa/packaging"
__version__ = "14.5"
__version__ = "15.0"
__author__ = "Donald Stufft"
__email__ = "donald@stufft.io"

View File

@ -458,21 +458,59 @@ class Specifier(_IndividualSpecifier):
@_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.*.
# Convert our spec to a Version instance, since we'll want to work with
# it as a version.
spec = Version(spec)
return (prospective < spec
and self._get_operator("!=")(prospective, str(spec) + ".*"))
# Check to see if the prospective version is less than the spec
# version. If it's not we can short circuit and just return False now
# instead of doing extra unneeded work.
if not prospective < spec:
return False
# This special case is here so that, unless the specifier itself
# includes is a pre-release version, that we do not accept pre-release
# versions for the version mentioned in the specifier (e.g. <3.1 should
# not match 3.1.dev0, but should match 3.0.dev0).
if not spec.is_prerelease and prospective.is_prerelease:
if Version(prospective.base_version) == Version(spec.base_version):
return False
# If we've gotten to here, it means that prospective version is both
# less than the spec version *and* it's not a pre-release of the same
# version in the spec.
return True
@_require_version_compare
def _compare_greater_than(self, prospective, spec):
# Greater 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.*.
# Convert our spec to a Version instance, since we'll want to work with
# it as a version.
spec = Version(spec)
return (prospective > spec
and self._get_operator("!=")(prospective, str(spec) + ".*"))
# Check to see if the prospective version is greater than the spec
# version. If it's not we can short circuit and just return False now
# instead of doing extra unneeded work.
if not prospective > spec:
return False
# This special case is here so that, unless the specifier itself
# includes is a post-release version, that we do not accept
# post-release versions for the version mentioned in the specifier
# (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0).
if not spec.is_postrelease and prospective.is_postrelease:
if Version(prospective.base_version) == Version(spec.base_version):
return False
# Ensure that we do not allow a local version of the version mentioned
# in the specifier, which is techincally greater than, to match.
if prospective.local is not None:
if Version(prospective.base_version) == Version(spec.base_version):
return False
# If we've gotten to here, it means that prospective version is both
# greater than the spec version *and* it's not a pre-release of the
# same version in the spec.
return True
def _compare_arbitrary(self, prospective, spec):
return str(prospective).lower() == str(spec).lower()

View File

@ -95,6 +95,10 @@ class LegacyVersion(_BaseVersion):
def public(self):
return self._version
@property
def base_version(self):
return self._version
@property
def local(self):
return None
@ -103,6 +107,10 @@ class LegacyVersion(_BaseVersion):
def is_prerelease(self):
return False
@property
def is_postrelease(self):
return False
_legacy_version_component_re = re.compile(
r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE,
@ -269,6 +277,19 @@ class Version(_BaseVersion):
def public(self):
return str(self).split("+", 1)[0]
@property
def base_version(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))
return "".join(parts)
@property
def local(self):
version_string = str(self)
@ -279,6 +300,10 @@ class Version(_BaseVersion):
def is_prerelease(self):
return bool(self._version.dev or self._version.pre)
@property
def is_postrelease(self):
return bool(self._version.post)
def _parse_letter_version(letter, number):
if letter:

View File

@ -2250,14 +2250,20 @@ class EntryPoint(object):
def load(self, require=True, env=None, installer=None):
if require:
self.require(env, installer)
entry = __import__(self.module_name, globals(), globals(),
['__name__'])
for attr in self.attrs:
try:
entry = getattr(entry, attr)
except AttributeError:
raise ImportError("%r has no %r attribute" % (entry, attr))
return entry
else:
warnings.warn(
"`require` parameter is deprecated. Use "
"EntryPoint._load instead.",
DeprecationWarning,
)
return self._load()
def _load(self):
module = __import__(self.module_name, fromlist=['__name__'], level=0)
try:
return functools.reduce(getattr, self.attrs, module)
except AttributeError as exc:
raise ImportError(str(exc))
def require(self, env=None, installer=None):
if self.extras and not self.dist:
@ -2266,6 +2272,15 @@ class EntryPoint(object):
items = working_set.resolve(reqs, env, installer)
list(map(working_set.add, items))
pattern = re.compile(
r'\s*'
r'(?P<name>[+\w. -]+?)\s*'
r'=\s*'
r'(?P<module>[\w.]+)\s*'
r'(:\s*(?P<attr>[\w.]+))?\s*'
r'(?P<extras>\[.*\])?\s*$'
)
@classmethod
def parse(cls, src, dist=None):
"""Parse a single entry point from string `src`
@ -2277,25 +2292,23 @@ class EntryPoint(object):
The entry name and module name are required, but the ``:attrs`` and
``[extras]`` parts are optional
"""
try:
attrs = extras = ()
name, value = src.split('=', 1)
if '[' in value:
value, extras = value.split('[', 1)
req = Requirement.parse("x[" + extras)
if req.specs:
raise ValueError
extras = req.extras
if ':' in value:
value, attrs = value.split(':', 1)
if not MODULE(attrs.rstrip()):
raise ValueError
attrs = attrs.rstrip().split('.')
except ValueError:
m = cls.pattern.match(src)
if not m:
msg = "EntryPoint must be in 'name=module:attrs [extras]' format"
raise ValueError(msg, src)
else:
return cls(name.strip(), value.strip(), attrs, extras, dist)
res = m.groupdict()
extras = cls._parse_extras(res['extras'])
attrs = res['attr'].split('.') if res['attr'] else ()
return cls(res['name'], res['module'], attrs, extras, dist)
@classmethod
def _parse_extras(cls, extras_spec):
if not extras_spec:
return ()
req = Requirement.parse('x' + extras_spec)
if req.specs:
raise ValueError()
return req.extras
@classmethod
def parse_group(cls, group, lines, dist=None):

View File

@ -8,4 +8,4 @@ CacheControl==0.10.7
lockfile==0.10.2
progress==1.2
ipaddress==1.0.7 # Only needed on 2.6, 2.7, and 3.2
packaging==14.5
packaging==15.0