diff options
author | Donald Stufft <donald@stufft.io> | 2014-05-02 23:19:42 -0400 |
---|---|---|
committer | Donald Stufft <donald@stufft.io> | 2014-05-02 23:19:42 -0400 |
commit | e71897269b59394505aa4ed6846fb34089d9a94b (patch) | |
tree | cefc2204cf77ff946613b2bbc0c5d85433c2d46d | |
parent | 86353875a92ca06fb42f8ad31322c83666781462 (diff) | |
parent | afae20557efc50ee8e6a937eef5a4a6229bfe61b (diff) | |
download | pip-e71897269b59394505aa4ed6846fb34089d9a94b.tar.gz |
Merge pull request #1784 from dstufft/upgrade-setuptools
Upgrade setuptools
-rw-r--r-- | CHANGES.txt | 2 | ||||
-rw-r--r-- | pip/_vendor/README.rst | 2 | ||||
-rw-r--r-- | pip/_vendor/pkg_resources.py | 113 |
3 files changed, 80 insertions, 37 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 10bbc4f7f..f886915a2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -13,7 +13,7 @@ Changelog * Update docs to point to https://pip.pypa.io/ * Upgrade the bundled projects (distlib==0.1.8, html5lib==1.0b3, six==1.6.1, - colorama==0.3.1). + colorama==0.3.1, setuptools==3.4.4). 1.5.4 (2014-02-21) diff --git a/pip/_vendor/README.rst b/pip/_vendor/README.rst index 0fc983d92..f2c9ee9b4 100644 --- a/pip/_vendor/README.rst +++ b/pip/_vendor/README.rst @@ -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 diff --git a/pip/_vendor/pkg_resources.py b/pip/_vendor/pkg_resources.py index b93cd24d3..ee8a4823b 100644 --- a/pip/_vendor/pkg_resources.py +++ b/pip/_vendor/pkg_resources.py @@ -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 = {} @@ -429,6 +427,48 @@ class WorkingSet(object): 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 @@ -504,7 +544,7 @@ class WorkingSet(object): 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`. @@ -512,8 +552,9 @@ class WorkingSet(object): 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) @@ -522,7 +563,7 @@ class WorkingSet(object): 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 @@ -532,7 +573,8 @@ class WorkingSet(object): 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`, @@ -542,6 +584,12 @@ class WorkingSet(object): 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 @@ -558,10 +606,18 @@ class WorkingSet(object): 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.") @@ -1811,6 +1867,7 @@ def register_namespace_handler(importer_type, namespace_handler): 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 @@ -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): @@ -2252,7 +2311,9 @@ class Distribution(object): 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""" @@ -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 |