如何为某个环境禁用 `site.ENABLE_USER_SITE`?

12 投票
4 回答
11056 浏览
提问于 2025-04-18 23:54

来自文档的内容:

site.ENABLE_USER_SITE

这是一个标志,用来显示用户的包目录的状态。True表示这个目录是启用的,并且已经被添加到sys.path中。False表示用户请求禁用了这个目录(通过使用-sPYTHONNOUSERSITE)。如果是None,说明因为安全原因(用户或组的身份和有效身份不匹配)或者管理员的原因,这个目录被禁用了。

我特别关注“或者由管理员”这句话。在我作为管理员的机器上(也就是我自己的机器),我该如何全局禁用这个选项,针对特定的解释器可执行文件呢?

我想这么做的原因是新的conda环境默认是启用这个选项的:https://github.com/conda/conda/issues/448

4 个回答

0

注意:这是反向操作,目的是在创建一个特定的虚拟环境后,重新启用全局站点包,因为我忘记这么做了。

这可能不是问题所问的确切内容,但这是我在谷歌搜索如何重新开启时找到的最接近的答案。

不需要对site.py进行任何黑客操作。


我在Python 3.12中需要进行这个反向操作。我通常会根据工作需要构建我的开发环境,但依赖全局站点包来提供一些工具或代码检查所需的实用包。

(最佳实践?可能不是,但我已经习惯了)

在这种情况下,为了测试从3.11到3.12的过渡,我创建了一个虚拟环境,从项目的requirements.txt安装了依赖,结果发现我忘记加--system-site-package这个选项了。

总之……

tree是一个用来显示目录内容的工具。

tree testyessite/ -L 1

testyessite/
├── bin
├── include
├── lib
└── pyvenv.cfg

pyvenv.cfg中,我发现了这个有趣的标志:

include-system-site-packages = true

所以,基本上把include-system-site-packages设置为true可以启用全局包,设置为false则禁用它,正如这个问题所述。

1

我遇到过类似的问题,有用户不小心在 ~/.local/lib/python3.x/site-packages 目录下安装了包,使用的是 pip install --user <package>,结果搞坏了他们的虚拟环境(venv)。

我找到三种方法可以忽略本地安装的包。

  1. 在启动解释器之前,设置环境变量 PYTHONNOUSERSITE=1

  2. -s 标志 启动解释器,命令是 python -s ...

  3. .../lib/site.py 文件中,把 ENABLE_USER_SITE = None 改成 ENABLE_USER_SITE = False

源代码链接: 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

根据评论来看,我觉得这个是可以修改的。 sed -i 's/^ENABLE_USER_SITE = None/ENABLE_USER_SITE = False/g' .../lib/python${PYTHON_VERSION}/site.py

8

简单来说,你可以添加一个环境变量 PYTHONNOUSERSITE=1(随便设置成什么值都可以)。

如果你想全局更改这个设置,可以把它加到 .bashrc 文件里,或者你使用的其他配置文件中。

对于 conda:

你可以为特定的环境指定一些变量,具体可以参考这个链接 查看链接。简单来说就是:

conda env config vars set PYTHONNOUSERSITE=1

然后重新激活你的环境。

9

这个变量的值完全是由Python代码决定的:

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

第一个测试只是检查是否使用了-s开关或者PYTHONNOUSERSITE这个环境变量。

接下来是一些测试,如果当前的用户ID或组ID和进程的用户ID或组ID不一样,就会返回None

管理员可以设置有效的用户ID或组ID,这样的话,执行这个程序的用户就会变成这个程序的拥有者或组,而不是执行Python的用户,这时上面的函数会返回None

除此之外,一个sitecustomize.py包也可以把这个值重新设置为None,并且明确地把用户目录从路径中移除。如果这样做的话,usercustomize.py的导入步骤就会被跳过。

撰写回答