mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-21 15:20:59 +00:00
0552ad23c1
Signed-off-by: Dan Ryan <dan@danryan.co>
138 lines
5.5 KiB
Diff
138 lines
5.5 KiB
Diff
diff --git a/pipenv/vendor/pip9/_vendor/pkg_resources/__init__.py b/pipenv/vendor/pip9/_vendor/pkg_resources/__init__.py
|
|
index eed9228..7b7da00 100644
|
|
--- a/pipenv/vendor/pip9/_vendor/pkg_resources/__init__.py
|
|
+++ b/pipenv/vendor/pip9/_vendor/pkg_resources/__init__.py
|
|
@@ -74,13 +74,8 @@ __import__('pip9._vendor.packaging.specifiers')
|
|
__import__('pip9._vendor.packaging.requirements')
|
|
__import__('pip9._vendor.packaging.markers')
|
|
|
|
-
|
|
if (3, 0) < sys.version_info < (3, 3):
|
|
- msg = (
|
|
- "Support for Python 3.0-3.2 has been dropped. Future versions "
|
|
- "will fail here."
|
|
- )
|
|
- warnings.warn(msg)
|
|
+ raise RuntimeError("Python 3.3 or later is required")
|
|
|
|
# declare some globals that will be defined later to
|
|
# satisfy the linters.
|
|
@@ -791,7 +786,7 @@ class WorkingSet(object):
|
|
self._added_new(dist)
|
|
|
|
def resolve(self, requirements, env=None, installer=None,
|
|
- replace_conflicting=False):
|
|
+ replace_conflicting=False, extras=None):
|
|
"""List all distributions needed to (recursively) meet `requirements`
|
|
|
|
`requirements` must be a sequence of ``Requirement`` objects. `env`,
|
|
@@ -807,6 +802,12 @@ class WorkingSet(object):
|
|
the wrong version. Otherwise, if an `installer` is supplied it will be
|
|
invoked to obtain the correct version of the requirement and activate
|
|
it.
|
|
+
|
|
+ `extras` is a list of the extras to be used with these requirements.
|
|
+ This is important because extra requirements may look like `my_req;
|
|
+ extra = "my_extra"`, which would otherwise be interpreted as a purely
|
|
+ optional requirement. Instead, we want to be able to assert that these
|
|
+ requirements are truly required.
|
|
"""
|
|
|
|
# set up the stack
|
|
@@ -830,7 +831,7 @@ class WorkingSet(object):
|
|
# Ignore cyclic or redundant dependencies
|
|
continue
|
|
|
|
- if not req_extras.markers_pass(req):
|
|
+ if not req_extras.markers_pass(req, extras):
|
|
continue
|
|
|
|
dist = best.get(req.key)
|
|
@@ -1009,7 +1010,7 @@ class _ReqExtras(dict):
|
|
Map each requirement to the extras that demanded it.
|
|
"""
|
|
|
|
- def markers_pass(self, req):
|
|
+ def markers_pass(self, req, extras=None):
|
|
"""
|
|
Evaluate markers for req against each extra that
|
|
demanded it.
|
|
@@ -1019,7 +1020,7 @@ class _ReqExtras(dict):
|
|
"""
|
|
extra_evals = (
|
|
req.marker.evaluate({'extra': extra})
|
|
- for extra in self.get(req, ()) + (None,)
|
|
+ for extra in self.get(req, ()) + (extras or (None,))
|
|
)
|
|
return not req.marker or any(extra_evals)
|
|
|
|
@@ -1956,6 +1957,12 @@ def find_eggs_in_zip(importer, path_item, only=False):
|
|
subpath = os.path.join(path_item, subitem)
|
|
for dist in find_eggs_in_zip(zipimport.zipimporter(subpath), subpath):
|
|
yield dist
|
|
+ elif subitem.lower().endswith('.dist-info'):
|
|
+ subpath = os.path.join(path_item, subitem)
|
|
+ submeta = EggMetadata(zipimport.zipimporter(subpath))
|
|
+ submeta.egg_info = subpath
|
|
+ yield Distribution.from_location(path_item, subitem, submeta)
|
|
+
|
|
|
|
|
|
register_finder(zipimport.zipimporter, find_eggs_in_zip)
|
|
@@ -2118,6 +2125,10 @@ def _rebuild_mod_path(orig_path, package_name, module):
|
|
parts = path_parts[:-module_parts]
|
|
return safe_sys_path_index(_normalize_cached(os.sep.join(parts)))
|
|
|
|
+ if not isinstance(orig_path, list):
|
|
+ # Is this behavior useful when module.__path__ is not a list?
|
|
+ return
|
|
+
|
|
orig_path.sort(key=position_in_sys_path)
|
|
module.__path__[:] = [_normalize_cached(p) for p in orig_path]
|
|
|
|
@@ -2304,8 +2315,14 @@ class EntryPoint(object):
|
|
def require(self, env=None, installer=None):
|
|
if self.extras and not self.dist:
|
|
raise UnknownExtra("Can't require() without a distribution", self)
|
|
+
|
|
+ # Get the requirements for this entry point with all its extras and
|
|
+ # then resolve them. We have to pass `extras` along when resolving so
|
|
+ # that the working set knows what extras we want. Otherwise, for
|
|
+ # dist-info distributions, the working set will assume that the
|
|
+ # requirements for that extra are purely optional and skip over them.
|
|
reqs = self.dist.requires(self.extras)
|
|
- items = working_set.resolve(reqs, env, installer)
|
|
+ items = working_set.resolve(reqs, env, installer, extras=self.extras)
|
|
list(map(working_set.add, items))
|
|
|
|
pattern = re.compile(
|
|
@@ -3010,9 +3027,11 @@ def _initialize(g=globals()):
|
|
"Set up global resource manager (deliberately not state-saved)"
|
|
manager = ResourceManager()
|
|
g['_manager'] = manager
|
|
- for name in dir(manager):
|
|
- if not name.startswith('_'):
|
|
- g[name] = getattr(manager, name)
|
|
+ g.update(
|
|
+ (name, getattr(manager, name))
|
|
+ for name in dir(manager)
|
|
+ if not name.startswith('_')
|
|
+ )
|
|
|
|
|
|
@_call_aside
|
|
@@ -3041,10 +3060,10 @@ def _initialize_master_working_set():
|
|
# ensure that all distributions added to the working set in the future
|
|
# (e.g. by calling ``require()``) will get activated as well,
|
|
# with higher priority (replace=True).
|
|
- dist = None # ensure dist is defined for del dist below
|
|
- for dist in working_set:
|
|
+ tuple(
|
|
dist.activate(replace=False)
|
|
- del dist
|
|
+ for dist in working_set
|
|
+ )
|
|
add_activation_listener(lambda dist: dist.activate(replace=True), existing=False)
|
|
working_set.entries = []
|
|
# match order
|