Home > Software design >  Can't install packages in virtual environment created with venv
Can't install packages in virtual environment created with venv

Time:11-14

I am developing in the following environment:

  • Windows11 21H2.
  • Ubuntu-20.04
  • Visual Studio Code 2022
  • Remote-WSL extension in VSCode
  • Python3.8.10 64-bit

I formatted a USB drive in NTFS format and installed Django in the virtual environment with the following procedure:

sudo python3 -m venv .venv
sudo source .venv/bin/activate
sudo python3 -m pip install django

Originally, the version should be displayed when sudo python3 -m django --version is executed, but No module named django is displayed.

How can I install packages for each virtual environment?

As a result of checking, it seems that it is installed in /usr/local/lib/python3.8/dist-packages/ even if (.venv) is displayed at the tip of the command line.

CodePudding user response:

As mentioned in the comments, sudo is problematic here. There are a few problems with using sudo with a venv in this case:

  • Typically, sudo python3 -m venv .venv would create the venv as root, but you mention that you are doing this on an NTFS-formatted USB drive. Because of the way that WSL accesses NTFS drives, all files on the NTFS drive will be owned by your default WSL user anyway, so sudo really has no effect here.

    If you were doing this on the ext4 filesystem that WSL provides, then the venv files would be owned by root. It's likely that this could then cause additional problems because of the VSCode issue described below.

  • VSCode, as well, always runs WSL as your default user. Really, WSL always runs VSCode (and any other Windows application) as your default user. Because of this, when inside VSCode, tools such as the Python extension will be accessing the venv as your default user, potentially leading to permissions issues if VSCode (or an extension) attempt to modify anything in it.

  • Then there's sudo source .venv/bin/activate, which should just be giving you an error, plain and simple.

    • sudo runs applications in Linux.
    • source is a Bash builtin, not an application itself.

    As a result, you should be receiving:

    sudo: source: command not found
    

    ... when attempting that. I'm guessing you are skipping sudo on that command to work around it, but forgot to leave it off in the question?

  • Finally, the biggest problem here is that venv works by modifying the environment of the current shell when you activate. This is why source is required. One of the key environment variables that is modified, of course, is the PATH, so that when you call python3 or pip3, it uses the one from the virtual environment.

    However, for security reasons, sudo does not, by default, allow the PATH to be propagated to the environment running inside it. You can run sudo -Es to run a shell with the other environment variables propagated, but the PATH will still be the default for root. Changing this is possible, via visudo, but not recommended for security reasons.

    This is the primary reason that your packages are being installed in the global/system environment, rather than in your virtual environment.

All-in-all, using sudo here is not going to be a good plan. Use your default user for the venv, VSCode, and WSL and things should work (more) as expected.

  • Side-issue: You don't mention WSL2, but it's the default for most installations. Under WSL2, even python3 -venv .venv is going to be very slow on an NTFS drive for the reasons I mention in this answer. It's highly recommended, if possible, to either keep your project on WSL2's ext4 filesystem. If you are using WSL1, then this does not apply.
  • Related