Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor virtualenv create logic #5533

Merged
merged 5 commits into from
Dec 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion news/5477.bugfix.rst
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Check if ``venv`` module is available and fallback to prior logic when it is not.
virtualenv creation no longer uses ``--creator=venv`` by default; introduced two environment variables:
``PIPENV_VIRTUALENV_CREATOR`` -- May be specified to instruct virtualenv which ``--creator=`` to use.
``PIPENV_VIRTUALENV_COPIES`` -- When specified as truthy, instructs virtualenv to not use symlinks.
49 changes: 22 additions & 27 deletions pipenv/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,27 @@ def convert_three_to_python(three, python):
return python


def _create_virtualenv_cmd(project, python, site_packages=False):
cmd = [
Path(sys.executable).absolute().as_posix(),
"-m",
"virtualenv",
]
if project.s.PIPENV_VIRTUALENV_CREATOR:
cmd.append(f"--creator={project.s.PIPENV_VIRTUALENV_CREATOR}")
cmd.append(f"--prompt={project.name}")
cmd.append(f"--python={python}")
cmd.append(project.get_location_for_virtualenv())
if project.s.PIPENV_VIRTUALENV_COPIES:
cmd.append("--copies")

# Pass site-packages flag to virtualenv, if desired...
if site_packages:
cmd.append("--system-site-packages")

return cmd


def do_create_virtualenv(project, python=None, site_packages=None, pypi_mirror=None):
"""Creates a virtualenv."""

Expand Down Expand Up @@ -989,46 +1010,22 @@ def do_create_virtualenv(project, python=None, site_packages=None, pypi_mirror=N
err=True,
)

try:
import venv # noqa

cmd = [
Path(sys.executable).absolute().as_posix(),
"-m",
"virtualenv",
"--creator=venv",
f"--prompt={project.name}",
f"--python={python}",
project.get_location_for_virtualenv(),
]
except ImportError:
cmd = [
Path(sys.executable).absolute().as_posix(),
"-m",
"virtualenv",
f"--prompt={project.name}",
f"--python={python}",
project.get_location_for_virtualenv(),
]

# Pass site-packages flag to virtualenv, if desired...
if site_packages:
click.echo(
click.style(fix_utf8("Making site-packages available..."), bold=True),
err=True,
)
cmd.append("--system-site-packages")

if pypi_mirror:
pip_config = {"PIP_INDEX_URL": pypi_mirror}
else:
pip_config = {}

# Actually create the virtualenv.
error = None
with console.status(
"Creating virtual environment...", spinner=project.s.PIPENV_SPINNER
):
cmd = _create_virtualenv_cmd(project, python, site_packages=site_packages)
c = subprocess_run(cmd, env=pip_config)
click.secho(f"{c.stdout}", fg="cyan", err=True)
if c.returncode != 0:
Expand All @@ -1052,7 +1049,6 @@ def do_create_virtualenv(project, python=None, site_packages=None, pypi_mirror=N
)

# Associate project directory with the environment.
# This mimics Pew's "setproject".
project_file_name = os.path.join(project.virtualenv_location, ".project")
with open(project_file_name, "w") as f:
f.write(project.project_directory)
Expand All @@ -1068,7 +1064,6 @@ def do_create_virtualenv(project, python=None, site_packages=None, pypi_mirror=N
pipfile=project.parsed_pipfile,
project=project,
)
project._environment.add_dist("pipenv")
# Say where the virtualenv is.
do_where(project, virtualenv=True, bare=False)

Expand Down
10 changes: 10 additions & 0 deletions pipenv/environments.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,16 @@ def __init__(self) -> None:
)
"""Tells Pipenv whether to name the venv something other than the default dir name."""

self.PIPENV_VIRTUALENV_CREATOR = get_from_env(
"VIRTUALENV_CREATOR", check_for_negation=False
)
"""Tells Pipenv to use the virtualenv --creator= argument with the user specified value."""

self.PIPENV_VIRTUALENV_COPIES = get_from_env(
"VIRTUALENV_COPIES", check_for_negation=True
)
"""Tells Pipenv to use the virtualenv --copies to prevent symlinks when specified as Truthy."""

self.PIPENV_PYUP_API_KEY = get_from_env("PYUP_API_KEY", check_for_negation=False)

# Internal, support running in a different Python from sys.executable.
Expand Down