如何为某个环境禁用 `site.ENABLE_USER_SITE`?
来自文档的内容:
site.ENABLE_USER_SITE
这是一个标志,用来显示用户的包目录的状态。
True
表示这个目录是启用的,并且已经被添加到sys.path
中。False
表示用户请求禁用了这个目录(通过使用-s
或PYTHONNOUSERSITE
)。如果是None,说明因为安全原因(用户或组的身份和有效身份不匹配)或者管理员的原因,这个目录被禁用了。
我特别关注“或者由管理员”这句话。在我作为管理员的机器上(也就是我自己的机器),我该如何全局禁用这个选项,针对特定的解释器可执行文件呢?
我想这么做的原因是新的conda环境默认是启用这个选项的:https://github.com/conda/conda/issues/448
4 个回答
注意:这是反向操作,目的是在创建一个特定的虚拟环境后,重新启用全局站点包,因为我忘记这么做了。
这可能不是问题所问的确切内容,但这是我在谷歌搜索如何重新开启时找到的最接近的答案。
不需要对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
则禁用它,正如这个问题所述。
我遇到过类似的问题,有用户不小心在 ~/.local/lib/python3.x/site-packages
目录下安装了包,使用的是 pip install --user <package>
,结果搞坏了他们的虚拟环境(venv)。
我找到三种方法可以忽略本地安装的包。
在启动解释器之前,设置环境变量
PYTHONNOUSERSITE=1
用 -s 标志 启动解释器,命令是
python -s ...
在
.../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
简单来说,你可以添加一个环境变量 PYTHONNOUSERSITE=1
(随便设置成什么值都可以)。
如果你想全局更改这个设置,可以把它加到 .bashrc
文件里,或者你使用的其他配置文件中。
对于 conda:
你可以为特定的环境指定一些变量,具体可以参考这个链接 查看链接。简单来说就是:
conda env config vars set PYTHONNOUSERSITE=1
然后重新激活你的环境。
这个变量的值完全是由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
的导入步骤就会被跳过。