Similar to pipenv shell
, I would have expected that when running poetry shell
the virtualenv gets activated, but apparently this is not the case...
➜ which python
/Users/timon/.pyenv/shims/python
➜ poetry shell
Spawning shell within /Users/timon/Library/Caches/pypoetry/virtualenvs/YOLO-SAR-py3.7
➜ which python
/Users/timon/.pyenv/shims/python
➜ source /Users/timon/Library/Caches/pypoetry/virtualenvs/yolo-sar-py3.7/bin/activate
➜ which python
/Users/timon/Library/Caches/pypoetry/virtualenvs/yolo-sar-py3.7/bin/python
for comparison
➜ poetry run which python
/Users/timon/Library/Caches/pypoetry/virtualenvs/yolo-sar-py3.7/bin/python
Am I misunderstanding something and this is expected behaviour or is it a bug?
Thanks a lot already for your time :)
Came to file the same issue. My shell shows that a virtualenv is activated, but it's empty; if I manually activate the .venv (installing locally to the project directory) then it works, but I would expect poetry shell
to do that.
You might be experiencing #497.
@seansfkelley Confirmed, am experiencing #497. Good catch!
I am also experiencing this.
I have all my setup opensourced, so one can follow all the steps of my zsh
/pyenv
/poetry shell
madness. Here it is: https://github.com/sobolevn/dotfiles
Related parts:
Things I have tried:
if [[ -z "$VIRTUAL_ENV" ]]; then
eval "$(pyenv init -)"
fi
Now, it just ignores pyenv
when new shell is created by poetry shell
, but is still does not work as it should. Maybe we can have a look at how pipenv
handles this? It is working for me.
The shell
command has been problematic from the start due to different shell configurations.
I think the best approach would be to stick with executing the virtualenv's activate
file for now until a better solution comes up.
Maybe something like source "$(poetry venv)"
? So, there would be no need in shell
command.
Just in case someone else came googling for a quick but reliable temporary alternative that works in all shells:
# on .{bash,zsh,wtv}rc
alias poetry_shell='. "$(dirname $(poetry run which python))/activate"'
@sdispater senpai please note it's actually pretty easy to make it work in a subshell for posix at least, there are only a few decisions to be made about windows compability and extra deps see https://github.com/sdispater/poetry/issues/497#issuecomment-443619684
I don't have an activate script inside .venv/bin/
This is Poetry 0.12.10 installed via pip3 because of #721
In order to then get poetry shell
to do anything I also had to pip3 install six attrs
poetry install --no-dev
ran OK, I have a .venv
in my project, but there's no activate script at .venv/bin/activate
@drcongo Are you sure that .venv/bin/activate
is missing? It could be that it doesn't have execution permissions.
I just encountered this and Google'd my way to this Github issue. The following did not complain:
$ chmod u+x .venv/bin/activate
Unsure about why the execution permissions are not being properly set at install time though.
@jbmusso Yeah, positive it wasn't there. Not sure what the issue was now, I ended up dropping pyenv from my build so that may have been a contributing factor.
I know it's hard to make a decision. Can you update docs to let users know this issue before it's resolved? @sdispater
I came here to figure out what shell
(and run
) is actually supposed to do. I've had the same experience as the others, that it doesn't seem to work like virtualenv. The docs are silent as to this. E.g., I just want the basics, like:
I've been spending a lot of time debugging these two use cases, and haven't found a solution. To me, these are the most important commands, actually using the results of all the config work.
tl; dr — Move your pyenv
and poetry
configuration settings to ~/.bash_profile
(make sure poetry
configs come after pyenv
's) and out of ~/.bashrc
if you're using bash
.
I got stuck on this issue in bash
and the main issues seem to stem from the interaction of pyenv
and poetry
's PATH
-setting configuration found in my dotfiles:
# Initialize pyenv when a new shell spawns
eval "$(pyenv init -)"
# Modify path for Python's poetry dependency management system
export PATH="$HOME/.poetry/bin:$PATH"
I found that moving these scripts to ~/.bash_profile
(as opposed to ~/.bashrc
) helps resolve this issue. The problem in bash stems from the fact that ~/.bash_profile
gets executed only on login (OS X registers new windows / panes as logins), whereas ~/.bashrc
gets executed each time a shell is started. Because poetry shell
is running a bash
shell under the hood, it will also source ~/.bashrc
(and therefore the pyenv
script) when it is run, thus prepending pyenv
's shims to PATH
after the virtual env is activated. By moving these configuration settings to ~/.bash_profile
, we avoid this issue and the virtual env can prepend its path to PATH
unfettered.
@wfa207 more details at https://github.com/sdispater/poetry/issues/198#issuecomment-430742299, which is linked from the (arguable duplicate of this issue) https://github.com/sdispater/poetry/issues/497.
@betafcc :
Just in case someone else came googling for a quick but reliable temporary alternative that works in all shells:
# on .{bash,zsh,wtv}rc alias poetry_shell='. "$(dirname $(poetry run which python))/activate"'
Or as a bash
/zsh
function ('functions' are a bit more flexible than alias, in scripting). I've renamed to poetry_activate
to show it is not a subshell
function poetry_activate () {
local _python="python${PYTHON_VERSION:-}" # you can do PYTHON_VERSION=2.7, PYTHON_VERSION=3.7 etc
local activation_script="$( dirname $( poetry run which ${_python} ) )/activate"
. "${activation_script}"
}
update: 👇 https://github.com/sdispater/poetry/issues/571#issuecomment-473438295 👇
Maybe something like
source "$(poetry venv)"
? So, there would be no need inshell
command.
This is my vote too 😀
Oh! The following is already supported in latest master
at least - I think this is plenty.
source "$( poetry env info --path )/bin/activate"
This is more performant (relevant if you want to do something like 'try/ensure' virtualenv activated before _every_ invocation of python
, etc, in your scripts) --
[ -z "${VIRTUAL_ENV:-}" ] && source "$( poetry env info --path )/bin/activate"
So then IMHO all we really need is
poetry shell
for deprecation.export POETRY_ACTIVE=1
to activate
script, upon any virtualenv creation. (otherwise poetry run
will have POETRY_ACTIVE
but not when you just source the activate
script.)If you're on Poetry 0.12.x that doesn't have env info
but only debug:info
, you can use:
source "$(poetry debug:info | rg '.*Path:[^/]+(.*)' -r '$1')/bin/activate"
(rg = ripgrep, though you could do it with grep and sed too)
or in alias form with escaping
alias activate=$'source "$(poetry debug:info | rg \'.*Path:[^/]+(.*)\' -r \'$1\')/bin/activate"'
If you're on Poetry 0.12.x that doesn't have
env info
but onlydebug:info
, you can use:source "$(poetry debug:info | rg '.*Path:[^/]+(.*)' -r '$1')/bin/activate"
Just a heads up for this to work make sure you've enabled the creation of virtualenvs:
poetry config settings.virtualenvs.create true
How would this work in the fish shell?
Anyone else find it odd that it's so tricky to get a virtualenv up and activated? To me, that's a main use case of poetry/pipenv/venv.
Starting with poetry 1.0.0beta2 you can do:
source $(poetry env info -p)/bin/activate
@dogweather That is not a constructive comment. You’re suggesting there’s some “natural” way to do this. There are many conflicting preferences people have about this.
If you want to add some detail to a usage, that’s constructive. For example, could you say if this works for you - currently it is, “source $(poetry env info -p)/bin/activate” if you want to just activate without going into subshell. (Or simply “poetry shell” if interactive subshell works for you). Don’t like this? Please be constructive in offering your take on a. more convenient workflow. “source $(poetry env activation)”? Etc.
Anyways, if that is your main use case, you should just look at autoenv and related. stdlib + venv is all you need if your comment is to be taken seriously.
Poetry/etc are about robust dependency management. Niceties about virtualenv are a small aspect. And keep in mind many of us want to use the same tools for multiple projects; too much “automatic assumptions for everyone” will hurt many multi-project use cases.
Went a slightly different route to above but same idea in my .bashrc:
poetry() {
if [[ $@ == "shell" ]]; then
if ([[ -f "$(poetry env info -p)/bin/activate" ]] && [[ -z "${VIRTUAL_ENV:-}" ]]); then
command source $(poetry env info -p)/bin/activate
else
command poetry "$@"
fi
else
command poetry "$@"
fi
}
Seems to work on WSL on Win10, just exploiting the fact bash will prioritise functions over aliases over binaries in path so wrapping it around to check if bin/active exists, and that the current shell isn't a virtualenv, if so, activate it.
In this scenario even if poetry shell is deprecated it'll still work on my environment for now.
I have a similar issue on Windows 10. I use Visual Studio Code and I have configured the Terminal of VSCode to use git bash. So when I open the Visual Studio code terminal an execute poetry shell -vvv
I get
Using virtualenv: C:\Users\Alexa\AppData\Local\pypoetry\Cache\virtualenvs\my-project-py3.7
Spawning shell within C:\Users\Alexa\AppData\Local\pypoetry\Cache\virtualenvs\my-project-py3.7
[RuntimeError]
Unable to detect the current shell.
Exception trace:
C:\Users\Alexa\.poetry\lib\poetry\_vendor\py3.7\cleo\application.py in run() at line 94
status_code = self.do_run(input_, output_)
C:\Users\Alexa\.poetry\lib\poetry\console\application.py in do_run() at line 88
return super(Application, self).do_run(i, o)
C:\Users\Alexa\.poetry\lib\poetry\_vendor\py3.7\cleo\application.py in do_run() at line 197
status_code = command.run(input_, output_)
C:\Users\Alexa\.poetry\lib\poetry\console\commands\command.py in run() at line 77
return super(BaseCommand, self).run(i, o)
C:\Users\Alexa\.poetry\lib\poetry\_vendor\py3.7\cleo\commands\base_command.py in run() at line 146
status_code = self.execute(input_, output_)
C:\Users\Alexa\.poetry\lib\poetry\_vendor\py3.7\cleo\commands\command.py in execute() at line 107
return self.handle()
C:\Users\Alexa\.poetry\lib\poetry\console\commands\shell.py in handle() at line 40
shell = Shell.get()
C:\Users\Alexa\.poetry\lib\poetry\utils\shell.py in get() at line 37
raise RuntimeError("Unable to detect the current shell.")
shell
Any solutions for this?
@alex-lechner that looks like a different issue and I suggest you file a different ticket for it.
I've had the same issue as reported in https://github.com/sdispater/poetry/issues/1118.
For those on a Poetry version without the env
command (like me, for example, on 0.12.16), you can also parse debug:info
. I have this in my bashrc:
[ -z "${POETRY_ACTIVE}" ] || source "$(poetry debug:info | grep Path | awk '{print $3}')/bin/activate"
@ziofil For fish, try:
alias poetry_shell='. (dirname (poetry run which python))/activate.fish'
For those of you in a Windows shop, the following works in Powershell. I have something similar in my GitLab CI configuration to take advantage of the venv caching of poetry, among other beautiful things that poetry does
invoke-expression $($(poetry debug:info | sls Path | Out-String -Width 1000 | % {$_.replace("* Path: ", "").trim()}) + "\Scripts\activate.ps1")
Just for info, while waiting for a proper fix, I'm using the following alias:
alias poetry_activate='bash --rcfile <(echo ". \"$HOME/.bashrc\"; . $(dirname $(poetry run which python))/activate")'
Advantage is that, just like pipenv shell
, it launches a new shell (in my case, bash) with the venv activated.
FTR:
Are you sure that
.venv/bin/activate
is missing? It could be that it doesn't have execution permissions.
The activate script must be sourced, not run, in order to edit the current shell configuration rather than run a sub-shell. That’s why it does not have the executable bit. (If Python install layouts had standard data directories like $prefix/share
on unix, the script would be there, avoiding the confusion created by putting it in bin
.)
Editing the current shell has issues and proves confusing, so there are other approaches based on sub-shells exist, like inve or poetry shell.
In my case pyenv
initialization was happening every time Poetry spawned a new shell.
As a workaround I moved pyenv
initialization from .zshrc
to .profile
, so that it will initialize only once, not on every shell spawn, appending shims directory to $PATH
over and over.
I think same fix can be used with .bashrc
or removing pyenv
from plugins, if you're using something like Oh My Zsh.
This was still broken in 1.0.0b7, but has been resolved in 1.0.0b8 (and is still working in 1.0.0b9). Thank you.
The shell
command has been improved in the latest 1.0.0
version and virtual environments should now be properly activated.
I am experiencing this issue in Poetry version 1.0.2; poetry shell
does not seem to activate the venv (I get eg. zsh: command not found: django-admin
when trying to run django-admin), and running poetry shell
a second time tells me it's already activated but still django-admin
is not found. But source .venv/bin/activate
does work, and adds the (.venv)
text to my command line prompt.
I use the setting that puts the venv in the local directory. The venv was created with poetry init
.
I have some pyenv environment variable stuff in my .zshrc
, and only this line in my .zprofile
: export PATH="$HOME/.poetry/bin:$PATH"
Note I also have miniconda installed, though I don't use it much.
I tried moving these two lines to before poetry's stuff in .zprofile
, and out of .zshrc
:
export PATH="$(pyenv root)/shims:$PATH"
export PYENV_VERSION=3.6.4
export PATH="$HOME/.poetry/bin:$PATH"
But now if I run poetry shell
I get this error due to not escaping my path that has a space in it:
(base) ➜ hue_app git:(master) ✗ poetry shell
Spawning shell within /Users/phoenix/Code/_personal projects/hue_app/.venv
Identity added: /Users/phoenix/.ssh/id_rsa_phoenix (/Users/phoenix/.ssh/id_rsa_phoenix)
(base) ➜ hue_app git:(master) ✗ . /Users/phoenix/Code/_personal projects/hue_app/.venv/bin/activate
.: no such file or directory: /Users/phoenix/Code/_personal
Am just looking for a way to deactivate the env poetry created. even when i close the poetry shell and run poetry env list it still show (Activated) how can i deactivate this? or is it ok to just leave it activated?
@sdispater I am experiencing this still on poetry 1.0.5 running on Ubuntu 20.04 under WSL2.
the virtual environment is in ~/.cache/pypoetry/virtualenvs
Whoever ends up here might be interested in setting up automatic Poetry virtualenv activation using direnv.
Most helpful comment
Just in case someone else came googling for a quick but reliable temporary alternative that works in all shells: