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

Option to create virtual environments in the project root (.venv) #108

Closed
jacebrowning opened this issue May 15, 2018 · 42 comments
Closed
Labels
area/config Related to configuration management kind/feature Feature requests/implementations

Comments

@jacebrowning
Copy link
Contributor

jacebrowning commented May 15, 2018

I'm considering migrating some of my projects from pipenv to poetry. I would like to be able to tell poetry to create virtual environments at ./.venv/ to support Makefile target dependencies, CI build caching, and automatic IDE support.

I added a feature to pipenv to detect and use virtual environments located at ./.venv/ based on the mere presence of a directory of that name. It looks like poetry nearly has the same behavior:

https://github.com/sdispater/poetry/blob/87c4aaf9cadbbb6c5657101d715b5a4e1a8d9a05/poetry/utils/venv.py#L55-L59

but I noticed that if .venv is an empty directory (in order to let the tool populate it) poetry seems to install dependencies into my global Python instead.

Would you consider a PR to add another case to this logic to create virtual environments in the root of a project? This should allow poetry to handle all of the following scenarios:

  • Use the currently activated virtual environment ($VIRTUAL_ENV set)
  • Use the exiting local virtual environment (./.venv/<bin>/python exists)
  • [NEW] Create a new local virtual environment (./.venv/ is empty)
  • Use the previously cached virtual environment
  • Create a new cached virtual environment
@jacebrowning
Copy link
Contributor Author

Alternatively, an option in pyproject.toml to specify the virtual environment location would also be great!

@sdispater
Copy link
Member

I might add a setting that can be set via the config command to tell poetry to create the virtualenv inside the project directory.

The only downside to that is that you can only have one virtualenv by project.

@sdispater sdispater added enhancement area/config Related to configuration management labels May 17, 2018
@buriy
Copy link

buriy commented May 18, 2018

@jacebrowning isn't there a config option already? https://github.com/sdispater/poetry/blob/87c4aaf9cadbbb6c5657101d715b5a4e1a8d9a05/poetry/utils/venv.py#L64
Not a command-line one, though, yet.

@jacebrowning
Copy link
Contributor Author

jacebrowning commented May 18, 2018

@buriy How might I use that? I'm having trouble understanding the documentation here:

$ poetry config -h
Usage:
  config [options] [--] <key> [<value>]...

...

 To add a repository:

     poetry repositories.foo https://bar.com/simple/

 To remove a repository (repo is a short alias for repositories):

     poetry --unset repo.foo
$  poetry virtualenvs.path .venv

[CommandNotFound]
Command "virtualenvs.path" is not defined.
$ poetry config virtualenvs.path .venv

[ValueError]
Setting virtualenvs.path does not exist

config [--list] [--unset] [--] <key> [<value>]...
$ poetry config settings.virtualenvs.path .venv

[ValueError]
Setting settings.virtualenvs.path does not exist

config [--list] [--unset] [--] <key> [<value>]...

@buriy
Copy link

buriy commented May 19, 2018

@jacebrowning I guess if you manually create the config.toml file, it would work, but there's no CLI support for that right now. Please, could you try if that works?

@sdispater
Copy link
Member

@buriy @jacebrowning This setting is here to tell poetry where to create every virtualenv so it wouldn't work for this use case. That's why I am thinking of adding a new setting to tell poetry to create the virtualenv for the current project inside the .venv directory.

@digitalresistor
Copy link
Contributor

Having a .venv directory would be great since many tools look there for formatting tools and the like, specifically I am thinking of ALE for Vim.

@Victor-Savu
Copy link

Victor-Savu commented May 21, 2018

Just wanted to point out the similarity to the approach Rust's package manager cargo has. cargo creates a directory target in the project root where it places all the dependencies and compilation artifacts. The proposed .venv directory seems to go in the same direction.

@ghost
Copy link

ghost commented May 22, 2018

Python packages can/have to support both python2 and python3, whereas you rarely need multiple rust versions to compile with.

Something along these lines in the pyproject.toml being used to create venvs could go a long way:

[tool.poetry.virtualenvs]
venv = { python = "~2.7" }
venv3 = { python = "^3.5" }

@Victor-Savu
Copy link

@kelseasy I just thought it would be fun to share this: https://pythonclock.org/

@buriy
Copy link

buriy commented May 26, 2018 via email

@sdispater
Copy link
Member

The new settings.virtualenvs.in-project setting is now available. You can activate it with:

poetry config settings.virtualenvs.in-project true

@Imaclean74
Copy link
Contributor

