这是我的精简版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中创建的目录结构相同,因为这是我的程序期望查找其资源的方式。
如何获得“安装”来创建此目录结构?据我所知,似乎忽略了我的清单文件。
答案 0 :(得分:55)
MANIFEST.in
告诉Distutils在源代码发布中包含哪些文件,但它不会直接影响安装的文件。为此,您需要在setup.py
文件中包含相应的文件,通常为package data或additional 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'],
)
参考书目: