【问题标题】:How to determine where pip3 installs binaries/scripts for non-user installs? [duplicate]如何确定 pip3 为非用户安装安装二进制文件/脚本的位置? [复制]
【发布时间】:2020-10-03 11:11:59
【问题描述】:

我可以使用pip3 install --user mypackage 确定 pip 在何处安装软件包二进制文件/脚本:

$(python3 -m site --user-base)/bin

是否有确定安装非用户二进制文件/脚本(例如pip3 install mypackage)的位置的机制?

请注意,我只对二进制文件/脚本的安装位置感兴趣,而不是库代码的安装位置。

更新:

目标是确保 PATH 环境变量包含安装二进制文件/脚本的文件夹,因为这在过去给我造成了一些问题。

更新 2:

$ python3 -c "import sysconfig; print(sysconfig.get_path('scripts'))"
/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/bin

$ python3 -c "from pip._internal.locations import bin_py; print(bin_py)"
/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/bin

但是,pip3 安装到 /usr/local/bin

注意:

$ which pip3
/usr/local/bin/pip3
$ which python3
/usr/local/bin/python3

【问题讨论】:

  • 导入我的包; mypackage.__ 文件__
  • 谢谢@sergey。我已经更新了问题,以澄清这种方法可能不适合我。
  • 这对我来说是令人惊讶的行为。我不熟悉mac和自制软件。 -- 你确定pip3 脚本对应于python3 二进制文件吗?当您调用python3 -m pip install Something 时,二进制文件/脚本安装在哪里? -- snarky.ca/why-you-should-use-python-m-pip
  • 您可能还想检查python3 -m sitepython3 -m sysconfig 的输出?

标签: python-3.x pip


【解决方案1】:

这已经在这里得到了回答(但我不能“关闭为重复”,因为有赏金):

https://stackoverflow.com/a/62167797


我相信规范的方式(向前)是使用sysconfig.get_path(...)。根据具体需要,可以结合 schemename。因此,也许对于您的确切用例:

import sysconfig

scripts_path = sysconfig.get_path('scripts')
print(scripts_path)

作为 单线 来自 shell:

python -c "import sysconfig; print(sysconfig.get_path('scripts'))"

可能有助于识别正确目录的其他事项:

python -m site
python -m sysconfig

参考文献

【讨论】:

    【解决方案2】:

    pip的来源

    pip_internal/locations.py 的源代码显示了如何解析系统 bin 路径: https://github.com/pypa/pip/blob/3fe826c699d85eccc7ebf16f4d86c851b2a1e705/src/pip/_internal/locations.py#L63-L91

    if WINDOWS:
        bin_py = os.path.join(sys.prefix, 'Scripts')
        bin_user = os.path.join(user_site, 'Scripts')
        # buildout uses 'bin' on Windows too?
        if not os.path.exists(bin_py):
            bin_py = os.path.join(sys.prefix, 'bin')
            bin_user = os.path.join(user_site, 'bin')
    else:
        bin_py = os.path.join(sys.prefix, 'bin')
        bin_user = os.path.join(user_site, 'bin')
    
        # Forcing to use /usr/local/bin for standard macOS framework installs
        # Also log to ~/Library/Logs/ for use with the Console.app log viewer
        if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/':
            bin_py = '/usr/local/bin'
    

    有关sys.prefix 的一些其他文档可在此处获得:https://docs.python.org/3/library/sys.html#sys.prefix

    根据 Git 历史,这种解析行为自 2017 年以来一直没有被触及。试图追踪这个变量的使用似乎并不表明这个变量是通过命令直接使用pip 暴露的。


    解决方案

    由于这似乎没有直接在 CLI 中公开,因此您可以导入脚本以访问已解析的 bin 位置:

    python -c "from pip._internal.locations import bin_py; print(bin_py)"
    

    例如:

    • 在 Linux 上:

      $ python -c "from pip._internal.locations import bin_py; print(bin_py)"
      /usr/local/bin
      

      这似乎与安装脚本的位置相匹配,这些软件包具有脚本/bin。例如

      • 系统安装
      $ pip install uvicorn >/dev/null && which uvicorn
      /usr/local/bin/uvicorn
      
      • 用户安装
      $ pip install --user uvicorn >/dev/null && find "$(python3 -m site --user-base)/bin"
      /root/.local/bin
      /root/.local/bin/uvicorn
      
    • 在 Windows 上:

      $ python -c "from pip._internal.locations import bin_py; print(bin_py)"
      C:\Users\[REDACTED]\AppData\Local\Programs\Python\Python38\Scripts
      

    此方法也适用于查找虚拟环境的 bin 目录。

    【讨论】:

    • 依赖实现细节和内部API在未来容易失败。
    • @sinroc 您可以从 pip._internal.locations 复制相关代码并制作自己的脚本/库。
    • @pbacterio 为什么要从 pip 复制内部私有代码,而规范解决方案(向前推进)已经在标准库中?
    猜你喜欢
    • 2022-11-23
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 2013-08-12
    • 1970-01-01
    相关资源
    最近更新 更多