包含setup.py的非Python文件

如何让setup.py包含不属于代码的文件? (具体来说,这是一个许可证文件,但可能是其他任何东西。)

我想能够控制文件的位置。 在原始源文件夹中,该文件位于包的根目录中。 (即与最高级的__init__.py相同的级别)。我希望在安装软件包时将其保留在那里,而不pipe操作系统如何。 我怎么做?

可能最好的方法是使用setuptools package_data指令。 这意味着使用setuptools (或distribute )而不是distutils ,但这是一个非常无缝的“升级”。

这是一个完整的(但未经testing的)例子:

 from setuptools import setup, find_packages setup( name='your_project_name', version='0.1', description='A description.', packages=find_packages(exclude=['ez_setup', 'tests', 'tests.*']), package_data={'': ['license.txt']}, include_package_data=True, install_requires=[], ) 

请注意这里至关重要的特定行:

 package_data={'': ['license.txt']} 

这是一个包名称(空=所有包) dict的模式列表(可以包括globs)。 例如,如果只想在包中指定文件,那么也可以这样做:

 package_data={'yourpackage': ['*.txt', 'path/to/resources/*.txt']} 

这里的解决scheme绝对不是.py扩展名重命名非py文件。

请参阅Ian Bicking的演示文稿了解更多信息。

更新:另一个[更好]的方法

如果你只是想控制源代码发布( sdist )的内容,并且使包(例如顶层目录)之外的文件添加一个MANIFEST.in文件,另一种方法很好。 有关此文件的格式,请参阅Python文档 。

自从编写这个响应之后,我发现使用MANIFEST.in通常是一个不那么令人沮丧的方法来确保您的源代码发布( tar.gz )具有您需要的文件。

例如,如果您想从顶层包含requirements.txt ,则recursion地包含顶级“数据”目录:

 include requirements.txt recursive-include data * 

要完成你所描述的将采取两个步骤…

  • 该文件需要被添加到源代码tarball
  • 需要修改setup.py以将数据文件安装到源path

步骤1:将文件添加到源代码压缩包中,将其包含在MANIFEST中

在包含setup.py的文件夹中创build一个MANIFEST模板

MANIFEST基本上是一个文本文件,其中包含将包含在源代码压缩包中的所有文件的列表。

以下是我的项目的MANIFEST:

  • CHANGELOG.txt
  • INSTALL.TXT
  • LICENSE.TXT
  • pypreprocessor.py
  • 的README.txt
  • setup.py
  • test.py
  • TODO.txt

注意:虽然sdist自动添加一些文件 ,但我更愿意明确地指定它们,而不是预测它做了什么,不做什么。

步骤2:要将数据文件安装到源文件夹,请修改setup.py

由于您正在寻找将数据文件(LICENSE.txt)添加到源安装文件夹,您需要修改数据安装path以匹配源安装path。 这是必要的,因为默认情况下,数据文件被安装到不同于源文件的位置。

要修改数据安装目录匹配源安装目录…

从distutils中安装目录信息:

 from distutils.command.install import INSTALL_SCHEMES 

修改数据安装目录以匹配源安装目录:

 for scheme in INSTALL_SCHEMES.values(): scheme['data'] = scheme['purelib'] 

并且,将数据文件和位置添加到setup()中:

 data_files=[('', ['LICENSE.txt'])] 

注意:上面的步骤应该完全按照标准方式完成,而不需要任何扩展库。

在setup(:)下的setup.py中:

 setup( name = 'foo library' ... package_data={ 'foolibrary.folderA': ['*'], # All files from folder A 'foolibrary.folderB': ['*.txt'] #All text files from folder B }, 

这是一个更简单的答案,为我工作。

首先,根据上面的Python Dev的评论,setuptools不是必需的:

 package_data is also available to pure distutils setup scripts since 2.3. – Éric Araujo 

这很好,因为在你的软件包中放置一个setuptools要求意味着你将不得不安装它。 简而言之:

 from distutils.core import setup setup( # ...snip... packages = ['pkgname'], package_data = {'pkgname': ['license.txt']}, ) 

我只是想跟进我在Centos 6上发现Python 2.7的工作。如上所述添加package_data或data_files对我来说不起作用。 我添加了一个MANIFEST.IN,其中包含非python文件放入tar包的文件,但没有通过RPM将它们安装到目标机器上。

最后,我能够使用setup / setuptools中的“选项”将文件导入到我的解决scheme中。 选项文件让你从setup.py中修改spec文件的各个部分。 如下。

 from setuptools import setup setup( name='theProjectName', version='1', packages=['thePackage'], url='', license='', author='me', author_email='me@email.com', description='', options={'bdist_rpm': {'install_script': 'filewithinstallcommands'}}, ) 

文件 – MANIFEST.in:

 include license.txt 

file – filewithinstall命令:

 mkdir -p $RPM_BUILD_ROOT/pathtoinstall/ #this line installs your python files python setup.py install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES #install license.txt into /pathtoinstall folder install -m 700 license.txt $RPM_BUILD_ROOT/pathtoinstall/ echo /pathtoinstall/license.txt >> INSTALLED_FILES 

在项目根目录下用recursive-include创buildMANIFEST.in recursive-include所需的目录或include文件名。

 include LICENSE include README.rst recursive-include package/static * recursive-include package/templates * 

文档可以在这里find

找出解决方法:我将lgpl2.1_license.txt重命名为lgpl2.1_license.txt.py ,并在文本周围添加了一些三重引号。 现在我不需要使用data_files选项,也不需要指定任何绝对path。 使它成为一个Python模块是丑陋的,我知道,但我认为这比指定绝对path更难看。