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

New env command and sub commands #731

Merged
merged 14 commits into from
Dec 18, 2018
Merged

New env command and sub commands #731

merged 14 commits into from
Dec 18, 2018

Conversation

sdispater
Copy link
Member

Pull Request Check List

  • Added tests for changed code.
  • Updated documentation for changed code.

This PR introduces a new env command with related sub commands, to make it easier to explicitly associate a Python version with the current project. This addresses #621.

Here are the changes:

New env use command

The env use command tells Poetry which Python version
to use for the current project.

poetry env use /full/path/to/python

If the python executable is in the PATH, it's possible to use it:

poetry env use python3.7

It's also possible in this case to only specify the minor Python version:

poetry env use 3.7

To disable the explicitly activated virtualenv, it's possible to use the
special system Python version to retrieve the default behavior:

poetry env use system

New env info command

The env info command displays basic information about the currently activated virtualenv:

poetry env info

will output something similar to this:

Virtualenv
Python:         3.7.1
Implementation: CPython
Path:           /path/to/poetry/cache/virtualenvs/test-O3eWbxRl-py3.7
Valid:          True

System
Platform: darwin
OS:       posix
Python:   /path/to/main/python

It's possible to only display the path of the virtualenv by passing the --path option
to env info:

poetry env info --path

New env list command

The env list command lists all the virtualenvs associated with the current virtualenv.

poetry env list

will output something like the following:

test-O3eWbxRl-py2.7
test-O3eWbxRl-py3.6
test-O3eWbxRl-py3.7 (Activated)

New env remove command

The env remove command deletes virtualenvs associated with the current project:

poetry env remove /full/path/to/python

Similarly to env use, it's possible to pass either python3.7, 3.7 or the name of
the virtualenv (as returned by env list):

poetry env remove python3.7
poetry env remove 3.7
poetry env remove test-O3eWbxRl-py3.7

Virtualenvs names now depend on the path of the project

This makes having different projects with the same name possible.

@sdispater sdispater added area/cli Related to the command line kind/feature Feature requests/implementations area/venv Related to virtualenv management labels Dec 11, 2018
@sdispater sdispater added this to the 1.0 milestone Dec 11, 2018
@sprt
Copy link
Contributor

sprt commented Dec 11, 2018

Really cool! I like the API.

Does the version info get persisted anywhere? I mean if I have a Python 3.7-only project, what happens when a new developer git clones the project and runs poetry install? Will the virtualenv use the default Python version?

@sdispater
Copy link
Member Author

@sprt This is a per-system feature, so the information is only persisted on the system the commands have been executed on. This is so that anyone can manage it's python versions and virtualenvs separately.

@jgirardet
Copy link
Contributor

That was a long way, but here it is thanks

@garyo
Copy link

garyo commented Dec 12, 2018

This is what I've been waiting for from poetry! Dependency management is great but we've needed a virtualenvwrapper replacement since it's apparently not being updated to use python -mvenv rather than venv, which is now sometimes required with python 3.7 at least on Ubuntu.

Some doc ideas:

  • which virtualenv env vars are used?
  • where virtualenvs go when created/used by poetry (and how to use ~/.virtualenvs if that's not the default)
  • Does it use the .project file in the virtualenv?
  • Also how to activate a poetry venv (I think it's just . $(poetry env info -p)/bin/activate or Scripts/ on Windows)

My big question: how can I use this right now? I'm not sure how to best install from the dev branch.

@sdispater
Copy link
Member Author

@garyo

which virtualenv env vars are used?

What do you mean? If you mean the VIRTUAL_ENV env var, Poetry will use it to determine the current virtualenv if it is set but Poetry does not set it itself, unless you use poerty shell.

 where virtualenvs go when created/used by poetry (and how to use ~/.virtualenvs if that's not the default)

Poetry creates the virtualenvs in its own cache directory, see: https://poetry.eustace.io/docs/configuration/#settingsvirtualenvspath-string

However, if you want them to be stored elsewhere, you can use the config command:

poetry config settings.virtualenvs.path ~/.virtualenvs

Does it use the .project file in the virtualenv?

What do you mean?

Also how to activate a poetry venv (I think it's just . $(poetry env info -p)/bin/activate or Scripts/ on Windows)

You have two choices here: . $(poetry env info --path)/bin/activate or poetry shell. Note that poetry shell will be improved before release 1.0.0.

Also, note that this is not a virtualenvwrapper replacement. The created virtualenvs are mainly intended to be used by Poetry and are mostly an implementation detail. The goal of Poetry is to not make the end users, especially newcomers, worry about virtualenvs.

As to how to use it right now, I would recommend waiting for the next alpha release of version 1.0.0 which I will make once this PR is merged. It would then be just a matter of executing poetry self:update --preview.

@garyo
Copy link

garyo commented Dec 12, 2018

Yes, primarily VIRTUAL_ENV. Also virtualenvwrapper and maybe others respect WORKON_HOME as the root of the virtualenv tree.
The .project file in the virtualenv can be used to cd to the project dir when activating, given only the virtualenv name. (I'm not sure if the standard activate script uses this or not.) (I don't think this is vital, I was just asking.)
As for activating, I tried subshells when I was using pipenv and hated them -- shell history, dir stack, shell vars, having to remember to not deactivate but exit instead... I definitely prefer activating in the current shell. Just my opinion.
Why do you say it's not a virtualenvwrapper replacement? It looks like it'll do everything I need -- which admittedly is pretty simple: just create envs in a central location, install stuff, activate in shells, and deactivate. Since virtualenvwrapper seems to be no longer maintained (last commit: Aug or Sept 2017 and already broken in python3.7) I think there is a need for something here and I'm hoping (at least for my simple use case) poetry can be it.

OK, I'll wait for the next alpha!

This was referenced Dec 12, 2018
@golyalpha
Copy link

golyalpha commented Dec 13, 2018

It would also be nice to have something like poetry env info --python to display path to the Python interpreter executable, just like IDEs like VSCode want it (as outlined in #278).

By the way, since we're still a long way off from having Poetry supported by the VSCode's Python extension, I've been scouring through it's docs, and I've found a way to at least get venvs from Poetry to show up in the interpreter selection menu:

"python.venvPath": "[path to poetry venvs]"

putting this in the user settings.json file (not the project one) results in this appearing in the interpreter selection menu:
image
You'll still have to fire up shell whenever you want to install project dependencies though.

@garyo
Copy link

garyo commented Dec 14, 2018

My venvs are in ~/.virtualenvs so venv-workon from that package TAB-completes the list. It's not ideally automated but it works enough for me.
It would be cool if the emacs code would parse the .project files in the virtualenvs and present any matching ones first, or just auto-select if only one. But that's a different project so let's take it up over there :-)

@bersace
Copy link

bersace commented Dec 14, 2018

Ok, I got emacs to use poetry venv :

$ poetry config settings.virtualenvs.path ${PYENV_ROOT}/versions
$ PYENV_VERSION=3.7.1 poetry install
$ poetry env info --path | basename > .python-version

Also, PROMPT_COMMAND activate .python-version if it's a venv.

@paranoidi
Copy link

This is nice welcomed addition! However please ensure that poetry install will automatically use correct version from pyproject.toml to create the virtualenv. The command is so simple and elegant that it would shame to complicate it by having to specify python version or worse create a wrong incompatible virtualenv. Which is unfortunately what is happening currently.

@geryogam
Copy link
Contributor

@sdispater, I think that @paranoidi's suggestion would improve the user experience dramatically. The default virtual environments created by the poetry add, poetry build, poetry install, poetry lock, poetry remove, poetry run, poetry shell, poetry show and poetry update commands should not be determined by the Python interpreter called by the #!/usr/bin/env python shebang line of the poetry script in the first place, but by the tool.poetry.dependencies.python property of the pyproject.toml file.

For instance, in the absence of an activated virtual environment and with the following pyproject.toml file:

[tool.poetry.dependencies]
python = "^3.7"

the poetry add, poetry build, poetry install, poetry lock, poetry remove, poetry run, poetry shell, poetry show and poetry update commands would create a Poetry built-in virtual environment with the Python 3.7 interpreter (like if the user had run the poetry env use 3.7 command), instead of one with the Python 2.7 interpreter as currently (like if the user had run the poetry env use system command).

@jabbalaci
Copy link

jabbalaci commented Nov 2, 2019

Is it available? "poetry env" says this command is not defined. I have version 0.12.17.

@tatianafrank
Copy link

Is it available? "poetry env" says this command is not defined. I have version 0.12.17.

I think this feature is part 1.0 release.

@tony
Copy link
Contributor

tony commented Dec 26, 2019

I'm having some difficulties getting the virtualenv path regardless of shell state (important for me due to keeping my session configuration scripts simple as possible):

It can't reliably give the pipenv equivalent of source pipenv --venv/bin/activate which gives the activate regardless of being already in an env or not.

  • outside the virtualenv, poetry env info isn't accessible since apparently multiple virtualenvs can exist. so poetry env list has to be used: source $(poetry env list --full-path | head -n 1 2> /dev/null)/bin/activate
  • inside the virtualenv env, poetry env info is used

If anyone has the same problem and considers this a feature request or a bug, feel free to make an issue. This seems like an observation / bikeshed at this point since only I'm complaining

@cglacet
Copy link

cglacet commented Dec 1, 2020

Is it supposed to work now (1.1.4)?

If it is, I get the following error:

❯ poetry env use python3.6.10
/bin/sh: python3.6.10: command not found

  EnvCommandError

  Command python3.6.10 -c "import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))" errored with the following return code 127, and output:


  at ~/.pyenv/versions/3.8.0/lib/python3.8/site-packages/poetry/utils/env.py:345 in activate
       341│                     shell=True,
       342│                 )
       343│             )
       344│         except CalledProcessError as e:
    →  345│             raise EnvCommandError(e)
       346│
       347│         python_version = Version.parse(python_version.strip())
       348│         minor = "{}.{}".format(python_version.major, python_version.minor)
       349│         patch = python_version.text

I do have this version installed:

❯ pyenv versions
  system
  3.6.1
  3.6.10

I tried to run using only 3.6, but it doesn't work either:

❯ poetry env use python3.6
pyenv: python3.6: command not found

The `python3.6' command exists in these Python versions:
  3.6.1
  3.6.10
  3.6.10/envs/raquel-3.6.10
  raquel-3.6.10

Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.

If I set the local interpreter to a 3.6 version it seems to work but I guess that's not the expected behaviour:

❯ pyenv local 3.6.10
❯ poetry env use python3.6
Recreating virtualenv .venv
Using virtualenv: .venv

But I still have only a single environnement visible by poetry:

❯ poetry env list
.venv (Activated)

And trying to switch back to the previous (3.8.0) will also fail.

I usually use pyenv virtualenv to handle my local environments.

Copy link

github-actions bot commented Mar 1, 2024

This pull request 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 Mar 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area/cli Related to the command line area/venv Related to virtualenv management kind/feature Feature requests/implementations
Projects
None yet
Development

Successfully merging this pull request may close these issues.