MANIFEST.in在“python setup.py install”上忽略 - 没有安装数据文件?

时间:2010-08-29 23:12:51

标签: python build install distutils

这是我的精简版setup.py脚本,删除了非代码内容:

#!/usr/bin/env python

from distutils.core import setup
from whyteboard.misc import meta


setup(
    name = 'Whyteboard',
    version = meta.version,

    packages = ['whyteboard', 'whyteboard.gui', 'whyteboard.lib', 'whyteboard.lib.pubsub',
                'whyteboard.lib.pubsub.core', 'whyteboard.lib.pubsub.utils', 'whyteboard.misc'],

    py_modules = ['whyteboard'],
    scripts = ['whyteboard.py'],
)

MANIFEST.in:

include *.txt
include whyteboard-help/*.*
recursive-include locale *.mo
recursive-include images *.png

当我运行“python setup.py install sdist”时,我得到一个很好的.tar.gz,带有“whyteboard-0.41”根文件夹,里面有我的locale / images /和whyteboard-help / folders。这也有我的whyteboard.py脚本,它从whyteboard源包中启动我的程序。

所以:

whyteboard/
 ├── locale/
 ├── images
 ├── whyteboard-help/
 ├── whyteboard/
 │  ├── __init__.py
 │  └── other packages etc
 ├── whyteboard.py
 ├── README
 ├── setup.py
 └── CHANGELOG

这反映了我的程序的来源,一切应该是怎样的,并且是正确的。

然而,当我运行“python setup.py install”时,我的数据文件都没有写入 - 只有“whyteboard”源包,而whyteboard.py放在/usr/local/lib/python2.6/dist中-packages /.

理想情况下,我希望在.tar.gz文件中生成的目录结构与在dist-packages中创建的目录结构相同,因为这是我的程序期望查找其资源的方式。

如何获得“安装”来创建此目录结构?据我所知,似乎忽略了我的清单文件。

6 个答案:

答案 0 :(得分:55)

MANIFEST.in告诉Distutils在源代码发布中包含哪些文件,但它不会直接影响安装的文件。为此,您需要在setup.py文件中包含相应的文件,通常为package dataadditional files

答案 1 :(得分:25)

除了Ned的回答(关于核心问题)之外的一些注释:

Distutils不会在site-packages(或Debian / Ubuntu上的dist-packages)的每个项目子目录中安装Python包和模块:它们直接安装到site-packages中,就像你'见过。因此,sdist中包含的whyteboard-xx目录将不会存在于最终安装的表单中。

这样做的一个含义是,您应该小心地以明确其所属项目的方式命名data_files,因为这些文件/目录直接安装到全局site-packages目录中,不在任何包含whyteboard目录的内部。

或者您可以改为生成package_data包的数据whyteboard(这意味着它需要存在于该包内,即__init__.py旁边),然后这不是一个问题。

最后,whyteboard.py中的py_modules模块和whyteboard/__init__.py中的packages包都没有多大意义。这两者是互斥的,如果你同时使用这两个模块,导入将忽略whyteboard.py模块,而使用相同名称的包。

如果whyteboard.py只是一个脚本,并且不打算导入,那么您应该使用scripts选项,并将其从py_modules中删除。

答案 2 :(得分:22)

我无法弄清楚为什么我的MANIFEST.in文件在我运行python setup.py install时被忽略 - 结果include_package_data=True解决了问题。实际上并不需要package_data选项。

答案 3 :(得分:8)

在Mac OSX上运行python 2.6.1,除了在setup.py中使用 data_files 参数外,我绝对没有运气。使用MANIFEST.in的所有内容只会导致文件包含在dist包中,但从未安装过。我检查了一些其他软件包,他们确实使用data_files来指定其他文件。

我创建了一个简短的函数来帮助枚举

中目录树中的所有文件 data_files期望的

(target_dir,[file list])格式:

def gen_data_files(*dirs):
    results = []

    for src_dir in dirs:
        for root,dirs,files in os.walk(src_dir):
            results.append((root, map(lambda f:root + "/" + f, files)))
    return results

现在我可以在我的设置调用中调用它:

setup(... data_files = gen_data_files("docs", "lib") ...

这些树中的所有东西都已安装。

答案 4 :(得分:7)

你应该使用setuptools:

#!/usr/bin/env python

from setuptools import setup, find_packages
from whyteboard.misc import meta


setup(
  name = 'Whyteboard',
  version = meta.version,

  packages = find_packages(),
  include_package_data=True,

  py_modules = ['whyteboard'],
  scripts = ['whyteboard.py'],
)

实际上并没有使用MANIFEST文件来完成这项工作,但它包含了所有需要的文件。

答案 5 :(得分:4)

发布的最低可运行示例

关键要点:只有MANIFEST.in为我工作,package_data没有为我工作。

在Ubuntu 19.10,Python 3.7.5,wheel == 0.32.3,setuptools == 41.1.0,twine == 3.1.1。上进行了测试

最终用户如何使用https://pypi.org/project/python-sample-package-with-data/中的软件包:

python3 -m pip install --user python-sample-package-with-data
python-sample-package-with-data

预期输出:

hello data

维护者如何发布它:

# One time setup.
python3 -m pip install --user setuptools wheel twine

# Every time you want to publish.
python setup.py sdist bdist_wheel
twine upload dist/*
rm -rf build dist *.egg-info

实际文件:

MANIFEST.in

# Or else pip install cannot find README.md on the setup.py under certain conditions.
include README.md

# This actually adds the data file.
include python_sample_package_with_data/mydata.txt

python-sample-package-with-data

#!/usr/bin/env python3

import python_sample_package_with_data

print(python_sample_package_with_data.get_data(), end='')

python_sample_package_with_data / __ init __。py

try:
    import importlib.resources as importlib_resources
except ImportError:
    # In PY<3.7 fall-back to backported `importlib_resources`.
    import importlib_resources

def get_data():
    return importlib_resources.read_text(__name__, 'mydata.txt')

python_sample_package_with_data / mydata.txt

hello data

setup.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from setuptools import setup, find_packages

from os import path
this_directory = path.abspath(path.dirname(__file__))
with open(path.join(this_directory, 'README.md')) as f:
    long_description = f.read()

setup(
    name='python-sample-package-with-data',
    version='0.0.3',
    description='My short description',
    long_description=long_description,
    long_description_content_type='text/markdown',
    url='https://github.com/cirosantilli/python-sample-package-with-data',
    author='Ciro Santilli',
    author_email='ciro.santilli.contact@gmail.com',
    packages=find_packages(),
    include_package_data=True,
    scripts=['python-sample-package-with-data'],
)

参考书目: