如何在setuptools/distutils中包含软件包数据?

9 浏览
0 Comments

如何在setuptools/distutils中包含软件包数据?

在使用setuptools时,我无法使安装程序引入任何package_data文件。我阅读的所有内容都说以下方法是正确的。请问有人可以提供建议吗?

setup(
   name='myapp',
   packages=find_packages(),
   package_data={
      'myapp': ['data/*.txt'],
   },
   include_package_data=True,
   zip_safe=False,
   install_requires=['distribute'],
)

其中myapp/data/是数据文件的位置。

0
0 Comments

如何在setuptools/distutils中包含软件包数据?

在使用Google进行搜索时,我意识到这是一个旧问题,但对于通过Google找到这里的人来说:package_data是一个下等的、肮脏的谎言。它仅在构建二进制包(python setup.py bdist ...)时使用,而不在构建源代码包(python setup.py sdist ...)时使用。这当然是荒谬的——人们期望构建源代码分发将会产生一系列文件,这些文件可以发送给其他人构建二进制分发。

无论如何,使用MANIFEST.in对于二进制和源代码发行版都有效。

我已经研究了这个问题一个小时,并尝试了很多方法。正如你所说,package_data适用于bdist而不适用于sdist。然而,MANIFEST.in适用于sdist,但不适用于bdist!因此,我能想出的最好的办法是同时包含package_data和MANIFEST.in以适应bdist和sdist。

我在stackoverflow上找到了另一个支持意见。在stackoverflow.com/a/2969087/261718中,使用MANIFEST.in用于不需要安装的文件,比如文档,而使用package_data用于在Python代码之外使用的文件(比如图像或模板)。

今天遇到了这个问题。我明白他们可能不想改变行为,但至少应该在文档中提到。

我正在使用sdist,并且必须同时包含MANIFEST.in和package_data。看起来MANIFEST.in控制了在分发中包含的内容,而package_data控制了在安装过程中复制到site_packages目录中的内容。令人困惑的是,MANIFEST.in中的路径是相对于setup.py的位置,而package_data是相对于各个包(例如模块)的根目录。

“从2.7版本开始更改:如果没有提供模板,所有与package_data匹配的文件将添加到MANIFEST文件中。请参阅指定要分发的文件。”来自distutils。因此,只有当您没有现有的MANIFEST.in文件,并且仅使用2.7+版本时,您才会看到package_data中的文件自动包含在ZIP文件中的行为。

使用setuptools可以安全地使用package_data:setuptools.readthedocs.io/en/latest/….文件将有效地包含在二进制和源代码分发中,并且可以方便地使用同一页面上描述的ResourceManager API进行访问。另请参阅stackoverflow.com/a/14211600/4716370。

说真的,我觉得这个问题是一个小组治疗会议,为那些使用setuptools并发现自己陷入可怕境地的人提供帮助。

感谢您提供这个。对于其他任何因缺少软件包数据文件而来到这里的人:如果您通过远程git存储库进行分发,请确保您的数据文件包含在git中。我的数据文件被忽略了,所以它不在远程存储库中;与setuptools或清单无关。

使用Python 3.6,如果我只运行python setup.py install,package_data对我仍然无效。添加MANIFEST.in解决了我的问题...

我发现有时对MANIFEST.in的更改不会生效,除非我删除egg-info文件夹。这些东西真是太令人困惑了!

我正在使用MANIFEST.in文件和include_package_data=True选项来构建sdist。只有当我运行python setup.py install_lib时,额外的文件才会出现在我的目标环境中,如此处所述

我在Python 3.6中看到的行为是:MANIFEST.in指定了要包含在源代码分发中的文件(sdist)。setup.py install自动将sdist的Python文件添加到site-packages。但是,include_package_data标志控制非Python文件在sdist中的分发,并且存在于可安装的Python包(具有__init__.py的目录)中的位置。因此,为了使非Python文件与您的代码一起安装,它们需要a)在sdist中(由MANIFEST.in控制);b)存在于可安装的Python包中。否则,您需要使用data_files。

还有一个观点认为,最好使用setuptools_scm而不是MANIFEST.in文件。

Python 3.8、setuptools 49.2.0使用[options.package_data]仅用于bdist。我发现缺失的是path/to/data/*需要相对于包的根目录。而不是src/package/path/to/data/*,也不是package/path/to/data/*。文件将自动添加到pip install .中,但如果我想删除它们(注释掉[options.package_data]而不是显式拒绝),我需要删除build和package.egg-info文件。当正确添加文件时,package.egg-info/SOURCES.txt会显示这些文件。不创建MANIFEST.in,不创建__init__.py,但两者都有效。

这个旧的但受欢迎的答案应该更新,因为“无论如何,使用MANIFEST.in将适用于二进制和源代码分发。”这是不正确的。正如Baugh在他的流行评论中所述,需要同时使用这两种方式才能获得sdist和bdist。

0
0 Comments

问题的出现原因是由于使用了include_package_data=True,但该选项的作用是包含来自版本控制的文件,而不是仅仅“包含软件包数据”。

解决方法是移除include_package_data=True,并在Manifest文件中添加相应的条目。

解决方法的具体原因在于,原文中指出,如果使用setuptools特定的include_package_data参数,则package_data指定的文件将不会自动添加到清单中,除非它们在MANIFEST.in文件中列出。

至于在package_data设置为非空列表并指定include_package_data=False的用例以及为什么需要在MANIFEST.inpackage_data中指定文件两次的原因,目前没有明确的解释。

0
0 Comments

问题的原因是在setup.py文件中使用了include_package_data=True,导致package_data无法正常工作。解决方法是将include_package_data=True注释掉。

以下是解决方法的具体实现:

from setuptools import setup, find_packages
import os.path
setup (
    name='myproject',
    version = "4.19",
    packages = find_packages(),
    package_data = {
        '': ['*.txt', '*.xml', '*.special', '*.huh'],
    },
    data_files=[
        ('/opt/local/myproject/etc', ['myproject/config/settings.py', 'myproject/config/other_settings.special']),
        ('/opt/local/myproject/etc', [os.path.join('myproject/config', 'cool.huh')]),
        ('/opt/local/myproject/etc', [os.path.join('myproject/config', 'other_settings.xml')]),
        ('/opt/local/myproject/data', [os.path.join('myproject/words', 'word_set.txt')]),
    ],
    install_requires=[ 'jsonschema', 'logging', ],
    entry_points = {
        'console_scripts': [
            # Blah...
        ],
    },
)

然后运行`python setup.py sdist`生成源代码分发包。在新的虚拟环境中运行`pip install ~/myproject-4.19.tar.gz`安装包,并将特定的数据文件安装到/opt/local/myproject/data和/opt/local/myproject/etc目录下。

0