diff --git a/news/5477.bugfix.rst b/news/5477.bugfix.rst index e6342dbca8..16388246b7 100644 --- a/news/5477.bugfix.rst +++ b/news/5477.bugfix.rst @@ -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. diff --git a/pipenv/core.py b/pipenv/core.py index 677845853c..00ed14e5b2 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -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.""" @@ -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: @@ -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) @@ -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) diff --git a/pipenv/environments.py b/pipenv/environments.py index b079d3902b..34bb0d160a 100644 --- a/pipenv/environments.py +++ b/pipenv/environments.py @@ -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.