首页 > 解决方案 > 如何从外部 src 子目录添加 package_data 以便实际安装它们?

问题描述

我知道已经有类似的问题,但那里提供的答案对我的情况没有帮助。我相信从那时起情况已经发生了变化,引入了 .whl 文件并将其设为默认值等。

点子 21.2.4
蟒蛇 3.9.5

情况是这样的。我有一个 python 项目,我正在为其生成已发布的包。该项目不会上传到公共存储库,因为它是用于在我的工作地点控制自定义设备的库。

在发布的包中,我不仅要包含 .py 文件,还要包含其他文件,例如配置文件的模板、使用示例、其他文档。等等

让我们关注模板,因为其余部分是类比的。

我当前的项目结构(名称已更改):

deviceFFS
+-dist
| \-generated release packages...
+-src
| \-deviceffs
|   +-__init__.py
|   \-other .py files...
+-template
| +-template_A.ini
| \-template_B.ini
+-tests
| \-some tests...
+-venv
| \-...
+-LICENSE
+-MANIFEST.in
+-pyproject.toml
+-README.md
+-requirements.txt
+-setup.cfg
\-setup.py

在我尝试添加其他文件之前配置文件的内容:
setup.cfg:

[metadata]
name = deviceffs
version = 0.1.2
author = B
author_email = B
description = device for my job

[options]
python_requires= >=3.9
install_requires=
        configparser
        pyserial
package_dir=
        =src
packages=find:

[options.packages.find]
where=src

设置.py:

from setuptools import setup

setup()

pyproject.toml:

[build-system]
requires = [
        "setuptools",
        "wheel"
]
build-backend = "setuptools.build_meta"

好的,现在我要添加模板文件:
template/template_A.ini
template/template_B.ini

第一种方法:

我编辑了 MANIFEST.in:

include template/*

并添加到 setup.cfg:

include_package_data=true

完成此操作后,生成的 ( python -m build) .tar.gz 文件确实包含“模板”子目录。不知道 .hwl 文件,因为我不知道如何预览这些文件。但是,如果我在自定义项目(使用 venv)中安装这个包,python -m pip install -vvv我发现无论我是从 .tar.gz 还是从 .whl 安装,这些文件都没有安装在任何地方。我-vvv用来查看 pip 完成的每个文件复制操作,以查看它是否已安装。

第二种方法:

而不是 MANIFEST.in 使用 package_data。我恢复以前方法的更改,而是编辑 setup.py:

setup(package_data={"deviceffs": ["template/*"]})

不幸的是,这样我就可以从 '.\src\deviceffs\template' 而不是来自 '.\template' 的文件,因为路径是相对的。

而且我不想将模板(以及将来的使用示例、其他描述)放到 .\src 中,也不想将它们单独分发到包中。

第三种方法:

而不是 'package_data' 使用 'data_files'

这是一个过去似乎可行的解决方案。但是现在 pip 默认使用 .whl(即使从 .tar.gz 安装),这似乎完全忽略了“data_files”。

最后:

我没主意了。
我今天大部分时间都在努力让生成的版本包含我的文件,而不是实际处理文件的实际内容。

来自互联网的信息相互矛盾。
我正在寻找如何正确配置它的建议。
提前致谢。

编辑添加 python 和 pip 版本。

标签: pythonpython-packaging

解决方案


看起来你需要使用package_dir. 我不太确定您所针对的结果包树结构,所以我会猜测一下。

如果我假设您希望将模板文件放在一个包deviceffs.template中,那么很明显setuptools find_packages函数找不到该deviceffs.templates包,因为没有src/devicesffs/template目录。所以我们不能完全依赖find_packages,需要在运行时修改packages列表setup.py

[我的头顶,未经测试]

setup.py

#!/usr/bin/env python"
import setuptools
setuptools.setup(
    packages=setuptools.find_packages() + ['deviceffs.template'],
    package_dir={
        'deviceffs': 'src/deviceffs',
        'deviceffs.template': 'template',
    },
    # The rest is in 'setup.cfg'
)

类似的东西。您可能还需要添加一个template/__init__.py文件。


推荐阅读