如何在 Python 的 setup.py 中包含和安装本地依赖项?

Posted

技术标签:

【中文标题】如何在 Python 的 setup.py 中包含和安装本地依赖项?【英文标题】:How to include and install local dependencies in setup.py in Python? 【发布时间】:2016-06-10 15:31:52 【问题描述】:

我正在创建一个 setup.py 来分发我的应用程序。 该应用程序有许多可以通过 pip 安装的依赖项,它还有一些无法从 PyPI 安装的自定义依赖项。

所以,我创建了一个 custom_package_0.1.whl,它将包含在分发中,并且必须在 setup.pyinstall_requires 安装所有内容后作为依赖项安装。

想象以下应用结构:

my_app/
    win_deps/custom_package_0.1.whl
    my_app/
        __init__.py
        main.py
        setup.py
        setup.cfg

我该怎么做?

【问题讨论】:

我遇到了类似的问题,找到了满意的答案here 这种广为人知的语言不以一种非 hacky 的方式支持本地依赖是一种耻辱...... 【参考方案1】:

基于上面的@RunOrVeith 答案,这适用于使用相对路径的本地车轮文件。所以它可以在各种主机上安装第三方包。适用于 Windows 和 Unix。

setup(# ... other arguments
      install_requires=[
          f"my-lib @ file://localhost/os.getcwd()/libs/my_lib-xxx-none-any.whl"
      ]
)

【讨论】:

【参考方案2】:

有一种称为Direct references 的新技术(自版本 19.1 起)。 假装你的文件托管在本地主机上。

from setuptools import setup

path_to_my_project = "/home/user/projects/my_package"  # Do any sort of fancy resolving of the path here if you need to


setup(# ... other arguments
      install_requires=[f"my_package @ file://localhost/path_to_my_project#egg=my_package"]
      )

【讨论】:

这似乎不适用于 Python 3.10 和 setuptools 59。我收到错误消息 Couldn't find index page for <package>' (maybe misspelled?) 并指定了 localhostlocalbuilds release history 中没有任何内容表明这里发生了一些变化 是的,我认为这是 setuptools 中的问题,而不是 pip。我在这里绊倒了:***.com/questions/70650046/…【参考方案3】:

扩展 wiesiu_p 的答案,您可以通过链接到其源目录来安装依赖项,该目录有自己的setup.py

假设你有你的依赖my-dependency的源文件,并且my-dependency的根有它自己的setup.py。在您的应用程序的setup.py

setup(
  ...,
  install_requires=['other-dependency','my-dependency'],
  dependency_links=[
    # location to your my-dependency project directory
    ''.join(['file:\\', os.path.join(os.getcwd(), 'path', 'to', 'my-dependency#egg=my-dependency-1.0')])
  ]
)

现在,如果您使用应用程序的setup.py 运行python setup.py install,它将安装my-dependency

【讨论】:

我知道这条评论很旧,但我无法让它发挥作用。我尝试了files:\` as you have it and files://`,我认为这是正确的吗?做pip install --find-links=<dep_link> my_package 有效,但当我将其放入 setup.py 时无效 我已经为答案添加了一些说明。我希望它有所帮助。 请注意,如果本地依赖本身具有本地依赖,这可能会失败,因为可能会从站点包调用 getcwd()。 这对我不起作用:当我执行pip install -e . 时,它会说ERROR: No matching distribution found for my-dependency。即使我这样做python setup.py install,我也会收到错误error: Could not find suitable distribution for Requirement.parse('my-dependency')。我正在使用 pip 20.3.3。 查看我的答案,了解如何让它与较新的 pip 版本一起使用【参考方案4】:

有可能,但不确定您应该使用哪个 setuptools 版本。 步骤:

在 setup.py 中

setup(
  ...,
  install_requires=['my-package'],
  dependency_links=[
    # location to your egg file
    os.path.join(os.getcwd(), 'deps', 'my_package-1.0.0-py3.5.egg')
  ]
)

重要的是您的位置不应通过 URL 模式测试,并且 egg 文件名应具有结构 <package_name_with_no_hyphens>-<version>-<py_version>.egg

【讨论】:

如果您还没有安装my-package,这似乎不起作用,因为在您安装之前没有.egg,对吧? @medley56 我认为您不需要使用 conda 或其他方式安装 my-package。我猜 setuptools 从本地位置读取它 dependency_links has been removed 这不适用于较新的 pip 版本,请滚动到我的答案以获取适用于 pip >= 19.1 的内容【参考方案5】:

有几个选项可供您选择:

    将您的包上传到某个服务器,并提供带有dependency_links 的URL。 您可以将您的 python 包放在您的 my_app 包中,并将其与 packages 参数链接,而不是使用轮文件。 更hacky的方法是使用setuptools api,然后自己安装包。

【讨论】:

对于2,我该怎么做?我将“win_deps”移动到“my_app”并添加了packages=(['win_deps']),但运行python2 setup.py install不会自动安装“win_deps”目录中的所有.whl 我在 2 中的意思是,您可以将整个包目录 custom_package_0.1 移动到此包目录中,而不是提供 whl 包。 哦,你的意思是把custom_package_0.1源文件移动到win_deps 完全正确。问题是 setup.py 没有任何可用的选项来安装 wheel 包。我能看到的唯一方法就是我建议你做的事情。其他方式比较老套,我不建议你这样做。 这是一个糟糕的公认答案。它没有关于解决方案的详细信息

以上是关于如何在 Python 的 setup.py 中包含和安装本地依赖项?的主要内容,如果未能解决你的问题,请参考以下文章

在 py2app 中包含 pymssql

如何在通过 pip 安装的应用程序中包含 django 模板?

如何列出 python 轮中的文件?

python setup.py - 如何在安装后显示消息

在 CMake 中使用 setup.py 构建 python 包

Python - 如何在字符串中包含任何随机整数