pdm icon indicating copy to clipboard operation
pdm copied to clipboard

After `venv activate`, packages are still installed in the previous venv

Open gjoseph92 opened this issue 2 years ago • 1 comments

Is your feature request related to a problem? Please describe.

It's confusing UX that pdm venv activate is not linked up to pdm use. When you activate a venv, all pdm commands will continue to target the environment that was active before, until you run pdm use "$(which python)". This is confusing and hard to remember.

Example
(pdm-test-3.10) gabe ~/pdm-test » cat pyproject.toml 
[project]
name = ""
version = ""
description = ""
authors = [
    {name = "Gabe Joseph", email = "[email protected]"},
]
dependencies = [
    "requests>=2.28.2",
]
requires-python = ">=3.9"
license = {text = "MIT"}

[tool.pdm]
(pdm-test-3.10) gabe ~/pdm-test » pdm info
PDM version:
  2.4.8
Python Interpreter:
  /Users/gabe/pdm-test/.venv/bin/python (3.10)
Project Root:
  /Users/gabe/pdm-test
Project Packages:
  None
(pdm-test-3.10) gabe ~/pdm-test » pdm venv create -n py39 3.9
Virtualenv /Users/gabe/Library/Application Support/pdm/venvs/pdm-test-RhWMxf7d-py39 is created successfully
(pdm-test-3.10) gabe ~/pdm-test » eval $(pdm venv activate py39)
(pdm-test-3.9) gabe ~/pdm-test » 
(pdm-test-3.9) gabe ~/pdm-test » pdm add cowsay
Adding packages to default dependencies: cowsay
🔒 Lock successful
Changes are written to pdm.lock.
Changes are written to pyproject.toml.
Synchronizing working set with lock file: 1 to add, 0 to update, 0 to remove

  ✔ Install cowsay 5.0 successful

🎉 All complete!

(pdm-test-3.9) gabe ~/pdm-test » cowsay
zsh: command not found: cowsay
(pdm-test-3.9) gabe ~/pdm-test » pdm sync  
All packages are synced to date, nothing to do.

🎉 All complete!

(pdm-test-3.9) gabe ~/pdm-test » pdm info
PDM version:
  2.4.8
Python Interpreter:
  /Users/gabe/pdm-test/.venv/bin/python (3.10)  # notice that the 3.10 interpreter is still active
Project Root:
  /Users/gabe/pdm-test
Project Packages:
  None
(pdm-test-3.9) gabe ~/pdm-test » pdm use "$(which python)"
Using Python interpreter: /Users/gabe/Library/Application Support/pdm/venvs/pdm-test-RhWMxf7d-py39/bin/python (3.9)
(pdm-test-3.9) gabe ~/pdm-test » pdm sync
Synchronizing working set with lock file: 6 to add, 0 to update, 0 to remove

  ✔ Install idna 3.4 successful
  ✔ Install certifi 2022.12.7 successful
  ✔ Install requests 2.28.2 successful
  ✔ Install urllib3 1.26.14 successful
  ✔ Install charset-normalizer 3.1.0 successful
  ✔ Install cowsay 5.0 successful

🎉 All complete!

(pdm-test-3.9) gabe ~/pdm-test » cowsay hello from 3.9
  ______________
| hello from 3.9 |
  ==============
              \
               \
                 ^__^
                 (oo)\_______
                 (__)\       )\/\
                     ||----w |
                     ||     ||
(pdm-test-3.9) gabe ~/pdm-test » 

Describe the solution you'd like

I'd like if eval "$(pdm venv activate)" also made PDM use the activated environment.

I'd most prefer a pdm shell command though, like poetry, pyenv, etc. Not only is this more convenient, but I'd hope it could be implemented in a way that didn't require modifying .pdm.toml. That way, you could have multiple shells open to different venvs at the same time.

gjoseph92 avatar Mar 10 '23 17:03 gjoseph92

Confirmed. I just struggled with this again. Starting from scratch, and doing what I think is reasonable:

Example with comments about what I expected to happen.
$ pdm venv create
[FileNotFoundError]: [Errno 2] No such file or directory: '.../.venv/bin/python'
Add '-v' to see the detailed traceback

Well, of course not: I am trying to create it... maybe I need to specify which python to use? (This is a very unhelpful error message.)

$ pdm use /opt/local/bin/python3.7
Using the last selection, add '-i' to ignore it.
Using Python interpreter: /opt/local/bin/python3.7 (3.7)
[FileNotFoundError]: [Errno 2] No such file or directory: '.../.venv/bin/python'
Add '-v' to see the detailed traceback

