Skip to content

Commit

Permalink
Merge pull request #1752 from dstufft/upgrade-setuptools
Browse files Browse the repository at this point in the history
Upgrade bundled pkg_resources and _markerlib to 3.4.4
  • Loading branch information
dstufft committed Apr 24, 2014
2 parents 830440d + ba6a08b commit 37ded08
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 36 deletions.
2 changes: 1 addition & 1 deletion pip/_vendor/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Modifications
Markerlib and pkg_resources
===========================

Markerlib and pkg_resources has been pulled in from setuptools 2.1
Markerlib and pkg_resources has been pulled in from setuptools 3.4.4


Note to Downstream Distributors
Expand Down
113 changes: 78 additions & 35 deletions pip/_vendor/pkg_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,8 @@ def _bypass_ensure_directory(name, mode=0x1FF): # 0777
_state_vars = {}

def _declare_state(vartype, **kw):
g = globals()
for name, val in kw.items():
g[name] = val
_state_vars[name] = vartype
globals().update(kw)
_state_vars.update(dict.fromkeys(kw, vartype))

def __getstate__():
state = {}
Expand Down Expand Up @@ -429,6 +427,48 @@ def __init__(self, entries=None):
for entry in entries:
self.add_entry(entry)

@classmethod
def _build_master(cls):
"""
Prepare the master working set.
"""
ws = cls()
try:
from __main__ import __requires__
except ImportError:
# The main program does not list any requirements
return ws

# ensure the requirements are met
try:
ws.require(__requires__)
except VersionConflict:
return cls._build_from_requirements(__requires__)

return ws

@classmethod
def _build_from_requirements(cls, req_spec):
"""
Build a working set from a requirement spec. Rewrites sys.path.
"""
# try it without defaults already on sys.path
# by starting with an empty path
ws = cls([])
reqs = parse_requirements(req_spec)
dists = ws.resolve(reqs, Environment())
for dist in dists:
ws.add(dist)

# add any missing entries from sys.path
for entry in sys.path:
if entry not in ws.entries:
ws.add_entry(entry)

# then copy back to sys.path
sys.path[:] = ws.entries
return ws

def add_entry(self, entry):
"""Add a path item to ``.entries``, finding any distributions on it
Expand Down Expand Up @@ -504,16 +544,17 @@ def __iter__(self):
seen[key]=1
yield self.by_key[key]

def add(self, dist, entry=None, insert=True):
def add(self, dist, entry=None, insert=True, replace=False):
"""Add `dist` to working set, associated with `entry`
If `entry` is unspecified, it defaults to the ``.location`` of `dist`.
On exit from this routine, `entry` is added to the end of the working
set's ``.entries`` (if it wasn't already present).
`dist` is only added to the working set if it's for a project that
doesn't already have a distribution in the set. If it's added, any
callbacks registered with the ``subscribe()`` method will be called.
doesn't already have a distribution in the set, unless `replace=True`.
If it's added, any callbacks registered with the ``subscribe()`` method
will be called.
"""
if insert:
dist.insert_on(self.entries, entry)
Expand All @@ -522,7 +563,7 @@ def add(self, dist, entry=None, insert=True):
entry = dist.location
keys = self.entry_keys.setdefault(entry,[])
keys2 = self.entry_keys.setdefault(dist.location,[])
if dist.key in self.by_key:
if not replace and dist.key in self.by_key:
return # ignore hidden distros

self.by_key[dist.key] = dist
Expand All @@ -532,7 +573,8 @@ def add(self, dist, entry=None, insert=True):
keys2.append(dist.key)
self._added_new(dist)

def resolve(self, requirements, env=None, installer=None):
def resolve(self, requirements, env=None, installer=None,
replace_conflicting=False):
"""List all distributions needed to (recursively) meet `requirements`
`requirements` must be a sequence of ``Requirement`` objects. `env`,
Expand All @@ -542,6 +584,12 @@ def resolve(self, requirements, env=None, installer=None):
will be invoked with each requirement that cannot be met by an
already-installed distribution; it should return a ``Distribution`` or
``None``.
Unless `replace_conflicting=True`, raises a VersionConflict exception if
any requirements are found on the path that have the correct name but
the wrong version. Otherwise, if an `installer` is supplied it will be
invoked to obtain the correct version of the requirement and activate
it.
"""

requirements = list(requirements)[::-1] # set up the stack
Expand All @@ -558,10 +606,18 @@ def resolve(self, requirements, env=None, installer=None):
if dist is None:
# Find the best distribution and add it to the map
dist = self.by_key.get(req.key)
if dist is None:
if dist is None or (dist not in req and replace_conflicting):
ws = self
if env is None:
env = Environment(self.entries)
dist = best[req.key] = env.best_match(req, self, installer)
if dist is None:
env = Environment(self.entries)
else:
# Use an empty environment and workingset to avoid
# any further conflicts with the conflicting
# distribution
env = Environment([])
ws = WorkingSet([])
dist = best[req.key] = env.best_match(req, ws, installer)
if dist is None:
#msg = ("The '%s' distribution was not found on this "
# "system, and is required by this application.")
Expand Down Expand Up @@ -1811,6 +1867,7 @@ def namespace_handler(importer,path_entry,moduleName,module):

def _handle_ns(packageName, path_item):
"""Ensure that named package includes a subpath of path_item (if needed)"""

importer = get_importer(path_item)
if importer is None:
return None
Expand All @@ -1825,12 +1882,14 @@ def _handle_ns(packageName, path_item):
elif not hasattr(module,'__path__'):
raise TypeError("Not a package:", packageName)
handler = _find_adapter(_namespace_handlers, importer)
subpath = handler(importer,path_item,packageName,module)
subpath = handler(importer, path_item, packageName, module)
if subpath is not None:
path = module.__path__
path.append(subpath)
loader.load_module(packageName)
module.__path__ = path
for path_item in path:
if path_item not in module.__path__:
module.__path__.append(path_item)
return subpath

def declare_namespace(packageName):
Expand Down Expand Up @@ -2252,7 +2311,9 @@ def activate(self,path=None):
self.insert_on(path)
if path is sys.path:
fixup_namespace_packages(self.location)
list(map(declare_namespace, self._get_metadata('namespace_packages.txt')))
for pkg in self._get_metadata('namespace_packages.txt'):
if pkg in sys.modules:
declare_namespace(pkg)

def egg_name(self):
"""Return what this distribution's standard .egg filename should be"""
Expand Down Expand Up @@ -2685,26 +2746,8 @@ def _initialize(g):
_initialize(globals())

# Prepare the master working set and make the ``require()`` API available
_declare_state('object', working_set = WorkingSet())
try:
# Does the main program list any requirements?
from __main__ import __requires__
except ImportError:
pass # No: just use the default working set based on sys.path
else:
# Yes: ensure the requirements are met, by prefixing sys.path if necessary
try:
working_set.require(__requires__)
except VersionConflict: # try it without defaults already on sys.path
working_set = WorkingSet([]) # by starting with an empty path
for dist in working_set.resolve(
parse_requirements(__requires__), Environment()
):
working_set.add(dist)
for entry in sys.path: # add any missing entries from sys.path
if entry not in working_set.entries:
working_set.add_entry(entry)
sys.path[:] = working_set.entries # then copy back to sys.path
working_set = WorkingSet._build_master()
_declare_state('object', working_set=working_set)

require = working_set.require
iter_entry_points = working_set.iter_entry_points
Expand Down

0 comments on commit 37ded08

Please sign in to comment.