代码之家  ›  专栏  ›  技术社区  ›  Ram Rachum

使用setup.py包含非python文件

  •  144
  • Ram Rachum  · 技术社区  · 15 年前

    我该怎么做 setup.py 包含不是代码一部分的文件?(具体来说,这是一个许可证文件,但可能是其他任何东西。)

    我希望能够控制文件的位置。在原始源文件夹中,文件位于包的根目录中。(即与最上面的同一水平面 __init__.py )无论操作系统如何,我都希望它在安装包时始终保持不变。我该怎么做?

    9 回复  |  直到 6 年前
        1
  •  152
  •   Ciprian Tomoiagă    6 年前

    可能最好的方法是使用 setuptools package_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,
    

    包装数据 是一个 dict 包名称(空=所有包)到一个模式列表(可以包括GLUs)。例如,如果您只想在包中指定文件,您也可以这样做:

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

    这里的解决方案肯定是 重命名非- py 文件与A .py 延伸。

    Ian Bicking's presentation 更多信息。

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

    如果您只想控制源发行版的内容,另一种方法可以很好地工作( sdist )在包外有文件(例如顶级目录)是为了添加 MANIFEST.in 文件。见 the Python documentation 对于此文件的格式。

    自从写了这个回复,我发现 通常是一种不那么令人沮丧的方法来确保您的源代码分发( tar.gz )有你需要的文件。

    例如,如果您想包括 requirements.txt 从顶层开始,递归地包含顶层“data”目录:

    include requirements.txt
    recursive-include data *
    

    不过,为了在安装时将这些文件复制到站点包中包的文件夹中,您需要提供 include_package_data=True setup() 功能。见 Adding Non-Code Files 更多信息。

        2
  •  40
  •   Evan Plaice    14 年前

    要完成你所描述的,需要两个步骤…

    • 需要将文件添加到源tarball
    • 需要修改setup.py才能将数据文件安装到源路径

    步骤1:要将文件添加到源tarball,请将其包含在清单中

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

    清单基本上是一个文本文件,包含源tarball中包含的所有文件的列表。

    我的项目清单如下:

    • 更改日志.txt
    • 安装程序
    • 许可证
    • pypreprocessor.py预处理器
    • 小精灵
    • Stuff.Py
    • Py
    • 小精灵

    注:同时 sdist does add some files automatically ,我更喜欢显式地指定它们来确定,而不是预测它做什么和不做什么。

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

    由于要将数据文件(license.txt)添加到源安装文件夹,因此需要修改数据安装路径以匹配源安装路径。这是必需的,因为默认情况下,数据文件安装在与源文件不同的位置。

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

    从distutils中提取install dir信息:

    from distutils.command.install import INSTALL_SCHEMES
    

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

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

    然后,将数据文件和位置添加到setup():

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

    注意:上面的步骤应该以标准的方式完成您描述的内容,而不需要任何扩展库。

        3
  •  7
  •   All Іѕ Vаиітy goblin    7 年前

    创造 MANIFEST.in 在项目根目录中 recursive-include 到所需的目录或 include 文件名。

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

    documentation can be found here

        4
  •  5
  •   Dashing Adam Hughes    10 年前

    在setup.py下的setup(:

    setup(
       name = 'foo library'
       ...
      package_data={
       'foolibrary.folderA': ['*'],     # All files from folder A
       'foolibrary.folderB': ['*.txt']  #All text files from folder B
       },
    
        5
  •  3
  •   Gringo Suave    11 年前

    这是一个对我有效的简单答案。

    首先,根据上面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']},
    )
    
        6
  •  1
  •   Scott Bowers    9 年前

    我只是想继续我在CentOS 6上发现的与Python2.7一起工作的东西。如前所述添加包数据或数据文件对我不起作用。我添加了一个manifest.in,其中包含我想要的文件,这些文件将非python文件放入tarball中,但没有通过rpm将它们安装到目标计算机上。

    最后,我可以使用安装程序/StudioToots中的“选项”将文件放入我的解决方案中。通过选项文件,可以从setup.py修改等级库文件的各个部分。如下所述。

    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
    

    文件-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
    
        7
  •  1
  •   rv.kvetch    6 年前

    我想对其中一个问题发表评论,但我的名声不足以做到这一点>>

    以下是对我有用的东西(在查阅了文档后提出):

    package_data={
        'mypkg': ['../*.txt']
    },
    
    include_package_data: False
    

    奇怪的是,最后一行对我来说也是至关重要的(你也可以省略这个关键字论证——它是一样的)。

    它的作用是复制顶级或根目录中的所有文本文件(从包向上一级 mypkg 你想分发)。

    希望这有帮助!

        8
  •  1
  •   debuglife    6 年前

    第一步:创建 MANIFEST.in 文件与setup.py位于同一文件夹中

    步骤2:包括要添加的文件的相对路径

    include README.rst
    include docs/*.txt
    include funniest/data.json
    

    步骤3:设置 include_package_data=True setup() 将这些文件复制到网站包的函数

    reference is here

        9
  •  -14
  •   Ram Rachum    15 年前

    解决办法:我重新命名了 lgpl2.1_license.txt lgpl2.1_license.txt.py ,并在文本周围加上三个引号。现在我不需要使用 data_files 选项或指定任何绝对路径。我知道,让它成为一个python模块很难看,但我认为它不如指定绝对路径难看。