【问题标题】:Can I have my pip user-installed package be preferred over system?我可以让我的 pip 用户安装包优先于系统吗?
【发布时间】:2023-06-22 17:25:01
【问题描述】:

我想找出一个“万无一失”的安装说明放入 Python 项目的 README 中,命名为 footools,以便我们组中的其他人可以在他们的上安装最新的 SVN 版本笔记本电脑及其服务器帐户。

问题是当 Python 调用 pip 安装的脚本时,让用户安装的库被 Python 使用。例如,我们使用的服务器在/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ 中有旧版本的footools。

如果我执行python2.7 setup.py install --user 并运行主入口脚本,它将使用/Users/unhammer/Library/Python/2.7/lib/python/site-packages/ 中的文件。这是我想要的,但是 setup.py 单独不会安装依赖项。

如果我(恢复安装并)改为执行pip-2.7 install --user . 并运行主入口脚本,它会使用/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ 中的旧文件——这不是我想要的。

如果我(恢复安装并且)改为执行pip-2.7 install --user -e . 并运行主入口脚本,它会使用. 中的文件——这不是我想要的,用户应该能够删除源目录(并且能够在不影响其安装的情况下进行 svn。


我可以使用(并推荐其他人使用)python2.7 setup.py install --user——但他们必须先这样做

pip-2.7 install -U --user -r requirements.txt -e .
pip-2.7 uninstall -y footools

为了安装依赖项(因为 pip 没有install --only-deps 选项)。不过,这相当冗长。

setup.py 在做什么,而 pip 在这里没有做什么?

(经过编辑以明确说明我正在寻找更简单+更安全的安装说明。)

【问题讨论】:

  • 可以用 virtualenv 吗?
  • 能否提供您使用的 setuptools 和 pip 版本?另外,当您使用 setuptools 安装和使用 pip 安装时,入口脚本的外观如何?可以在每次安装后运行python -m sitepython -c "import os; print os.environ.get('PYTHONPATH')" 并报告结果吗?
  • Piotr,在github.com/pypa/pip/issues/536 上有一个关于它的大讨论——对于我自己的情况,我不再需要解决这个问题,但我建议任何人都去看看这个问题。
  • 您是说您的footools 与系统中已安装的版本相同吗?在您的问题中,您说 If I (revert the installation and) 而是执行 pip-2.7 install --user 。并运行主入口脚本 (...)。如果根据问题 536 您的命令 pip-2.7 install --user . 应该是空操作(如果您的版本与系统版本相同),那么您如何能够运行 main entry script 所以不应该有任何控制台脚本安装在用户安装方案的bin目录中?
  • 如果我没记错的话,问题是已经安装的包的版本号与 SVN 中的相同,所以 pip 没有覆盖。通过“恢复安装”,我想我指的是 ~/.local/site-python-whatever-it's-所谓的库,而不是 ~/bin 加载器。

标签: python pip setup.py sys.path


【解决方案1】:

安装virtualenvwrapper。我允许设置单独的 python 环境来缓解您可能遇到的任何冲突。 Here is a tutorial 用于安装和使用 virtualenv。

相关:

【讨论】:

  • 所以……这对安装人员来说是更多的工作,而不是更少:-)我当然看到了它的优势,并且可以将它用于我自己的工作流程,但如果目标是让安装更简单其他人,那么我必须编写一个完整的 virtualenvwrapper-wrapper,这似乎不太值得。
  • @unhammer:我理解您的担忧,但这是目前最好的解决方案。安装virtualenvwrapper 非常容易,除非您在Windows 上,最好的选择可能是切换到带有此类工具的Python 3。 PIP 的主要问题是它更改了默认的 Python 安装,这可能会破坏其他代码。您的修复 - 安装在用户提供的位置 - 有助于但 Python 的 venv 工具也解决了您尚未遇到的其他问题。
【解决方案2】:

pip 在安装过程中生成的控制台脚本应使用用户安装的库版本,根据 PEP 370:

在系统站点目录之前添加用户站点目录 但是在 Python 的搜索路径和 PYTHONPATH 之后。 此设置允许 用户安装与系统不同版本的软件包 管理员,但它可以防止用户意外覆盖 标准库模块。 Stdlib 模块仍然可以被覆盖 PYTHONPATH。

旁注


Setuptools 通过在easy_install.pth 文件中插入代码来使用hack,该文件位于site-packages 目录中。此代码使使用 setuptools 安装的软件包位于 sys.path 中的其他软件包之前,因此它们隐藏其他具有相同名称的软件包。这在 table 比较 setuptools 和 pip 中称为 sys.path 修改。这就是当您使用setup.py install 而不是使用 pip 安装时控制台脚本使用用户安装的库的原因。


考虑到以上所有因素,您观察到的原因可能是:

  • PYTHONPATH 指向具有系统范围安装库的目录
  • 使用sudo python.py install (...) 安装系统范围的库
  • 操作系统以某种方式影响sys.path 构造

在第一种情况下,清除 PYTHONPATH 或将用户安装库的路径添加到 PYTHONPATH 的开头应该会有所帮助。
在第二种情况下,卸载系统范围的库并使用发行版包管理器安装它们可能会有所帮助(请注意,您永远不应将 sudo 与 pip 或 setup.py 一起使用来安装 Python 包)。
在第三种情况下,有必要了解操作系统如何影响sys.path 的构造,以及是否有某种方法可以将用户安装的库放在系统库之前。

您可能有兴趣阅读问题pip list reports wrong version of package installed both in system site and user site,我问的问题与您基本相同:

这是否意味着使用 easy_install 安装系统范围的 Python 包,从而让它们使用 sys.path 操作会破坏用户 bin 目录中的脚本?如果有,有什么解决办法吗?

最后的手段解决方案是在导入这些库之前,从您的脚本中手动将目录/目录与用户安装的库放在sys.path 的开头。

话虽如此,如果您的用户不需要直接访问源代码,我建议您使用 pexPlatter 之类的工具将您的应用与所有依赖项打包成独立的bundle

【讨论】:

    最近更新 更多