virtualenv可重定位 - 它真的有用吗?

时间:2011-08-22 20:20:02

标签: python virtualenv virtualenvwrapper

我一直在寻找答案,但没有找到答案。 我有一个虚拟的环境目录,一个带有req.txt的项目目录。 当我运行pip -r req.txt时,它会安装一些来自github(源代码)的应用程序和一些来自pypi的应用程序。 来自pypi的那些在虚拟evn上的可重新定位调用之后很好,但是从github安装的应用程序的站点包中的链接仍然指向旧的目录位置。

其他人有过这种行为吗?有什么快速的方法吗? 此外,relocatable不支持最初在virtualenv上使用的--no-site-packages标志。移动虚拟并重新激活后,系统的站点包中都可以看到所有内容。文档表明这种行为是一个事实,所以我想知道是否有任何快速的解决方法?

2 个答案:

答案 0 :(得分:13)

the documentation --relocatable中所述,这是一个实验性选项,因此您遇到困难并不奇怪。也就是说,您是否记得在安装新软件包后重新运行--relocatable?如果您使用-e从github安装了软件包,这可能是一个问题,因为它不会安装到site-packages中,而是安装在其中的符号链接。作为使用--relocatable的替代方法,您通常可以删除特定于virtualenv的文件并在适当的位置重新创建它(我在平台之间切换时已经做​​了几次)。

答案 1 :(得分:11)

不,对于一个'--relocatable'不会更新'virtualenv / bin / activate'脚本。是的,您可以通过重新运行虚拟环境设置来解决这个问题,因为zeekay建议,但是仍然无法导入任何'pip -e git ...'安装,这些安装位于'virtualenv / src'中,因此您将不得不重新运行那些pip手动安装。

由于我已经获得了开发人员的经验,我现在避免使用额外的依赖和抽象层,这些层次只是一种失败的倾向。

所以现在我不用pip editable(-e)安装,如果需要手动将存储库克隆到'project / src /'而不是'project / virtualenv / src',并使用下面的auto_prep_pythonpath.py脚本在启动我的项目之前加载(我在我的django.wsgi脚本中引用它)。

作为旁注,我将“量身定制”添加到“project / src”中被修改/黑客攻击的任何包中,这样我就不必担心向后兼容性了,我在代码控制下跟踪所有源代码作为在线存储库可以并且将会制造你。

希望这有帮助。

"""
Prepares python path to include additional project/src/<APP> in PYTHONPATH - This file gets automatically loaded by projects __init__.py

This script lives in 'project/src/django-project/auto_prep_pythonpath.py', modify 
'SOURCE_ROOT' if you place it somewhere else.
"""
import logging
import os
import sys
SOURCE_ROOT = os.path.dirname(os.path.abspath(__file__)).replace('\\','/') # the replacements are when on windows
SOURCE_ROOT = os.path.join(SOURCE_ROOT, '../').replace('\\','/') 
SOURCE_ROOT = os.path.normpath(SOURCE_ROOT)

logger = logging.getLogger(__name__)

logger.info("Adding packages in 'src/*' required by project to PYTHONPATH.")
dirlist_arr = os.listdir(SOURCE_ROOT)
while dirlist_arr:
    item_path = os.path.join(SOURCE_ROOT, dirlist_arr.pop()).replace('\\','/') # replace dashes is for win based file system
    if os.path.isdir(item_path):
        if not item_path in sys.path:
            sys.path.insert(0, item_path) # we use insert to take precedence over any global paths - minimizes import conflict surprises
        logger.debug("Path '%s' added."  % item_path)