mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-21 15:20:59 +00:00
d937050884
Signed-off-by: Dan Ryan <dan@danryan.co>
543 lines
23 KiB
Diff
543 lines
23 KiB
Diff
diff --git a/pipenv/patched/pip/_internal/download.py b/pipenv/patched/pip/_internal/download.py
|
|
index 2bbe1762..872af328 100644
|
|
--- a/pipenv/patched/pip/_internal/download.py
|
|
+++ b/pipenv/patched/pip/_internal/download.py
|
|
@@ -77,7 +77,7 @@ def user_agent():
|
|
Return a string representing the user agent.
|
|
"""
|
|
data = {
|
|
- "installer": {"name": "pip", "version": pip.__version__},
|
|
+ "installer": {"name": "pip", "version": pipenv.patched.notpip.__version__},
|
|
"python": platform.python_version(),
|
|
"implementation": {
|
|
"name": platform.python_implementation(),
|
|
diff --git a/pipenv/patched/pip/_internal/index.py b/pipenv/patched/pip/_internal/index.py
|
|
index 9eda3a35..67dd952c 100644
|
|
--- a/pipenv/patched/pip/_internal/index.py
|
|
+++ b/pipenv/patched/pip/_internal/index.py
|
|
@@ -331,6 +331,9 @@ class PackageFinder(object):
|
|
# The Session we'll use to make requests
|
|
self.session = session
|
|
|
|
+ # Kenneth's Hack
|
|
+ self.extra = None
|
|
+
|
|
# The valid tags to check potential found wheel candidates against
|
|
self.valid_tags = get_supported(
|
|
versions=versions,
|
|
@@ -369,6 +372,23 @@ class PackageFinder(object):
|
|
)
|
|
return "\n".join(lines)
|
|
|
|
+ @staticmethod
|
|
+ def get_extras_links(links):
|
|
+ requires = []
|
|
+ extras = {}
|
|
+
|
|
+ current_list = requires
|
|
+
|
|
+ for link in links:
|
|
+ if not link:
|
|
+ current_list = requires
|
|
+ if link.startswith('['):
|
|
+ current_list = []
|
|
+ extras[link[1:-1]] = current_list
|
|
+ else:
|
|
+ current_list.append(link)
|
|
+ return extras
|
|
+
|
|
@staticmethod
|
|
def _sort_locations(locations, expand_dir=False):
|
|
# type: (Sequence[str], bool) -> Tuple[List[str], List[str]]
|
|
@@ -427,8 +447,8 @@ class PackageFinder(object):
|
|
|
|
return files, urls
|
|
|
|
- def _candidate_sort_key(self, candidate):
|
|
- # type: (InstallationCandidate) -> CandidateSortingKey
|
|
+ def _candidate_sort_key(self, candidate, ignore_compatibility=True):
|
|
+ # type: (InstallationCandidate, bool) -> CandidateSortingKey
|
|
"""
|
|
Function used to generate link sort key for link tuples.
|
|
The greater the return value, the more preferred it is.
|
|
@@ -448,14 +468,18 @@ class PackageFinder(object):
|
|
if candidate.location.is_wheel:
|
|
# can raise InvalidWheelFilename
|
|
wheel = Wheel(candidate.location.filename)
|
|
- if not wheel.supported(self.valid_tags):
|
|
+ if not wheel.supported(self.valid_tags) and not ignore_compatibility:
|
|
raise UnsupportedWheel(
|
|
"%s is not a supported wheel for this platform. It "
|
|
"can't be sorted." % wheel.filename
|
|
)
|
|
if self.prefer_binary:
|
|
binary_preference = 1
|
|
- pri = -(wheel.support_index_min(self.valid_tags))
|
|
+ tags = self.valid_tags if not ignore_compatibility else None
|
|
+ try:
|
|
+ pri = -(wheel.support_index_min(tags=tags))
|
|
+ except TypeError:
|
|
+ pri = -(support_num)
|
|
if wheel.build_tag is not None:
|
|
match = re.match(r'^(\d+)(.*)$', wheel.build_tag)
|
|
build_tag_groups = match.groups()
|
|
@@ -608,7 +632,10 @@ class PackageFinder(object):
|
|
|
|
page_versions = []
|
|
for page in self._get_pages(url_locations, project_name):
|
|
- logger.debug('Analyzing links from page %s', page.url)
|
|
+ try:
|
|
+ logger.debug('Analyzing links from page %s', page.url)
|
|
+ except AttributeError:
|
|
+ continue
|
|
with indent_log():
|
|
page_versions.extend(
|
|
self._package_versions(page.iter_links(), search)
|
|
@@ -628,8 +655,8 @@ class PackageFinder(object):
|
|
# This is an intentional priority ordering
|
|
return file_versions + find_links_versions + page_versions
|
|
|
|
- def find_requirement(self, req, upgrade):
|
|
- # type: (InstallRequirement, bool) -> Optional[Link]
|
|
+ def find_requirement(self, req, upgrade, ignore_compatibility=False):
|
|
+ # type: (InstallRequirement, bool, bool) -> Optional[Link]
|
|
"""Try to find a Link matching req
|
|
|
|
Expects req, an InstallRequirement and upgrade, a boolean
|
|
@@ -784,8 +811,8 @@ class PackageFinder(object):
|
|
logger.debug('Skipping link %s; %s', link, reason)
|
|
self.logged_links.add(link)
|
|
|
|
- def _link_package_versions(self, link, search):
|
|
- # type: (Link, Search) -> Optional[InstallationCandidate]
|
|
+ def _link_package_versions(self, link, search, ignore_compatibility=True):
|
|
+ # type: (Link, Search, bool) -> Optional[InstallationCandidate]
|
|
"""Return an InstallationCandidate or None"""
|
|
version = None
|
|
if link.egg_fragment:
|
|
@@ -801,12 +828,12 @@ class PackageFinder(object):
|
|
link, 'unsupported archive format: %s' % ext,
|
|
)
|
|
return None
|
|
- if "binary" not in search.formats and ext == WHEEL_EXTENSION:
|
|
+ if "binary" not in search.formats and ext == WHEEL_EXTENSION and not ignore_compatibility:
|
|
self._log_skipped_link(
|
|
link, 'No binaries permitted for %s' % search.supplied,
|
|
)
|
|
return None
|
|
- if "macosx10" in link.path and ext == '.zip':
|
|
+ if "macosx10" in link.path and ext == '.zip' and not ignore_compatibility:
|
|
self._log_skipped_link(link, 'macosx10 one')
|
|
return None
|
|
if ext == WHEEL_EXTENSION:
|
|
@@ -820,7 +847,7 @@ class PackageFinder(object):
|
|
link, 'wrong project name (not %s)' % search.supplied)
|
|
return None
|
|
|
|
- if not wheel.supported(self.valid_tags):
|
|
+ if not wheel.supported(self.valid_tags) and not ignore_compatibility:
|
|
self._log_skipped_link(
|
|
link, 'it is not compatible with this Python')
|
|
return None
|
|
@@ -856,14 +883,14 @@ class PackageFinder(object):
|
|
link.filename, link.requires_python)
|
|
support_this_python = True
|
|
|
|
- if not support_this_python:
|
|
+ if not support_this_python and not ignore_compatibility:
|
|
logger.debug("The package %s is incompatible with the python "
|
|
"version in use. Acceptable python versions are: %s",
|
|
link, link.requires_python)
|
|
return None
|
|
logger.debug('Found link %s, version: %s', link, version)
|
|
|
|
- return InstallationCandidate(search.supplied, version, link)
|
|
+ return InstallationCandidate(search.supplied, version, link, link.requires_python)
|
|
|
|
|
|
def _find_name_version_sep(egg_info, canonical_name):
|
|
diff --git a/pipenv/patched/pip/_internal/models/candidate.py b/pipenv/patched/pip/_internal/models/candidate.py
|
|
index 4475458a..6748957d 100644
|
|
--- a/pipenv/patched/pip/_internal/models/candidate.py
|
|
+++ b/pipenv/patched/pip/_internal/models/candidate.py
|
|
@@ -13,11 +13,12 @@ class InstallationCandidate(KeyBasedCompareMixin):
|
|
"""Represents a potential "candidate" for installation.
|
|
"""
|
|
|
|
- def __init__(self, project, version, location):
|
|
- # type: (Any, str, Link) -> None
|
|
+ def __init__(self, project, version, location, requires_python=None):
|
|
+ # type: (Any, str, Link, Any) -> None
|
|
self.project = project
|
|
self.version = parse_version(version) # type: _BaseVersion
|
|
self.location = location
|
|
+ self.requires_python = requires_python
|
|
|
|
super(InstallationCandidate, self).__init__(
|
|
key=(self.project, self.version, self.location),
|
|
diff --git a/pipenv/patched/pip/_internal/operations/prepare.py b/pipenv/patched/pip/_internal/operations/prepare.py
|
|
index 4f31dd5a..ed0c86b2 100644
|
|
--- a/pipenv/patched/pip/_internal/operations/prepare.py
|
|
+++ b/pipenv/patched/pip/_internal/operations/prepare.py
|
|
@@ -17,7 +17,7 @@ from pip._internal.exceptions import (
|
|
from pip._internal.utils.compat import expanduser
|
|
from pip._internal.utils.hashes import MissingHashes
|
|
from pip._internal.utils.logging import indent_log
|
|
-from pip._internal.utils.misc import display_path, normalize_path
|
|
+from pip._internal.utils.misc import display_path, normalize_path, rmtree
|
|
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
|
from pip._internal.vcs import vcs
|
|
|
|
@@ -258,14 +258,7 @@ class RequirementPreparer(object):
|
|
# package unpacked in `req.source_dir`
|
|
# package unpacked in `req.source_dir`
|
|
if os.path.exists(os.path.join(req.source_dir, 'setup.py')):
|
|
- raise PreviousBuildDirError(
|
|
- "pip can't proceed with requirements '%s' due to a"
|
|
- " pre-existing build directory (%s). This is "
|
|
- "likely due to a previous installation that failed"
|
|
- ". pip is being responsible and not assuming it "
|
|
- "can delete this. Please delete it and try again."
|
|
- % (req, req.source_dir)
|
|
- )
|
|
+ rmtree(req.source_dir)
|
|
req.populate_link(finder, upgrade_allowed, require_hashes)
|
|
|
|
# We can't hit this spot and have populate_link return None.
|
|
diff --git a/pipenv/patched/pip/_internal/pep425tags.py b/pipenv/patched/pip/_internal/pep425tags.py
|
|
index 1e782d1a..3c760ca3 100644
|
|
--- a/pipenv/patched/pip/_internal/pep425tags.py
|
|
+++ b/pipenv/patched/pip/_internal/pep425tags.py
|
|
@@ -10,7 +10,10 @@ import sysconfig
|
|
import warnings
|
|
from collections import OrderedDict
|
|
|
|
-import pip._internal.utils.glibc
|
|
+try:
|
|
+ import pip._internal.utils.glibc
|
|
+except ImportError:
|
|
+ import pip.utils.glibc
|
|
from pip._internal.utils.compat import get_extension_suffixes
|
|
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
|
|
|
diff --git a/pipenv/patched/pip/_internal/req/req_install.py b/pipenv/patched/pip/_internal/req/req_install.py
|
|
index a4834b00..2c22e141 100644
|
|
--- a/pipenv/patched/pip/_internal/req/req_install.py
|
|
+++ b/pipenv/patched/pip/_internal/req/req_install.py
|
|
@@ -588,7 +588,8 @@ class InstallRequirement(object):
|
|
self.setup_py, self.link,
|
|
)
|
|
script = SETUPTOOLS_SHIM % self.setup_py
|
|
- base_cmd = [sys.executable, '-c', script]
|
|
+ sys_executable = os.environ.get('PIP_PYTHON_PATH', sys.executable)
|
|
+ base_cmd = [sys_executable, '-c', script]
|
|
if self.isolated:
|
|
base_cmd += ["--no-user-cfg"]
|
|
egg_info_cmd = base_cmd + ['egg_info']
|
|
@@ -746,9 +747,10 @@ class InstallRequirement(object):
|
|
with indent_log():
|
|
# FIXME: should we do --install-headers here too?
|
|
with self.build_env:
|
|
+ sys_executable = os.environ.get('PIP_PYTHON_PATH', sys.executable)
|
|
call_subprocess(
|
|
[
|
|
- sys.executable,
|
|
+ sys_executable,
|
|
'-c',
|
|
SETUPTOOLS_SHIM % self.setup_py
|
|
] +
|
|
@@ -995,7 +997,8 @@ class InstallRequirement(object):
|
|
pycompile # type: bool
|
|
):
|
|
# type: (...) -> List[str]
|
|
- install_args = [sys.executable, "-u"]
|
|
+ sys_executable = os.environ.get('PIP_PYTHON_PATH', sys.executable)
|
|
+ install_args = [sys_executable, "-u"]
|
|
install_args.append('-c')
|
|
install_args.append(SETUPTOOLS_SHIM % self.setup_py)
|
|
install_args += list(global_options) + \
|
|
diff --git a/pipenv/patched/pip/_internal/req/req_set.py b/pipenv/patched/pip/_internal/req/req_set.py
|
|
index d1410e93..69a53bf2 100644
|
|
--- a/pipenv/patched/pip/_internal/req/req_set.py
|
|
+++ b/pipenv/patched/pip/_internal/req/req_set.py
|
|
@@ -18,7 +18,7 @@ logger = logging.getLogger(__name__)
|
|
|
|
class RequirementSet(object):
|
|
|
|
- def __init__(self, require_hashes=False, check_supported_wheels=True):
|
|
+ def __init__(self, require_hashes=False, check_supported_wheels=True, ignore_compatibility=True):
|
|
# type: (bool, bool) -> None
|
|
"""Create a RequirementSet.
|
|
"""
|
|
@@ -26,6 +26,9 @@ class RequirementSet(object):
|
|
self.requirements = OrderedDict() # type: Dict[str, InstallRequirement] # noqa: E501
|
|
self.require_hashes = require_hashes
|
|
self.check_supported_wheels = check_supported_wheels
|
|
+ if ignore_compatibility:
|
|
+ self.check_supported_wheels = False
|
|
+ self.ignore_compatibility = (check_supported_wheels is False or ignore_compatibility is True)
|
|
|
|
# Mapping of alias: real_name
|
|
self.requirement_aliases = {} # type: Dict[str, str]
|
|
@@ -186,7 +189,7 @@ class RequirementSet(object):
|
|
return self.requirements[name]
|
|
if name in self.requirement_aliases:
|
|
return self.requirements[self.requirement_aliases[name]]
|
|
- raise KeyError("No project with the name %r" % project_name)
|
|
+ pass
|
|
|
|
def cleanup_files(self):
|
|
# type: () -> None
|
|
diff --git a/pipenv/patched/pip/_internal/resolve.py b/pipenv/patched/pip/_internal/resolve.py
|
|
index 33f572f1..dfe149ad 100644
|
|
--- a/pipenv/patched/pip/_internal/resolve.py
|
|
+++ b/pipenv/patched/pip/_internal/resolve.py
|
|
@@ -19,6 +19,7 @@ from pip._internal.exceptions import (
|
|
UnsupportedPythonVersion,
|
|
)
|
|
from pip._internal.req.constructors import install_req_from_req_string
|
|
+from pip._internal.req.req_install import InstallRequirement
|
|
from pip._internal.utils.logging import indent_log
|
|
from pip._internal.utils.misc import dist_in_usersite, ensure_dir
|
|
from pip._internal.utils.packaging import check_dist_requires_python
|
|
@@ -58,7 +59,8 @@ class Resolver(object):
|
|
force_reinstall, # type: bool
|
|
isolated, # type: bool
|
|
upgrade_strategy, # type: str
|
|
- use_pep517=None # type: Optional[bool]
|
|
+ use_pep517=None, # type: Optional[bool]
|
|
+ ignore_compatibility=False, # type: bool
|
|
):
|
|
# type: (...) -> None
|
|
super(Resolver, self).__init__()
|
|
@@ -81,8 +83,12 @@ class Resolver(object):
|
|
self.ignore_dependencies = ignore_dependencies
|
|
self.ignore_installed = ignore_installed
|
|
self.ignore_requires_python = ignore_requires_python
|
|
+ self.ignore_compatibility = ignore_compatibility
|
|
self.use_user_site = use_user_site
|
|
self.use_pep517 = use_pep517
|
|
+ self.requires_python = None
|
|
+ if self.ignore_compatibility:
|
|
+ self.ignore_requires_python = True
|
|
|
|
self._discovered_dependencies = \
|
|
defaultdict(list) # type: DefaultDict[str, List]
|
|
@@ -273,7 +279,8 @@ class Resolver(object):
|
|
def _resolve_one(
|
|
self,
|
|
requirement_set, # type: RequirementSet
|
|
- req_to_install # type: InstallRequirement
|
|
+ req_to_install, # type: InstallRequirement
|
|
+ ignore_requires_python=False # type: bool
|
|
):
|
|
# type: (...) -> List[InstallRequirement]
|
|
"""Prepare a single requirements file.
|
|
@@ -298,11 +305,18 @@ class Resolver(object):
|
|
try:
|
|
check_dist_requires_python(dist)
|
|
except UnsupportedPythonVersion as err:
|
|
- if self.ignore_requires_python:
|
|
+ if self.ignore_requires_python or ignore_requires_python or self.ignore_compatibility:
|
|
logger.warning(err.args[0])
|
|
else:
|
|
raise
|
|
|
|
+ # A huge hack, by Kenneth Reitz.
|
|
+ try:
|
|
+ self.requires_python = check_dist_requires_python(dist, absorb=False)
|
|
+ except TypeError:
|
|
+ self.requires_python = None
|
|
+
|
|
+
|
|
more_reqs = [] # type: List[InstallRequirement]
|
|
|
|
def add_req(subreq, extras_requested):
|
|
@@ -329,10 +343,14 @@ class Resolver(object):
|
|
# We add req_to_install before its dependencies, so that we
|
|
# can refer to it when adding dependencies.
|
|
if not requirement_set.has_requirement(req_to_install.name):
|
|
+ available_requested = sorted(
|
|
+ set(dist.extras) & set(req_to_install.extras)
|
|
+ )
|
|
# 'unnamed' requirements will get added here
|
|
req_to_install.is_direct = True
|
|
requirement_set.add_requirement(
|
|
req_to_install, parent_req_name=None,
|
|
+ extras_requested=available_requested,
|
|
)
|
|
|
|
if not self.ignore_dependencies:
|
|
@@ -356,6 +374,20 @@ class Resolver(object):
|
|
for subreq in dist.requires(available_requested):
|
|
add_req(subreq, extras_requested=available_requested)
|
|
|
|
+ # Hack for deep-resolving extras.
|
|
+ for available in available_requested:
|
|
+ if hasattr(dist, '_DistInfoDistribution__dep_map'):
|
|
+ for req in dist._DistInfoDistribution__dep_map[available]:
|
|
+ req = InstallRequirement(
|
|
+ req,
|
|
+ req_to_install,
|
|
+ isolated=self.isolated,
|
|
+ wheel_cache=self.wheel_cache,
|
|
+ use_pep517=None
|
|
+ )
|
|
+
|
|
+ more_reqs.append(req)
|
|
+
|
|
if not req_to_install.editable and not req_to_install.satisfied_by:
|
|
# XXX: --no-install leads this to report 'Successfully
|
|
# downloaded' for only non-editable reqs, even though we took
|
|
diff --git a/pipenv/patched/pip/_internal/utils/packaging.py b/pipenv/patched/pip/_internal/utils/packaging.py
|
|
index 7aaf7b5e..d56f0512 100644
|
|
--- a/pipenv/patched/pip/_internal/utils/packaging.py
|
|
+++ b/pipenv/patched/pip/_internal/utils/packaging.py
|
|
@@ -37,7 +37,7 @@ def check_requires_python(requires_python):
|
|
requires_python_specifier = specifiers.SpecifierSet(requires_python)
|
|
|
|
# We only use major.minor.micro
|
|
- python_version = version.parse('.'.join(map(str, sys.version_info[:3])))
|
|
+ python_version = version.parse('{0}.{1}.{2}'.format(*sys.version_info[:3]))
|
|
return python_version in requires_python_specifier
|
|
|
|
|
|
@@ -57,9 +57,11 @@ def get_metadata(dist):
|
|
return feed_parser.close()
|
|
|
|
|
|
-def check_dist_requires_python(dist):
|
|
+def check_dist_requires_python(dist, absorb=False):
|
|
pkg_info_dict = get_metadata(dist)
|
|
requires_python = pkg_info_dict.get('Requires-Python')
|
|
+ if absorb:
|
|
+ return requires_python
|
|
try:
|
|
if not check_requires_python(requires_python):
|
|
raise exceptions.UnsupportedPythonVersion(
|
|
diff --git a/pipenv/patched/pip/_internal/utils/temp_dir.py b/pipenv/patched/pip/_internal/utils/temp_dir.py
|
|
index 2c81ad55..ff2ccc5a 100644
|
|
--- a/pipenv/patched/pip/_internal/utils/temp_dir.py
|
|
+++ b/pipenv/patched/pip/_internal/utils/temp_dir.py
|
|
@@ -5,8 +5,10 @@ import itertools
|
|
import logging
|
|
import os.path
|
|
import tempfile
|
|
+import warnings
|
|
|
|
from pip._internal.utils.misc import rmtree
|
|
+from pipenv.vendor.vistir.compat import finalize, ResourceWarning
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
@@ -47,6 +49,20 @@ class TempDirectory(object):
|
|
self.path = path
|
|
self.delete = delete
|
|
self.kind = kind
|
|
+ self._finalizer = None
|
|
+ if path:
|
|
+ self._register_finalizer()
|
|
+
|
|
+ def _register_finalizer(self):
|
|
+ if self.delete and self.path:
|
|
+ self._finalizer = finalize(
|
|
+ self,
|
|
+ self._cleanup,
|
|
+ self.path,
|
|
+ warn_message = None
|
|
+ )
|
|
+ else:
|
|
+ self._finalizer = None
|
|
|
|
def __repr__(self):
|
|
return "<{} {!r}>".format(self.__class__.__name__, self.path)
|
|
@@ -74,14 +90,30 @@ class TempDirectory(object):
|
|
self.path = os.path.realpath(
|
|
tempfile.mkdtemp(prefix="pip-{}-".format(self.kind))
|
|
)
|
|
+ self._register_finalizer()
|
|
logger.debug("Created temporary directory: {}".format(self.path))
|
|
|
|
+ @classmethod
|
|
+ def _cleanup(cls, name, warn_message=None):
|
|
+ try:
|
|
+ rmtree(name)
|
|
+ except OSError:
|
|
+ pass
|
|
+ else:
|
|
+ if warn_message:
|
|
+ warnings.warn(warn_message, ResourceWarning)
|
|
+
|
|
def cleanup(self):
|
|
"""Remove the temporary directory created and reset state
|
|
"""
|
|
- if self.path is not None and os.path.exists(self.path):
|
|
- rmtree(self.path)
|
|
- self.path = None
|
|
+ if getattr(self._finalizer, "detach", None) and self._finalizer.detach():
|
|
+ if os.path.exists(self.path):
|
|
+ try:
|
|
+ rmtree(self.path)
|
|
+ except OSError:
|
|
+ pass
|
|
+ else:
|
|
+ self.path = None
|
|
|
|
|
|
class AdjacentTempDirectory(TempDirectory):
|
|
@@ -152,4 +184,5 @@ class AdjacentTempDirectory(TempDirectory):
|
|
self.path = os.path.realpath(
|
|
tempfile.mkdtemp(prefix="pip-{}-".format(self.kind))
|
|
)
|
|
+ self._register_finalizer()
|
|
logger.debug("Created temporary directory: {}".format(self.path))
|
|
diff --git a/pipenv/patched/pip/_internal/wheel.py b/pipenv/patched/pip/_internal/wheel.py
|
|
index 67bcc7f7..968cdff9 100644
|
|
--- a/pipenv/patched/pip/_internal/wheel.py
|
|
+++ b/pipenv/patched/pip/_internal/wheel.py
|
|
@@ -114,7 +114,7 @@ def fix_script(path):
|
|
firstline = script.readline()
|
|
if not firstline.startswith(b'#!python'):
|
|
return False
|
|
- exename = sys.executable.encode(sys.getfilesystemencoding())
|
|
+ exename = os.environ.get('PIP_PYTHON_PATH', sys.executable).encode(sys.getfilesystemencoding())
|
|
firstline = b'#!' + exename + os.linesep.encode("ascii")
|
|
rest = script.read()
|
|
with open(path, 'wb') as script:
|
|
@@ -201,7 +201,8 @@ def message_about_scripts_not_on_PATH(scripts):
|
|
]
|
|
# If an executable sits with sys.executable, we don't warn for it.
|
|
# This covers the case of venv invocations without activating the venv.
|
|
- not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable)))
|
|
+ executable_loc = os.environ.get("PIP_PYTHON_PATH", sys.executable)
|
|
+ not_warn_dirs.append(os.path.normcase(os.path.dirname(executable_loc)))
|
|
warn_for = {
|
|
parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items()
|
|
if os.path.normcase(parent_dir) not in not_warn_dirs
|
|
@@ -901,8 +902,9 @@ class WheelBuilder(object):
|
|
# isolating. Currently, it breaks Python in virtualenvs, because it
|
|
# relies on site.py to find parts of the standard library outside the
|
|
# virtualenv.
|
|
+ executable_loc = os.environ.get('PIP_PYTHON_PATH', sys.executable)
|
|
return [
|
|
- sys.executable, '-u', '-c',
|
|
+ executable_loc, '-u', '-c',
|
|
SETUPTOOLS_SHIM % req.setup_py
|
|
] + list(self.global_options)
|
|
|
|
diff --git a/pipenv/patched/pip/_internal/utils/misc.py b/pipenv/patched/pip/_internal/utils/misc.py
|
|
index 84605ee3..649311c0 100644
|
|
--- a/pipenv/patched/pip/_internal/utils/misc.py
|
|
+++ b/pipenv/patched/pip/_internal/utils/misc.py
|
|
@@ -117,8 +117,8 @@ def get_prog():
|
|
@retry(stop_max_delay=3000, wait_fixed=500)
|
|
def rmtree(dir, ignore_errors=False):
|
|
# type: (str, bool) -> None
|
|
- shutil.rmtree(dir, ignore_errors=ignore_errors,
|
|
- onerror=rmtree_errorhandler)
|
|
+ from pipenv.vendor.vistir.path import rmtree as vistir_rmtree, handle_remove_readonly
|
|
+ vistir_rmtree(dir, onerror=handle_remove_readonly, ignore_errors=ignore_errors)
|
|
|
|
|
|
def rmtree_errorhandler(func, path, exc_info):
|