Imaclean74 commented Jun 23, 2018

This is great - glad to be able to set this. Question though - does it make more sense for local .venv to be the default ? This is the first thing I changed when I started using pipenv - since it also wants to create the venv under user settings. More than likely - I'm missing some fundamental reason that using user settings is a better option - but arguments for defaulting to local .venv might be :

  • Obvious where those deps went - you have new directory right there
  • This is how npm works - so familiarity for devs with any java script experience. Devils advocate - gradle uses a shared cache - and I don't know what cargo ( one inspiration for poetry ? ) uses.
  • familiar for python devs used to the standard virtualenv workflow
  • the tooling issue raised by a few others. VSCode for example will automatically find a local venv - but has no way of knowing which venv under /Users//Library/Caches/pypoetry/virtualenvs to look for

@Atrox
Copy link

Atrox commented Jan 9, 2019

Sorry for commenting on an old issue, but is there a way to set this option for a project (in pyproject.toml) and not per machine with poetry config?

@b-long
Copy link

b-long commented Apr 11, 2019

@Atrox This looks like an open issue: #618

@brycedrennan brycedrennan added kind/feature Feature requests/implementations and removed enhancement labels Aug 17, 2019
@Cito
Copy link

Cito commented Sep 10, 2019

I noticed in v1 beta it only works without the settings.-prefix: poetry config virtualenvs.in-project true

@bangseongbeom
Copy link

@Cito, you mean poetry config --local virtualenvs.in-project true?

@Cito
Copy link

Cito commented Sep 11, 2019

@bangseongbeom Yes, sorry, corrected that already.

@jwiede
Copy link

jwiede commented Jan 19, 2020

If you had a project created using virtualenvs.in-project=false, and then subsequently set the config setting to true, is there any way to get poetry to copy the venv contents from its prior venv location to the "new" location?

@heynemann
Copy link

@jwiede yes you can. Just do the following:

$ poetry env list

Find the name of the virtual environment you currently have.

$ poetry env remove

This will delete the Venv. Now just do poetry install and it will work out.

@cgarciae
Copy link

cgarciae commented Feb 4, 2020

It would be nice if this was the default so you don't end up with zombie environments when you delete a project's folder.

@joshfriend
Copy link

I've read numerous issues for both poetry and pipenv about placing the venv in the project directory by default and cannot recall a single reason why that is a bad idea.

@Cito
Copy link

Cito commented Feb 6, 2020

@joshfriend One disadvantage is that you can easily create monster size backups with the ".venv" und "node_modules" sub-directories of all your various projects, which is completely unnecessary because you can easily recreate them. It took me quite a while to find a backup program that allows to generally ignore sub-directories with certain names, and not just a list of fixed paths or files with certain extensions. If the ".venv"s are all in a central place, you can more easily exclude them from backups.

@cgarciae
Copy link

cgarciae commented Feb 6, 2020

@joshfriend This is a good use case for global directory feature but not a reason why it should be the default. I think 90% or more of the users would benefit with the more transparent and maintainable local strategy.

The local .venv folder is even recognized by vscode automatically while the with the global strategy its a bit tricky to setup at first. In other words, using the local .venv folder improves user experience a lot for those starting to get familiar with poetry.

@cgarciae
Copy link

cgarciae commented Feb 6, 2020

@sdispater local (in-project) by default would be an amazing feature for 1.0.0!

@joshfriend
Copy link

1.0 has already been released 😄

I'm glad @Cito mentioned the backups reason, personally I don't mind having 100 venvs in my backups, but thats not true for everyone ;)

I still don't think thats a good enough reason to keep in-project .venv location off by default.

@Cito
Copy link

Cito commented Feb 6, 2020

@joshfriend to be clear about that - I also like to have my .venvs local and think that should be the default. The backups only became really problematic for me once I started to have also node_modules directories in my projects, which serve a similar purpose in JavaScript, are always local and are notoriously known as heaviest objects in the universe.

@Cito
Copy link

Cito commented Feb 6, 2020

Local .venvs are also automatically recognized by PyCharm.

@gsemet
Copy link

gsemet commented Feb 10, 2020

With poetry > 1.0.0, the command to set in-project venv is:

poetry config --local virtualenvs.in-project true

@mikelnrd
Copy link

And VSCode

Local .venvs are also automatically recognized by PyCharm.

@ChristianSauer
Copy link

There is also the problem that shared configuration in VSCode does not really work without local envs.
The shared configuration takes a path - and this path is different for every user if the .venv is not in the project directory.
Honestly, bkacups are not even on my radar, I use git and a matching .gitignore.

