mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
Leverage pip to access installed packages
- Use `get_installed_distributions` from pip - This cascades to `pkg_resources.working_set` which relies on `sys.path` to uncover packages - Consequently I implemented `temp_path()` as a contextmanager in the style of `temp_environ()` - This requires us to know the environment's `sys.path`, so `load_path(python)` will do a `json.dumps` of `sys.path` to stdout which then gets loaded and returned - Allows us to avoid trying to hack around `pip freeze` output to parse out names from comments etc - Provides other potential uses Signed-off-by: Dan Ryan <dan@danryan.co>
This commit is contained in:
+1
-14
@@ -2543,23 +2543,10 @@ def do_clean(
|
||||
pypi_mirror=None,
|
||||
):
|
||||
# Ensure that virtualenv is available.
|
||||
from .vendor.requirementslib import Requirement
|
||||
|
||||
ensure_project(three=three, python=python, validate=False, pypi_mirror=pypi_mirror)
|
||||
ensure_lockfile(pypi_mirror=pypi_mirror)
|
||||
installed_package_names = []
|
||||
pip_freeze_command = delegator.run("{0} freeze".format(which_pip()))
|
||||
for line in pip_freeze_command.out.split("\n"):
|
||||
installed = line.strip()
|
||||
if not installed or installed.startswith("#"): # Comment or empty.
|
||||
continue
|
||||
r = Requirement.from_line(installed).requirement
|
||||
# Ignore editable installations.
|
||||
if not r.editable:
|
||||
installed_package_names.append(r.name.lower())
|
||||
else:
|
||||
if verbose:
|
||||
click.echo("Ignoring {0}.".format(repr(r.name)), err=True)
|
||||
installed_package_names = [pkg.project_name for pkg in project.get_installed_packages()]
|
||||
# Remove known "bad packages" from the list.
|
||||
for bad_package in BAD_PACKAGES:
|
||||
if bad_package in installed_package_names:
|
||||
|
||||
@@ -269,6 +269,20 @@ class Project(object):
|
||||
return os.path.join(self.project_directory, ".venv")
|
||||
return str(get_workon_home().joinpath(self.virtualenv_name))
|
||||
|
||||
def get_installed_packages(self):
|
||||
from . import PIPENV_ROOT, PIPENV_VENDOR, PIPENV_PATCHED
|
||||
from .utils import temp_path, load_path, temp_environ
|
||||
if self.virtualenv_exists:
|
||||
with temp_path(), temp_environ():
|
||||
new_path = load_path(self.which("python"))
|
||||
new_path = [new_path[0], PIPENV_ROOT, PIPENV_PATCHED, PIPENV_VENDOR] + new_path[1:]
|
||||
sys.path = new_path
|
||||
os.environ['VIRTUAL_ENV'] = self.virtualenv_location
|
||||
from .patched.notpip._internal.utils.misc import get_installed_distributions
|
||||
return get_installed_distributions(local_only=True)
|
||||
else:
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def _sanitize(cls, name):
|
||||
# Replace dangerous characters into '_'. The length of the sanitized
|
||||
|
||||
@@ -934,6 +934,28 @@ def temp_environ():
|
||||
os.environ.update(environ)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def temp_path():
|
||||
"""Allow the ability to set os.environ temporarily"""
|
||||
path = [p for p in sys.path]
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
sys.path = [p for p in path]
|
||||
|
||||
|
||||
def load_path(python):
|
||||
import delegator
|
||||
import json
|
||||
python = escape_grouped_arguments(python)
|
||||
json_dump_commmand = "'import json, sys; print(json.dumps(sys.path));'"
|
||||
c = delegator.run("{0} -c {1}".format(python, json_dump_commmand))
|
||||
if c.return_code == 0:
|
||||
return json.loads(c.out.strip())
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def is_valid_url(url):
|
||||
"""Checks if a given string is an url"""
|
||||
pieces = urlparse(url)
|
||||
|
||||
Reference in New Issue
Block a user