我如何使setup.py包含一个不是代码一部分的文件?(具体来说,它是一个许可证文件,但也可以是其他任何东西。)

我希望能够控制文件的位置。在原始源文件夹中,文件位于包的根目录中。(即与最顶层的__init__.py在同一层。)我希望它在安装包时保持在那里,而不管操作系统是什么。我怎么做呢?


当前回答

步骤1:创建MANIFEST。和setup.py在同一个文件夹里

步骤2:在MANIFEST.in中包含要添加的文件的相对路径

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

步骤3:在setup()函数中设置include_package_data=True,将这些文件复制到site-package

参考资料在这里。

其他回答

这在2020年有效!

正如其他人所说,创造“显化”。在“setup.py所在的位置”。

接下来在manifest中包含/排除所有必要的东西。这里要注意语法。 例如:假设我们有模板文件夹要包含在源包中。

在manifest文件中这样做:

recursive-include template *

确保像上面那样在文件/dirs的dir-name和pattern之间留有空格。 不要像我们在gitignore那样做

recursive-include template/* [this won't work]

其他选项是使用include。有很多选择。看看他们的Manifest.in文件

最后重要的一步是,在setup.py中包含这个参数,然后就可以开始了!

   setup(
    ...
    include_package_data=True,
    ......
)

希望有帮助!编码快乐!

步骤1:创建MANIFEST。和setup.py在同一个文件夹里

步骤2:在MANIFEST.in中包含要添加的文件的相对路径

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

步骤3:在setup()函数中设置include_package_data=True,将这些文件复制到site-package

参考资料在这里。

我想对其中一个问题发表评论,但我没有足够的声誉来做>.>

以下是对我有效的方法(参考文档后想到的):

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

include_package_data: False

奇怪的是,最后一行对我来说也很重要(你也可以省略这个关键字参数——它的工作原理是一样的)。

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

对于要包含在安装中的非python文件,它们必须位于已安装包目录中的一个目录中。如果您在MANIFEST中指定包目录之外的非python文件。中,它们将包含在您的发行版中,但不会被安装。在包目录之外安装任意文件的“文档化”方式并不可靠(现在每个人都注意到了)。

The above answer from Julian Mann copies the files to your package directory in the build directory, so it does work, but not if you are installing in editable/develop mode (pip install -e or python setup.py develop). Based on this answer to a related question (and Julian's answer), below is an example that copies files to your installed package location either way after all the other install/develop tasks are done. The assumption here is that files file1 and file2 in your root-level data directory will be copied to your installed package directory (my_package), and that they will be accessible from python modules in your package using os.path.join(os.path.dirname(__file__), 'file1'), etc.

记得也要做清单。在上面描述的东西中,以便这些文件也包含在您的发行版中。为什么setuptools会在你的发行版中包含文件,然后默默地不安装它们,这超出了我的理解范围。尽管在包目录之外安装它们可能更可疑。

import os
from setuptools import setup
from setuptools.command.develop import develop
from setuptools.command.install import install
from shutil import copyfile

HERE = os.path.abspath(os.path.dirname(__file__))
NAME = 'my_package'

def copy_files (target_path):
    source_path = os.path.join(HERE, 'data')
    for fn in ["file1", "file2"]:
        copyfile(os.path.join(source_path, fn), os.path.join(target_path,fn))

class PostDevelopCommand(develop):
    """Post-installation for development mode."""
    def run(self):
        develop.run(self)
        copy_files (os.path.abspath(NAME))

class PostInstallCommand(install):
    """Post-installation for installation mode."""
    def run(self):
        install.run(self)
        copy_files (os.path.abspath(os.path.join(self.install_lib, NAME)))

setup(
    name=NAME,
    cmdclass={
        'develop': PostDevelopCommand,
        'install': PostInstallCommand,
    },
    version='0.1.0',
    packages=[NAME],
    include_package_data=True,
    setup_requires=['setuptools_scm'],
)

我找到了一个解决办法:我将我的lgpl2.1 .1_license.txt重命名为lgpl2.1 .1_license.txt.py,并在文本周围加上一些三引号。现在我不需要使用data_files选项,也不需要指定任何绝对路径。我知道把它变成Python模块很难看,但我认为它没有指定绝对路径难看。