2009-10-23 145 views
108

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

我希望能够控制文件的位置。在原始源文件夹中,该文件位于程序包的根目录中。 (即与最上面的__init__.py位于同一级别)。我希望它在安装软件包时完全保留在那里,而不管操作系统如何。我怎么做?

+0

你怎么做,在目前?你以前的问题表明你很熟悉如何添加许可证文件,那么你的代码是什么“不起作用”? – SilentGhost 2009-10-23 11:22:15

+1

'data_files = [('',['lgpl2.1_license.txt',]),]'把它放到Python26文件夹中。 – 2009-10-23 11:23:24

+0

经过一些负面反馈,我再次阅读您的问题,并意识到我错过了什么。我已经更新了我的答案,为您的问题提供了一个不需要任何附加模块(如setuptools或distribute)的非侵入式解决方案。 – 2010-11-19 14:26:45

回答

122

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

这里有一个完整的(但未经测试)例如:

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']}, 
include_package_data=True, 

package_data是包名的dict(空=全包)至模式列表(可以包括球体)。例如,如果你想只有你的包中指定的文件,你也可以这样做:

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

这里的解决方案肯定是不你非py文件与.py扩展名重命名。

有关更多信息,请参见Ian Bicking's presentation

UPDATE:另一个[更好]方法

另一种方法,如果你只是想控制源分布(sdist)的内容,并有文件包外(例如顶级目录)行之有效的添加一个MANIFEST.in文件。有关此文件的格式,请参见the Python documentation

因为写这个回应,我已经发现,使用MANIFEST.in通常是少折腾方法只要确保你的源代码分发(tar.gz)有你需要的文件。

例如,如果你想包括从顶级的requirements.txt,递归包括顶级的“数据”目录:

include requirements.txt 
recursive-include data * 

尽管如此,为了在安装时被复制这些文件到站点包内的​​包文件夹,您需要为setup()函数提供include_package_data=True。有关更多信息,请参阅Adding Non-Code Files

+0

链接到伊恩的演示文稿已损坏:( – 2011-09-30 12:48:08

+0

更新后的演示文稿链接 - 谢谢! – 2011-12-08 17:56:14

+5

package_data也可用于自Python 2.3以来的纯distutils安装脚本 – 2011-12-09 16:12:25

-13

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

+6

查看我的帖子。它不一定是丑陋的。在网上很难找到一个很好的例子,因为很难找到用于设置软件包的良好文档。 – 2010-06-15 04:05:06

34

要完成您所描述的内容,需要执行两个步骤...

  • 的文件需要被添加到源压缩包
  • setup.py需要被修改到数据文件安装到源路径

步骤1:要添加的文件到源码包,包括它在清单

创建包含setup.py

文件夹中的 MANIFEST模板0

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

这里是我的项目的清单如下所示:

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

注:虽然sdist does add some files automatically,我更喜欢明确指定他们是肯定的,而不是预测它做什么和不。

第2步:安装数据文件到源文件夹,修改setup.py

既然你正在寻找一个数据文件(LICENSE.TXT)添加到源安装文件夹,你需要修改数据安装路径以匹配源安装路径。这是必要的,因为默认情况下,数据文件安装到与源文件不同的位置。

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

拉动从安装使用的distutils目录信息:

from distutils.command.install import INSTALL_SCHEMES 

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

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

而且,添加数据文件和位置设置():

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

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

+4

MANIFEST只控制包含在源代码tarball中的文件(由sdist生成)。列出的文件将不会被安装。 – 2010-11-17 07:56:19

+0

@David我没有意识到我在第一种方法中有多远。我已经更新了答案,无需额外的第三方库即可完成问题的提问。 – 2010-11-19 14:21:31

+0

我认为手动编辑安装方案是一个非常糟糕的主意。 – 2011-12-09 16:13:32

3

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

首先,上面的每一个Python开发的评论,不需要的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']}, 
) 
+0

它会抱怨'pkgame'不存在的目录 – 2016-01-05 05:01:45

4

在setup.py下设置(:

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

我只是想跟进的东西,我发现与Python 2.7在CentOS 6的工作添加package_data或data_files如前所述上面没有为我工作,我添加了MANIFEST.IN与我想要的文件,把非python文件放到tarball中,但没有通过RPM将它们安装到目标机器上。能够使用setup/setuptool中的“选项”将文件导入到我的解决方案中秒。选项文件可让您从setup.py中修改spec文件的各个部分。如下。

from setuptools import setup 


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

文件 - MANIFEST.in:

include license.txt 

文件 - filewithinstallcommands:

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 
1

在项目的根创建MANIFEST.inrecursive-include所需目录或include的文件名。

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

documentation can be found here

相关问题