【问题标题】:How can setup.py reference other files in the source repo?setup.py 如何引用源代码库中的其他文件?
【发布时间】:2021-12-23 20:58:07
【问题描述】:

我无法使用python -m build . 构建python 包。 setup.py 失败:

FileNotFoundError: [Errno 2] No such file or directory: 'requirements/requirements.txt'

这是因为build首先将文件复制到临时目录。但它只是复制source/README.mdsetup.pysetup.cfg。不是抄袭requirements/


由于复杂的原因,我的 setup.py 需要引用源 repo 根目录下的其他文件 - 一个包含多个 requirements.txt 文件的目录。 真的不值得讨论为什么需要以这种方式构建,我已经与同事进行了长时间的辩论。

当我们通过 pip install -e . 或作为 git 依赖项 git+ssh://... 安装包时,这工作正常,但在我们推送到 pypi 存储库之前构建时失败。

setup.cfg
setup.py
source/
source/my_package/
requirements/
requirements/requirements.txt
requirements/some-other-requirements.txt

setup.py 在调用setup() 之前引用了这个目录。

from pathlib import Path
from setuptools import setup, find_namespace_packages


requirements_dir = Path("requirements")


# This is the line that fails:
with (requirements_dir / "requirements.txt").open() as f:
    install_requires = list(f)


setup(
    packages=find_namespace_packages(where="source", include=["acme_corp.*"], exclude=["tests", "tests.*"]),
    package_dir={"": "source"},
    install_requires=install_requires,
    extras_require=optional_packages,
)

【问题讨论】:

  • 那是this build 吗?
  • @2e0byo 这就是你输入pip3 install build时得到的任何东西,所以我猜是这样。
  • 你试过build with --no-isolation吗?
  • @MisterMiyagi 是的,这显然不会阻止复制行为。我怀疑它只控制创建一个新的虚拟环境以防止setup.py对其进行修改。

标签: python setuptools


【解决方案1】:

build 在这里做了正确的工作。在构建源 dist 之后,它会检查构建的结果是否可以实际安装。并且如果不将requirements 下的文件包含到源目录中,源目录将无法安装,因此无法使用。试试看:

$ python -m build --sdist  # builds fine, but the tar is broken:
$ cd dist
$ tar tf pkg-0.0.1.tar.gz | grep requirements  # will be empty
$ pip wheel pkg-0.0.1.tar.gz  # will fail
Processing ./pkg-0.0.1.tar.gz
  File was already downloaded 
  Preparing metadata (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command:
   ...
  Complete output (9 lines):
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "/tmp/pip-req-build-wfzz27_k/setup.py", line 9, in <module>
      with (requirements_dir / "requirements.txt").open() as f:
    File "/usr/lib64/python3.9/pathlib.py", line 1252, in open
      return io.open(self, mode, buffering, encoding, errors, newline,
    File "/usr/lib64/python3.9/pathlib.py", line 1120, in _opener
      return self._accessor.open(self, flags, mode)
  FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pip-req-build-wfzz27_k/requirements/requirements.txt'

要修复,请在源 dist 中包含 requirements 目录的 setup.py 旁边写一个 MANIFEST.in。示例文件内容:

graft requirements

现在应该可以构建源 dist 了;您还可以验证 sdist 现在是否包含要安装的所有文件:

$ tar tf dist/pkg-0.0.1.tar.gz | grep requirements
pkg-0.0.1/requirements/
pkg-0.0.1/requirements/requirements.txt
...

这仅涉及源 dist,因为轮子已经构建在主机(您的机器)上并且不再包含设置脚本。 Wheel building 也将忽略 MANIFEST.in 文件。

【讨论】:

  • 我想这只能由开发人员来回答 :-) 也许他们暗示通过 --sdist 意味着你知道你在做什么 - 毕竟,建造一个轮子可能很耗时而且你希望通过传递--sdist 来明确避免这种情况。或者答案可能只是 build 是一个相对较新的项目,所以检查尚未实施,谁知道呢。
  • 是的,我认为耗时的部分可能是问题所在。如果安装程序需要构建二进制文件,那么如果不这样做,检查就没有意义。取决于可能需要大量开销的项目(熊猫、密码学)。
猜你喜欢
  • 2016-09-19
  • 2021-04-19
  • 2020-07-14
  • 2017-07-02
  • 1970-01-01
  • 2010-10-09
  • 2023-01-25
  • 1970-01-01
  • 2020-03-04
相关资源
最近更新 更多