Same error message. Ah. I forgot to add the -i flag. Why does PDM cache this when the last operation failed?

$ pdm use -i /opt/local/bin/python3.7
Using Python interpreter: /opt/local/bin/python3.7 (3.7)
$ pdm venv create
Virtualenv .../.venv is created successfully
$ pdm venv activate
Can't activate a non-venv Python /opt/local/bin/python3.7, you can specify one with pdm venv activate <env_name>

What does this mean? I just created the venv? Well, I will follow the suggestion:

$ pdm venv activate .venv   # Why does this not work?
No virtualenv with key .venv is found
$ pdm venv list
Virtualenvs created with this project:

-  in-project: /Users/mforbes/work/mmfgh/zopeext/.venv
$ pdm venv activate -
No virtualenv with key - is found
$ pdm venv activate in-project
source /Users/mforbes/work/mmfgh/zopeext/.venv/bin/activate

Minor gripe: the dash - is sometimes meaningful, though I realize now that it is just a bullet. Does one need bullets here? They are confusing. It might be good if the the docs had an example of in-project there. Also, following tools like conda, it seems maybe reasonable that if the argument is a directory that is a venv, then this will be processed? Perhaps the key in-project could even be renamed .venv so that this just works? Proceeding...

$ source /Users/mforbes/work/mmfgh/zopeext/.venv/bin/activate
(zopeext-3.7) $ 

As I have discussed before, at this point I expect to be able to install everything into the virtual environment, which is what this issue requests, however, everything is still installed in the previous venv - in this case, __pypackages__.

(zopeext-3.7) $ pdm install
Synchronizing working set with lock file: 47 to add, 0 to update, 0 to remove
...

It might be helpful if PDM could give some notification at this point about where these are being installed. For example:

Installing into __pypackages__ since the python in .pdm.toml is not in a .venv.
(Use pdm use .venv/bin/python to use the current venv.)
...

pdm config gives some hint, but is contradictory

(zopeext-3.7) $ pdm config
...
venv.backend = virtualenv
venv.in_project = True
...
python.path = /opt/local/bin/python3.7

Since I created .venv with this python, I thought this was simply recording the actual base python on my machine.

The correct thing to do of course is:

(zopeext-3.7) $ pdm use .venv/bin/python
Using the last selection, add '-i' to ignore it.     # What does this mean?
Using Python interpreter: .../.venv/bin/python (3.7)

I am very confused by the Using the last selection, add '-i' to ignore it. comment. It seems like the last selection is not being used in this case. Perhaps I need to do

(zopeext-3.7) $ pdm use -i .venv/bin/python
Using the last selection, add '-i' to ignore it.     # What does this mean?
Using Python interpreter: .../.venv/bin/python (3.7)

Anyway, finally, the install works like I think it should... but there is no indication - the output looks exactly the same as before:

(zopeext-3.7) $ pdm install 
Synchronizing working set with lock file: 47 to add, 0 to update, 0 to remove
...

The takeaway is that it seems the shortest way to guarantee that things work is something like:

$ pdm use -i /opt/local/bin/python3.7
Using Python interpreter: /opt/local/bin/python3.7 (3.7)
$ PDM_VENV_IN_PROJECT=1 PDM_USE_VENV=1 PDM_VENV_BACKEND=virtualenv pdm venv create
Virtualenv .../.venv is created successfully
$ pdm use -i .venv/bin/python
$ . .venv/bin/activate
(zopeext-3.7) $ pdm install
Synchronizing working set with lock file: 47 to add, 0 to update, 0 to remove
...

when, as requested in this issue, the shortest path (with an appropriate configuration and access to appropriate python versions) should be something like

$ pdm shell
Virtualenv .../.venv is created successfully
Starting new shell with active virtualenv .../.venv/
Checking dependencies...
Synchronizing working set with lock file: 47 to add, 0 to update, 0 to remove
...
(zopeext-3.7) $

I.e., pdm shell checks the configuration, sees that venv.in_project is True, creates an in-project virtualenv if needed with the specified backend, activates that virtualenv, updates the packages to make sure that the dev tools are installed and at the correct version, and then allows the user to work in this new shell.

mforbes avatar Mar 19 '23 03:03 mforbes

Use pdm use to switch the env used by PDM

frostming avatar Jul 08 '24 09:07 frostming