如何将其他文件添加到滚轮?

时间:2014-06-22 01:48:24

标签: python pip python-wheel

如何控制车轮中包含哪些文件? MANIFEST.in使用python setup.py bdist_wheel似乎没有使用。

更新

我从源tarball与wheel安装之间的区别是错误的。源代码分发包括MANIFEST.in中指定的文件,但安装的软件包只有python文件。需要步骤来识别应安装的其他文件,无论安装是通过源分发,egg还是wheel。也就是说,其他包文件需要package_data,而命令行脚本或系统配置文件等包外文件需要data_files

原始问题

我有a project我正在使用python setup.py sdist构建我的软件包,MANIFEST.in来控制包含和排除的文件,以及pyroma和{{ 3}}确认我的设置。

我最近将它转换为双Python 2/3代码,并添加了一个带有

的setup.cfg
[bdist_wheel]
universal = 1

我可以使用python setup.py bdist_wheel制作一个轮子,它看起来像是一个万向轮。但是,它不包含MANIFEST.in中指定的所有文件。

安装什么?

我挖得更深,现在对包装和滚轮了解得更多。这是我学到的东西:

我将两个包文件上传到check-manifest

  • multigtfs-0.4.2.tar.gz - 来源tar球,其中包含MANIFEST.in中的所有文件。
  • multigtfs-0.4.2-py2.py3-none-any.whl - 有问题的二进制分发。

我使用Python 2.7.5创建了两个新的虚拟环境,并安装了每个包(pip install multigtfs-0.4.2.tar.gz)。这两种环境几乎完全相同。它们有不同的.pyc文件,这些文件是"编译的#34; Python文件。有记录磁盘上不同路径的日志文件。源tar球的安装包括一个文件夹multigtfs-0.4.2-py27.egg-info,详细说明了安装,并且wheel安装有一个multigtfs-0.4.2.dist-info文件夹,其中包含该进程的详细信息。但是,从使用multigtfs项目的代码的角度来看,这两种安装方法没有区别。

显然,我的测试使用的.zip文件都没有,所以测试套件会失败:

$ django-admin startproject demo
$ cd demo
$ pip install psycopg2  # DB driver for PostGIS project
$ createdb demo         # Create PostgreSQL database
$ psql -d demo -c "CREATE EXTENSION postgis" # Make it a PostGIS database 
$ vi demo/settings.py   # Add multigtfs to INSTALLED_APPS,
                        # Update DATABASE to set ENGINE to django.contrib.gis.db.backends.postgis
                        # Update DATABASE to set NAME to test
$ ./manage.py test multigtfs.tests  # Run the tests
...
IOError: [Errno 2] No such file or directory: u'/Users/john/.virtualenvs/test/lib/python2.7/site-packages/multigtfs/tests/fixtures/test3.zip'

指定其他文件

使用答案中的建议,我向setup.py添加了一些其他指令:

from __future__ import unicode_literals
# setup.py now requires some funky binary strings
...
setup(
    name='multigtfs',
    packages=find_packages(),
    package_data={b'multigtfs': ['test/fixtures/*.zip']},
    include_package_data=True,
    ...
)

这会将zip文件(以及README)安装到该文件夹​​,现在测试可以正常运行。谢谢你的建议!

7 个答案:

答案 0 :(得分:28)

您是否尝试在package_data中使用setup.pyMANIFEST.in似乎针对python版本< = 2.6,我不确定更高版本是否会查看它。

在探索https://github.com/pypa/sampleproject后,他们的MANIFEST.in说:

