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.