12

From the docs:

site.ENABLE_USER_SITE

Flag showing the status of the user site-packages directory. True means that it is enabled and was added to sys.path. False means that it was disabled by user request (with -s or PYTHONNOUSERSITE). None means it was disabled for security reasons (mismatch between user or group id and effective id) or by an administrator.

I'm particularly interested in the phrase or by an administrator. On machines on which I'm an administrator (i.e. my own), how do I disable this option globally, for a specific interpreter executable?

The reason I want to do this is that new conda environments leave this enabled: https://github.com/conda/conda/issues/448

Community
  • 1
  • 1
ontologist
  • 595
  • 4
  • 20

3 Answers3

9

The value of that variable is determined entirely in Python code:

def check_enableusersite():
    """Check if user site directory is safe for inclusion

    The function tests for the command line flag (including environment var),
    process uid/gid equal to effective uid/gid.

    None: Disabled for security reasons
    False: Disabled by user (command line option)
    True: Safe and enabled
    """
    if sys.flags.no_user_site:
        return False

    if hasattr(os, "getuid") and hasattr(os, "geteuid"):
        # check process uid == effective uid
        if os.geteuid() != os.getuid():
            return None
    if hasattr(os, "getgid") and hasattr(os, "getegid"):
        # check process gid == effective gid
        if os.getegid() != os.getgid():
            return None

    return True

The first test is simply for the -s switch or the PYTHONNOUSERSITE environment variable having been used.

What remains is the tests that return None if the effective userid or groupid differ from the process userid or groupid.

An administrator can set the effective user id or group id bits, at which point the effective user of the executable is changed to the owner or group of the executable rather than the user executing Python, at which point the above function will return None.

Other than that, a sitecustomize.py package could set the value to None again, and explicitly remove user directories from the path again. If so, the usercustomize.py import step is skipped.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Yeah, I saw this. The docs seem to imply there's a another way: "None means it was disabled for security reasons (mismatch between user or group id and effective id) *or* by an administrator.". That implies there's another way besides changing the user/group id. – ontologist Aug 30 '14 at 16:30
  • @ontologist: the above implementation is what is actually going to happen. Since setting the effective user / group bits is an administrator action, I think that is what the documentation is (ineffectively) alluding to. – Martijn Pieters Aug 30 '14 at 16:31
  • Yes, that may be the case. Although, none of these solutions is very convenient. Environment variables are not interpreter-specific, always using a command-line flag is fragile, and changing the user/group id has other effects. – ontologist Aug 30 '14 at 16:32
  • Ah, saw your edit. That may be the only way to go. Annoying that just setting the value to `None` isn't enough, and you would have to explicitly edit `sys.path`. – ontologist Aug 30 '14 at 16:33
  • @ontologist: you'd check what `site.getusersitepackages()` returns and remove that path again. – Martijn Pieters Aug 30 '14 at 16:34
  • @MartijnPieters With the sitecustomize strategy to "fix" the environment do we potentially still need to worry that *.pth files in the user directory have already been executed? – Robert Feb 19 '20 at 14:57
  • @Robert: No. `.pth` files are processed in `addsitedir()`, which is [only called for the user directory if `ENABLE_USER_SITE` is true](https://github.com/python/cpython/blob/44c690112d96a81fe02433de7900a4f8f9457012/Lib/site.py#L315-L316). – Martijn Pieters Feb 19 '20 at 15:30
  • I am calling check_enableusersite() outright with a True value returned (because I did attempt by creating a user site) and yet ENABLE_USER_SITE is False. Working within venv in our current future seems now seems to affect ENABLE_USER_SITE above and beyond check_enableusersite()... – gkedge Sep 09 '20 at 12:47
  • A [really good SO reference on _customizing_ virtual environments](https://stackoverflow.com/a/54367842/2973538) thoroughly written up by [@pmav99](https://stackoverflow.com/users/592289/pmav99). – gkedge Sep 09 '20 at 13:03
7

Basically you can add the environment variable PYTHONNOUSERSITE=1 (just set it to something)

So if need to change it globally add this to the .bashrc or whatever you use.

for conda:

You can specify variables that will be set for the specific environment see link in short:

conda env config vars set PYTHONNOUSERSITE=1

and then reactivate your env

yayo
  • 71
  • 1
  • 1
1

Had a similar issues where user accidentally installed packages in ~/.local/lib/python3.x/site-packages with pip install --user <package> and that broke their venv.

Found 3 ways to ignore local packages.

  1. Set the environment variable PYTHONNOUSERSITE=1 before starting the interpreter

  2. Start the interpreter with the -s flag python -s ...

  3. Patch ENABLE_USER_SITE = None to ENABLE_USER_SITE = False in the .../lib/site.py

Source code: https://github.com/python/cpython/blob/main/Lib/site.py#L82

# Enable per user site-packages directory
# set it to False to disable the feature or True to force the feature
ENABLE_USER_SITE = None

Judging by the comment, I believe this is meant to be patchable. sed -i 's/^ENABLE_USER_SITE = None/ENABLE_USER_SITE = False/g' .../lib/python${PYTHON_VERSION}/site.py

user5994461
  • 5,301
  • 1
  • 36
  • 57