Skip to content

Commit

Permalink
Respect in-project config even when .venv exists
Browse files Browse the repository at this point in the history
Before this change, when .venv directory exists  within the project 
root, poetry will use it as the path to the venv regardless whether 
virtualenvs.in-project is set to true or not. This leads to confusion
as described in #1770 and #2756.

With this change poetry will check if virtualenvs.in-project is set to
true if it finds a .venv folder.

This commit also changes the default state of this configuration to be
unset (null), in order to not break any current environments.

Resolves: #1770 #2756
  • Loading branch information
finswimmer authored Sep 23, 2020
1 parent 32f11c3 commit 81b2774
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 19 deletions.
9 changes: 7 additions & 2 deletions docs/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ which will give you something similar to this:
```toml
cache-dir = "/path/to/cache/directory"
virtualenvs.create = true
virtualenvs.in-project = false
virtualenvs.in-project = null
virtualenvs.path = "{cache-dir}/virtualenvs" # /path/to/cache/directory/virtualenvs
```

Expand Down Expand Up @@ -110,7 +110,12 @@ Defaults to `true`.
### `virtualenvs.in-project`: boolean

Create the virtualenv inside the project's root directory.
Defaults to `false`.
Defaults to `None`.

If set to `true`, the virtualenv wil be created and expected in a folder named `.venv` within the root directory of the project.

If not set explicitly (default), `poetry` will use the virtualenv from the `.venv` directory when one is available. If set to `false`, `poetry` will ignore any existing `.venv` directory.


### `virtualenvs.path`: string

Expand Down
2 changes: 1 addition & 1 deletion poetry/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Config(object):
"cache-dir": str(CACHE_DIR),
"virtualenvs": {
"create": True,
"in-project": False,
"in-project": None,
"path": os.path.join("{cache-dir}", "virtualenvs"),
},
"experimental": {"new-installer": True},
Expand Down
7 changes: 4 additions & 3 deletions poetry/utils/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,11 @@ def get(self, reload=False): # type: (bool) -> Env

if not in_venv or env is not None:
# Checking if a local virtualenv exists
if (cwd / ".venv").exists() and (cwd / ".venv").is_dir():
venv = cwd / ".venv"
if self._poetry.config.get("virtualenvs.in-project") is not False:
if (cwd / ".venv").exists() and (cwd / ".venv").is_dir():
venv = cwd / ".venv"

return VirtualEnv(venv)
return VirtualEnv(venv)

create_venv = self._poetry.config.get("virtualenvs.create", True)

Expand Down
6 changes: 3 additions & 3 deletions tests/console/commands/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_list_displays_default_value_if_not_set(app, config):
expected = """cache-dir = "/foo"
experimental.new-installer = true
virtualenvs.create = true
virtualenvs.in-project = false
virtualenvs.in-project = null
virtualenvs.path = {path} # /foo{sep}virtualenvs
""".format(
path=json.dumps(os.path.join("{cache-dir}", "virtualenvs")), sep=os.path.sep
Expand All @@ -35,7 +35,7 @@ def test_list_displays_set_get_setting(app, config):
expected = """cache-dir = "/foo"
experimental.new-installer = true
virtualenvs.create = false
virtualenvs.in-project = false
virtualenvs.in-project = null
virtualenvs.path = {path} # /foo{sep}virtualenvs
""".format(
path=json.dumps(os.path.join("{cache-dir}", "virtualenvs")), sep=os.path.sep
Expand Down Expand Up @@ -83,7 +83,7 @@ def test_list_displays_set_get_local_setting(app, config):
expected = """cache-dir = "/foo"
experimental.new-installer = true
virtualenvs.create = false
virtualenvs.in-project = false
virtualenvs.in-project = null
virtualenvs.path = {path} # /foo{sep}virtualenvs
""".format(
path=json.dumps(os.path.join("{cache-dir}", "virtualenvs")), sep=os.path.sep
Expand Down
30 changes: 20 additions & 10 deletions tests/utils/test_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,27 @@ def test_virtualenvs_with_spaces_in_their_path_work_as_expected(tmp_dir, manager
assert venv.run("python", "-V", shell=True).startswith("Python")


def test_env_get_in_project_venv(manager, poetry):
if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"]

(poetry.file.parent / ".venv").mkdir()

@pytest.fixture
def in_project_venv_dir(poetry):
os.environ.pop("VIRTUAL_ENV", None)
venv_dir = poetry.file.parent.joinpath(".venv")
venv_dir.mkdir()
try:
yield venv_dir
finally:
venv_dir.rmdir()


@pytest.mark.parametrize("in_project", [True, False, None])
def test_env_get_venv_with_venv_folder_present(
manager, poetry, in_project_venv_dir, in_project
):
poetry.config.config["virtualenvs"]["in-project"] = in_project
venv = manager.get()

assert venv.path == poetry.file.parent / ".venv"

shutil.rmtree(str(venv.path))
if in_project is False:
assert venv.path != in_project_venv_dir
else:
assert venv.path == in_project_venv_dir


def build_venv(path, executable=None): # type: (Union[Path,str], Optional[str]) -> ()
Expand Down

0 comments on commit 81b2774

Please sign in to comment.