Fix installed package discovery

- Exclude python when searching virtualenvs created using nested
  virtualenv interpreters (via `lib-dynload` library directory)

Signed-off-by: Dan Ryan <dan@danryan.co>
This commit is contained in:
Dan Ryan
2019-02-19 20:29:26 -05:00
parent 5ac228e68f
commit bfdb9aed87
4 changed files with 19 additions and 13 deletions
+2 -1
View File
@@ -630,7 +630,8 @@ def sync(
def clean(ctx, state, dry_run=False, bare=False, user=False):
"""Uninstalls all packages not specified in Pipfile.lock."""
from ..core import do_clean
do_clean(ctx=ctx, three=state.three, python=state.python, dry_run=dry_run)
do_clean(ctx=ctx, three=state.three, python=state.python, dry_run=dry_run,
system=state.system)
# Only invoke the "did you mean" when an argument wasn't passed (it breaks those).
+7 -7
View File
@@ -2714,7 +2714,10 @@ def do_sync(
click.echo(crayons.green("All dependencies are now up-to-date!"))
def do_clean(ctx, three=None, python=None, dry_run=False, bare=False, pypi_mirror=None):
def do_clean(
ctx, three=None, python=None, dry_run=False, bare=False, pypi_mirror=None,
system=False
):
# Ensure that virtualenv is available.
from packaging.utils import canonicalize_name
ensure_project(three=three, python=python, validate=False, pypi_mirror=pypi_mirror)
@@ -2736,6 +2739,7 @@ def do_clean(ctx, three=None, python=None, dry_run=False, bare=False, pypi_mirro
if used_package in installed_package_names:
installed_package_names.remove(used_package)
failure = False
cmd = [which_pip(allow_global=system), "uninstall", "-y", "-qq"]
for apparent_bad_package in installed_package_names:
if dry_run and not bare:
click.echo(apparent_bad_package)
@@ -2747,12 +2751,8 @@ def do_clean(ctx, three=None, python=None, dry_run=False, bare=False, pypi_mirro
)
)
# Uninstall the package.
c = delegator.run(
"{0} uninstall {1} -y".format(
escape_grouped_arguments(which_pip()),
apparent_bad_package
)
)
cmd_str = Script.parse(cmd + [apparent_bad_package]).cmdify()
c = delegator.run(cmd_str, block=True)
if c.return_code != 0:
failure = True
sys.exit(int(failure))
+10 -4
View File
@@ -244,7 +244,7 @@ class Environment(object):
"""
pkg_resources = self.safe_import("pkg_resources")
return pkg_resources.find_distributions(self.paths["PYTHONPATH"])
return pkg_resources.find_distributions(self.paths["libdirs"])
def find_egg(self, egg_dist):
"""Find an egg by name in the given environment"""
@@ -271,16 +271,22 @@ class Environment(object):
def dist_is_in_project(self, dist):
"""Determine whether the supplied distribution is in the environment."""
from .project import _normalized
prefix = _normalized(self.base_paths["prefix"])
prefixes = [
_normalized(prefix) for prefix in self.base_paths["libdirs"]
if _normalized(self.prefix).startswith(_normalized(prefix))
]
location = self.locate_dist(dist)
if not location:
return False
return _normalized(location).startswith(prefix)
return any(_normalized(location).startswith(prefix) for prefix in prefixes)
def get_installed_packages(self):
"""Returns all of the installed packages in a given environment"""
workingset = self.get_working_set()
packages = [pkg for pkg in workingset if self.dist_is_in_project(pkg)]
packages = [
pkg for pkg in workingset
if self.dist_is_in_project(pkg) and pkg.key != "python"
]
return packages
@contextlib.contextmanager
-1
View File
@@ -100,7 +100,6 @@ def test_directory_with_leading_dash(PipenvInstance):
return mkdtemp(suffix, prefix, dir)
with mock.patch('pipenv.vendor.vistir.compat.mkdtemp', side_effect=mocked_mkdtemp):
del os.environ['PIPENV_VENV_IN_PROJECT']
with temp_environ(), PipenvInstance(chdir=True) as p:
if "PIPENV_VENV_IN_PROJECT" in os.environ:
del os.environ['PIPENV_VENV_IN_PROJECT']