@gsemet
Copy link

gsemet commented May 14, 2020

Why not using a $ variable ?

@b-long
Copy link

b-long commented May 14, 2020

I'm surprised that the poetry.toml file hasn't been mentioned on this thread. I place a file called poetry.toml into all of my Python projects:

[virtualenvs]
create = true
in-project = true

This produces a local .venv/ folder, and you can configure your editor to point to it using a relative path. For example, with VSCode, you could place this in settings.json:

"python.pythonPath": "${workspaceFolder}/.venv/bin/python"

@joshfriend
Copy link

I've been reading and commenting on threads like this both in Poetry and Pipenv for well over 2 years now and it seems pretty clear to me that the most beneficial default is having in-project be true. I think a LOT of people don't care either way, probably because they don't understand the benefits of in-project, whose docs mention zero reasons for or against using it. Then there are the users like myself who actually do care, because we want our development tools to integrate easily with each other.

The remaining users have a few (valid) edge cases that they care about which I'm fairly certain make up the minority:

  1. Reducing backup size and clutter
  2. Another case I saw on a different thread was about using poetry/pipenv locally and with a docker container simultaneously. in-project would cause the venv to be shared with two incompatible platforms, whereas the hidden venv option takes care of that

I don't think either is difficult to work around, and I think the benefits of compatibility with PyCharm/VSCode/etc should carry more weight in the decision of what should be the default.

Further, to what @b-long is saying above me, I knew exactly what I wanted poetry to do for me and I still found it difficult to find the CLI command to set that flag or write it manually in pyproject.toml.

in-project=true as the default would be amazing for the development experience. I'm 🙏 begging y'all to change it 😆

@mfoglio
Copy link

mfoglio commented May 27, 2020

I'm surprised that the poetry.toml file hasn't been mentioned on this thread. I place a file called poetry.toml into all of my Python projects:

[virtualenvs]
create = true
in-project = true

This produces a local .venv/ folder, and you can configure your editor to point to it using a relative path. For example, with VSCode, you could place this in settings.json:

"python.pythonPath": "${workspaceFolder}/.venv/bin/python"

But does that the path configuration works too? Because it seems to be ignored.
Source: https://python-poetry.org/docs/configuration/#virtualenvspath-string

@Pet3ris
Copy link

Pet3ris commented Jul 23, 2021

The setting has now changed to:

poetry config virtualenvs.in-project true

@n-ae
Copy link

n-ae commented Jan 4, 2022

poetry config virtualenvs.in-project true --local

could be useful for enabling it exclusively in a project. For example you may want to use a formatter installed with dev dependency in settings.json in vscode as in settings.json:

{
  "python.formatting.provider": "black",
  "python.formatting.blackPath": "${workspaceFolder}/.venv/bin/black"
}

dimbleby pushed a commit to dimbleby/poetry that referenced this issue Apr 21, 2022
* Fix for including modules from different locations

When we define multiple packages from different source locations,
Poetry currently only uses the last specified from= location.
This patch adds explicit paths to package_dir for additional packages.

This fixes python-poetry#1811, fixes python-poetry#2354,
and possibly even python-poetry#2450.

* Test the fix for including modules from different locations

When we try to include moduleA from libA and moduleB from libB then
package_dir in the generated setup.py must to contain either one or
both `"moduleA": "libA/moduleA"` or `"moduleB": "libB/moduleB"`
so we are able to find both modules when building the source dist.

`ns["package_dir"].keys() == {"", "module_b"}`
should always be true, so we don't have to test for module_a in
`ns["package_dir"]`.
@hector97i
Copy link

@Cito, you mean poetry config --local virtualenvs.in-project true?

This is the thing everyone needs.

@lordvcs
Copy link

lordvcs commented Oct 31, 2022

is it possible to set this configuration in pyproject.toml. I tried the below but it wont work

[virtualenvs]
in-project = true

@neersighted
Copy link
Member

It is set in poetry.toml which is the local configuration file for Poetry instances. This is both covered in the documentation and the above suggested command (poetry config --local virtualenvs.in-project true).

@Lewiscowles1986
Copy link

I Have set this in poetry.toml. I don't love having another toml, so I tried to add to pyproject.toml under tool.poetry.virtualenvs but it did not work, and even triggered a lot of vscode warnings.

Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 29, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area/config Related to configuration management kind/feature Feature requests/implementations
Projects
None yet
Development

No branches or pull requests