97

这是我的精简 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'],
)

清单.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/ 文件夹。这也有我的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/ .

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

我怎样才能“安装”来创建这个目录结构?据我所知,它似乎忽略了我的清单文件。

4

6 回答 6

71

MANIFEST.in告诉 Distutils 在源代码分发中包含哪些文件,但它不直接影响安装的文件。为此,您需要在文件中包含适当的setup.py文件,通常作为包数据附加文件

于 2010-08-30T01:09:13.217 回答
35

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

于 2015-05-27T22:34:31.810 回答
30

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

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

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

或者您可以改为制作包的数据package_datawhyteboard这意味着它需要存在于该包内,即在 旁边__init__.py),然后这不是问题。

最后,whyteboard.py在. _ 两者是互斥的,如果两者都有,则导入将忽略该模块,以支持同名包。py_moduleswhyteboard/__init__.pypackageswhyteboard.py

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

于 2010-08-30T13:45:42.577 回答
9

您应该使用 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 文件来完成这项工作,但它包含了所有需要的文件。

于 2013-03-07T07:14:16.183 回答
8

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

我创建了一个简短的函数来帮助枚举目录树中的所有文件

(target_dir, [file list]) data_files 期望的格式:

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") ...

并且这些树中的所有内容都已安装。

于 2011-09-02T19:30:31.623 回答
5

最小的已发布可运行示例

关键要点:只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

实际文件:

清单文件

# 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

安装程序.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'],
)

参考书目:

于 2020-03-18T07:52:51.683 回答