【问题标题】:Python setuptools/pip packing data files into your packagePython setuptools/pip 将数据文件打包到你的包中
【发布时间】:2020-07-28 09:34:30
【问题描述】:

我有这个 git repo 结构:

.gitignore
JSONs/subdirA/some.json
JSONs/subdirB/other.json
MyPackage/__init__.py
MyPackage/myModule.py

如何正确地将JSONs文件夹打包到MyPackage/JSONs中,而不是将其永久移动到那里(主要是因为客户直接将此git repo用于非python使用,并且repo顶部的文件夹很容易/直观...但是现在我也想将相同的目录发布到我的 PyPi 包中)?

我尝试将其添加到MANIFEST.in,然后在setup.pypackage_data 中使用data_files...但无济于事。也许一些 .pyc 或缓存的构建文件对我来说是最好的......但我还没有从所有其他(不完全)重复的问题中弄清楚,因为它们没有专门调出它们的目录结构和所需的最终位置。

我尝试在调用setup 之前使用os.walkshutil.copy,然后在setup 之后删除该目录...虽然它似乎在本地工作,但在推送到我们的本地devpi 包服务器时,出了点问题。我的目标完全脱离了 setuptools/pip 理想的雷达吗???还是我只是缺少一些关键的理解?请赐教!

【问题讨论】:

  • 为什么不简单地使用符号链接使其看起来像 JSONs 目录在 MyPackage 内?然后剩下的就很标准了(here for example)。不要使用data_files,使用MANIFEST.inpackage_data
  • 可以将符号链接提交给 GIT 吗?以跨平台方式(python 包主要适用于 Windows,但使用 JSON 的 C 代码适用于 linux)
  • 我猜是的。但除此之外,您可以使用setuptoolspackage_dir 重写JSONs 目录的路径。类似于package_dir = {'MyPackage.JSONs': 'JSONs'},假设您的setup.py.gitignore(根目录)位于同一目录中。 -- docs.python.org/3/distutils/…
  • 谢谢,我现在就试试package_dir。您之前链接的页面令人困惑的是,数据文件已经在包中,而在我的情况下它们不是。所以我之前的尝试是将JSONs 文件夹留在sys.prefixsite-packages,具体取决于我的尝试。
  • 是的,这就是 package_dir 的全部意义所在,它会在构建时将 ./JSONs 转换为 MyPackage/JSONs,即在 wheel 中它具有新路径,但在 sdist 中它仍然具有旧结构。

标签: python pip setuptools


【解决方案1】:

以下内容可能会有所帮助:

首先,我们需要确保将 json 文件添加到 源分发

MANIFEST.in:

recursive-include JSONs *.json

然后在实际的 setup 脚本中,必须动态修改 列表以考虑目标包结构。

setup.py:

#!/usr/bin/env python3

import setuptools

PACKAGES = (
    setuptools.find_packages(exclude=['JSONs*'])
    +
    [
        f'MyPackage.{package}'
        for package
        in setuptools.find_namespace_packages(include=['JSONs*'])
    ]
)

setuptools.setup(
    packages=PACKAGES,
    package_dir={
        'MyPackage.JSONs': 'JSONs',
    },
    include_package_data=True,
    #
    name='Something',
    version='1.2.3',
)

JSONs/subdirA/some.json :

{"Marco": "Polo"}

这样的包数据可以这样读取:

MyPackage/myModule.py:

import pkgutil

print(pkgutil.get_data('MyPackage', 'JSONs/subdirA/some.json').decode())

并像下面这样使用它:

$ python -m pip install .
$ # Move to another directory to prevent that the current working directory
$ # ... overshadows the installed project
$ cd ..
$ python -m MyPackage.myModule
{"Marco": "Polo"}

【讨论】:

  • 非常感谢!这有效,无需添加任何 __init__.py 文件
  • 很高兴它能帮助您解决问题。确实,我们不需要添加__init__.py 文件,这让我有点吃惊,但是无论如何...我不太喜欢我们必须设置include_package_data = True,但是-再一次- 无论如何...工作。
猜你喜欢
  • 1970-01-01
  • 2021-01-15
  • 2019-05-31
  • 2012-08-04
  • 2012-01-23
  • 2018-11-30
  • 2011-05-29
相关资源
最近更新 更多