# If using Python 2.6 or less, then have to include package data, even though
# it's already declared in setup.py
include sample/*.dat

这似乎意味着这种方法已经过时了。同时,他们在setup.py声明:

setup(
    name='sample',
    ...
    # If there are data files included in your packages that need to be
    # installed, specify them here.  If using Python 2.6 or less, then these
    # have to be included in MANIFEST.in as well.
    package_data={
        'sample': ['package_data.dat'],
    },
    ...
)

(我不确定他们为什么选择MANIFEST.in中的通配符和setup.py中的文件名。他们引用相同的文件)

同样,更简单,似乎再次暗示package_data路线优于MANIFEST.in方法。好吧,除非你必须支持2.6,在这种情况下,我的祈祷会发给你。

答案 1 :(得分:13)

MANIFEST.insetup.py中进行任何更改之前,您必须删除旧的输出目录。 Setuptools正在缓存一些数据,这可能会导致意外结果。

rm -rf build *.egg-info

如果您不这样做,则无法正常工作。

现在已经不在了。

  1. 如果您正在制作来源分发sdist),那么您可以使用以下任何方法。

  2. 如果您正在构建bdist_wheel),则会忽略include_package_dataMANIFEST.in,您必须使用package_datadata_files

  3. INCLUDE_PACKAGE_DATA

    这是一个不错的选择,但bdist_wheel不尊重它。

    setup(
        ...
        include_package_data=True
    )
    
    # MANIFEST.in
    include package/data.json
    

    非包裹数据的DATA_FILES

    这是最灵活的选项,因为您可以将回购邮件中的任何文件添加到sdistbdist_wheel

    setup(
        ....
        data_files=[
            ('output_dir',['conf/data.json']),
        ]
        # For sdist, output_dir is ignored!
        #
        # For bdist_wheel, data.json from conf dir in root of your repo 
        # and stored at `output_dir/` inside of the sdist package.
    )
    

    包内的非python文件的PACKAGE_DATA

    与上面类似,但对于bdist_wheel,您可以将数据文件放在包中。它与sdist完全相同,但比data_files有更多限制,因为文件只能来自您的包子目录。

    setup(
        ...
        package_data={'package':'data.json'},
        # data.json must be inside of your actual package
    )
    

答案 2 :(得分:11)

您可以使用envoyer-root/storage中的package_datadata_files来指定其他文件,但这些文件是ridiculously hard to get right (and buggy)

另一种方法是使用setup.py并在MANIFEST.in的{​​{1}}中添加include_package_data=True作为indicated here

使用此指令,setup()将用于指定不仅包含在源tarball / zip中,还包含在wheel和win32安装程序中的文件。这也适用于任何python版本(我在从py2.6到py3.6的项目上测试过。)

答案 3 :(得分:10)

您可以使用data_files指令指定要安装的额外文件。那是你在找什么?这是一个小例子:

from setuptools import setup
from glob import glob

setup(
    name='extra',
    version='0.0.1',
    py_modules=['extra'],
    data_files=[
        ('images', glob('assets/*.png')),
    ],
)

答案 4 :(得分:1)

include_package_data是必经之路,它适用于sdist 和滚轮

但是您必须正确地做,这花了我几个月的时间才弄清楚,所以这就是我学到的东西。

该技巧实际上是通过选项include_PACKAGE_data的名称给出的:数据文件必须位于程序包的子文件夹中

当且仅当

  • include_package_data是True
  • 数据文件列在MANIFEST.in中(*另请参阅关于setuptools_scm的结尾处的注释)
  • 并且数据文件在软件包目录下

然后将包含数据文件。

工作示例:

鉴于该项目具有以下结构和文件:

|- MANIFEST.in
|- setup.cfg
|- setup.py
|
\---foo
    |- __init__.py
    |
    \---data
         - example.png

以及以下配置:

Manifest.in:

recursive-include foo/data *

setup.py

import setuptools

setuptools.setup()

setup.cfg

[metadata]
name = wheel-data-files-example
url = www.example.com
maintainer = None
maintainer_email = none@example.com

[options]
packages =
    foo
include_package_data = True

sdist包和构建的轮子也将包含example.png数据文件。

(当然,也可以在setup.py中直接指定配置而不是setup.cfg。但这与示例无关。)

更新:用于src布局项目

这也应适用于使用src布局的项目,如下所示:

|- MANIFEST.in
|- setup.cfg
|- setup.py
|
\---src
    |
    \---foo
        |- __init__.py
        |
        \---data
             - example.png

要使其正常运行,请使用package_dir向setuptools告知src目录:

setup.cfg

[metadata]
name = wheel-data-files-example
url = www.example.com
maintainer = None
maintainer_email = none@example.com

[options]
packages =
    foo
include_package_data = True
package_dir =
    =src

然后在清单中调整路径:

Manifest.in:

recursive-include src/foo/data *

注意:如果您使用setuptools_scm

,则无需清单。

如果碰巧使用setuptools并添加了setuptools_scm插件(on pypi),则无需管理Manifest.in文件。相反,setuptools_scm将注意将git跟踪的所有文件添加到软件包中。

因此,在这种情况下,是否将文件添加到sdist / wheel的规则是: 当且仅当

  • include_package_data是True
  • 该文件由git(或其他受setuptools_scm支持的工具)跟踪
  • 并且数据文件在软件包目录下

然后将包含数据文件。

答案 5 :(得分:0)

我的config /目录中带有JSON文件,需要将其添加到wheel包中。因此,我将这些行添加到了MANIFEST.in

recursive-include config/ *.json

setup.py的以下指令:

setup(
 ...
 include_package_data=True,
)

没有任何效果。 直到我在__init__.py目录中创建了一个名为config/的空文件。

(Python 3.6.7,wheel 3.6.7,setuptools 39.0.1)

答案 6 :(得分:-6)

"轮子是ZIP格式的档案......" (http://wheel.readthedocs.org/en/latest

因此,将.whl文件视为.zip文件。添加文件:

  • Python ZipFile object
  • 任何存档/ zip文件实用程序,如7-zip,Winzip,Ark,file-roller等。