mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
More granular control over PIPENV_VENV_IN_PROJECT variable. (#5026)
* Allow PIPENV_VENV_IN_PROJECT to be read in as None, and ensure if it is set to False that it does not use .venv directory. * refactor based on PR feedback and add news fragment. * Review unit test coverage and add new tests. Remove unneccesary bits from other tests.
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
Pipenv will now ignore ``.venv`` in the project when ``PIPENV_VENV_IN_PROJECT`` variable is False.
|
||||
Unset variable maintains the existing behavior of preferring to use the project's ``.venv`` should it exist.
|
||||
@@ -1 +0,0 @@
|
||||
Internal to pipenv, the utils.py was split into a utils module with unused code removed.
|
||||
+12
-4
@@ -297,10 +297,18 @@ class Setting:
|
||||
Default is 120 seconds, an arbitrary number that seems to work.
|
||||
"""
|
||||
|
||||
self.PIPENV_VENV_IN_PROJECT = bool(os.environ.get("PIPENV_VENV_IN_PROJECT"))
|
||||
"""If set, creates ``.venv`` in your project directory.
|
||||
|
||||
Default is to create new virtual environments in a global location.
|
||||
self.PIPENV_VENV_IN_PROJECT = os.environ.get("PIPENV_VENV_IN_PROJECT")
|
||||
if self.PIPENV_VENV_IN_PROJECT is not None:
|
||||
if self.PIPENV_VENV_IN_PROJECT.lower() in _true_values:
|
||||
self.PIPENV_VENV_IN_PROJECT = True
|
||||
elif self.PIPENV_VENV_IN_PROJECT.lower() in _false_values:
|
||||
self.PIPENV_VENV_IN_PROJECT = False
|
||||
else:
|
||||
self.PIPENV_VENV_IN_PROJECT = None
|
||||
""" When set True, will create or use the ``.venv`` in your project directory.
|
||||
When Set False, will ignore the .venv in your project directory even if it exists.
|
||||
Default is None will use the .venv of project directory should it exist, otherwise
|
||||
will create new virtual environments in a global location.
|
||||
"""
|
||||
|
||||
self.PIPENV_VERBOSE = bool(os.environ.get("PIPENV_VERBOSE"))
|
||||
|
||||
+3
-1
@@ -242,6 +242,8 @@ class Project:
|
||||
|
||||
def is_venv_in_project(self):
|
||||
# type: () -> bool
|
||||
if self.s.PIPENV_VENV_IN_PROJECT is False:
|
||||
return False
|
||||
return self.s.PIPENV_VENV_IN_PROJECT or (
|
||||
self.project_directory
|
||||
and os.path.isdir(os.path.join(self.project_directory, ".venv"))
|
||||
@@ -288,7 +290,7 @@ class Project:
|
||||
return str(get_workon_home().joinpath(self.virtualenv_name))
|
||||
|
||||
# If content looks like a path, use it as a relative path.
|
||||
# Otherwise use directory named after content in WORKON_HOME.
|
||||
# Otherwise, use directory named after content in WORKON_HOME.
|
||||
if looks_like_dir(name):
|
||||
path = Path(self.project_directory, name)
|
||||
return path.absolute().as_posix()
|
||||
|
||||
@@ -7,13 +7,15 @@ from tempfile import TemporaryDirectory
|
||||
|
||||
import pytest
|
||||
|
||||
from pipenv.environments import _true_values, _false_values
|
||||
from pipenv.utils.shell import normalize_drive, temp_environ
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
def test_venv_in_project(PipenvInstance):
|
||||
@pytest.mark.parametrize("true_value", _true_values)
|
||||
def test_venv_in_project(true_value, PipenvInstance):
|
||||
with temp_environ():
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = '1'
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = true_value
|
||||
with PipenvInstance() as p:
|
||||
c = p.pipenv('install requests')
|
||||
assert c.returncode == 0
|
||||
@@ -21,10 +23,38 @@ def test_venv_in_project(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
def test_venv_at_project_root(PipenvInstance):
|
||||
@pytest.mark.parametrize("false_value", _false_values)
|
||||
def test_venv_in_project_disabled_ignores_venv(false_value, PipenvInstance):
|
||||
venv_name = "my_project"
|
||||
with temp_environ():
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = false_value
|
||||
with PipenvInstance() as p:
|
||||
file_path = os.path.join(p.path, '.venv')
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(venv_name)
|
||||
|
||||
with temp_environ(), TemporaryDirectory(
|
||||
prefix='pipenv-', suffix='temp_workon_home'
|
||||
) as workon_home:
|
||||
os.environ['WORKON_HOME'] = workon_home
|
||||
c = p.pipenv('install requests')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('--venv')
|
||||
assert c.returncode == 0
|
||||
venv_loc = Path(c.stdout.strip()).absolute()
|
||||
assert venv_loc.exists()
|
||||
assert venv_loc.joinpath('.project').exists()
|
||||
venv_path = normalize_drive(venv_loc.as_posix())
|
||||
venv_expected_path = Path(workon_home).joinpath(venv_name).absolute().as_posix()
|
||||
assert venv_path == normalize_drive(venv_expected_path)
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
@pytest.mark.parametrize("true_value", _true_values)
|
||||
def test_venv_at_project_root(true_value, PipenvInstance):
|
||||
with temp_environ():
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = '1'
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = true_value
|
||||
c = p.pipenv('install')
|
||||
assert c.returncode == 0
|
||||
assert normalize_drive(p.path) in p.pipenv('--venv').stdout
|
||||
@@ -80,7 +110,7 @@ def test_venv_file(venv_name, PipenvInstance):
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
def test_empty_venv_file(PipenvInstance):
|
||||
"""Tests virtualenv creation when a empty .venv file exists at the project root
|
||||
"""Tests virtualenv creation when an empty .venv file exists at the project root
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
file_path = os.path.join(p.path, '.venv')
|
||||
@@ -109,9 +139,8 @@ def test_empty_venv_file(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
def test_venv_file_with_path(PipenvInstance):
|
||||
"""Tests virtualenv creation when a .venv file exists at the project root
|
||||
and contains an absolute path.
|
||||
def test_venv_in_project_default_when_venv_exists(PipenvInstance):
|
||||
"""Tests virtualenv creation when a .venv file exists at the project root.
|
||||
"""
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
with TemporaryDirectory(
|
||||
|
||||
@@ -405,8 +405,6 @@ def test_install_venv_project_directory(PipenvInstance):
|
||||
prefix="pipenv-", suffix="temp_workon_home"
|
||||
) as workon_home:
|
||||
os.environ["WORKON_HOME"] = workon_home
|
||||
if "PIPENV_VENV_IN_PROJECT" in os.environ:
|
||||
del os.environ["PIPENV_VENV_IN_PROJECT"]
|
||||
|
||||
c = p.pipenv("install six")
|
||||
assert c.returncode == 0
|
||||
|
||||
@@ -92,14 +92,9 @@ def test_proper_names_unamanged_virtualenv(PipenvInstance):
|
||||
def test_directory_with_leading_dash(raw_venv, PipenvInstance):
|
||||
with temp_environ():
|
||||
with PipenvInstance(chdir=True, venv_in_project=False, name="-project-with-dash") as p:
|
||||
if "PIPENV_VENV_IN_PROJECT" in os.environ:
|
||||
del os.environ['PIPENV_VENV_IN_PROJECT']
|
||||
c = p.pipenv('run pip freeze')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('--venv')
|
||||
assert c.returncode == 0
|
||||
venv_path = c.stdout.strip()
|
||||
assert os.path.isdir(venv_path)
|
||||
# Manually clean up environment, since PipenvInstance assumes that
|
||||
# the virutalenv is in the project directory.
|
||||
p.pipenv('--rm')
|
||||
|
||||
Reference in New Issue
Block a user