1

I'm trying to prevent users from using pip to install packages in their home directories.

The output from python3 -m site --help would indicate that it is possible for a super user to disable the user site directory. But how is this done? I've tried setting site.ENABLE_USER_SITE from a sitecustomize.py but that doesn't help. Setting PYTHONNOUSERSITE=1 in the environment or passing -s to python works but is not exactly a superuser tweak.

I've also tried to approach this by somehow disabling pip for users. We'd be quite happy for packages to be installed into venv environments but not user home directories. Is there anything I can put in pip.conf to forcibly disable --user installs.

1

Q: Is there anything I can put in pip.conf to forcibly disable --user installs.

A: No. The config file can always be overridden according the the precedence defined in the pip docs:

Command line options have precedence over environment variables, which have precedence over the config file.

Q: It is possible for a super user to disable the user site directory. But how is this done? Setting PYTHONNOUSERSITE=1 in the environment or passing -s to python works but is not exactly a superuser tweak.

A: I came to this question through Google because I was finding the exact opposite - I do not see PYTHONNOUSERSITE actually changing the behaviour of pip:

$ docker run --net=host -it python:3.8 bash

$ pip install -U pip
Requirement already up-to-date: pip in /usr/local/lib/python3.8/site-packages (20.2.2)

$ ls -ltr ~/.local
ls: cannot access '/root/.local': No such file or directory

$ PYTHONNOUSERSITE=1 pip install --user typing-extensions
Collecting typing-extensions
  Downloading typing_extensions-3.7.4.3-py3-none-any.whl (22 kB)
Installing collected packages: typing-extensions
Successfully installed typing-extensions-3.7.4.3

$ ls -ltr ~/.local
total 4
drwxr-xr-x 3 root root 4096 Aug 24 07:08 lib

The docs for PYTHONNOUSERSITE state that:

If this is set, Python won’t add the user site-packages directory to sys.path.

So even though I was surprised by the behaviour, I suppose it is reasonable for pip to still install to PYTHONUSERBASE even if this variable is set (even though the resulting installed package won't be available on the Python path).

I found a relevant issue on the pip issue tracker and it looks like there is already a special case for venvs which have system site packages disabled (the default) not being allowed to do user installs (I didn't explicitly check this).

So following through to the solution to that original bug report we arrive at a pull request which has some interesting features. Namely, there is apparently a special file that a super-user can create, ````, which disables the user site-package installation. I also found a question on SO relating to this. So I tried this, but unfortunately it still continued to install into the user base:

$ touch /usr/local/lib/python3.8/no-global-site-packages.txt

$ pip install --user typing-extensions
...
Successfully installed typing-extensions-3.7.4.3

Of course, this makes sense when we read the actual pull request implementation which only checks for this file under virtualenv situations. In my case, I want to be able to always disable this behaviour, so I'll dig a little deeper into the pip codebase...

It turns out that the key function is decide_user_site, which does honour the site.ENABLE_USER_SITE value, but only after it has checked for the explicit user argument. As we can see in the function itself this is asymmetric with how virtual environments are handled, which will prevent global/user installs if a virtual environment has disabled them. I consider this to be a bug, and I've raised it in https://github.com/pypa/pip/issues/8794.

So the answer is: It isn't currently possible, as far as I can tell, to disable --user installs in a base (i.e. non-virtual) environment. When it is possible to do so (hopefully when the issue linked above is fixed) the -s and PYTHONNOUSERSITE=1 environment variables can be used, but the "sys-admin" way of doing this that I think you are looking for is to modify site.py directly, as explained in the site.py implementation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.