如何在 Python 源分发中正确包含杂项文件
How To Properly Include Miscellaneous File With Python Source Distribution
我无法将其他(非Python)文件包含在 Python 项目中 pip install
。
我尝试在 setup()
中使用 include_package_data = True
和 MANIFEST.in
,但它没有包含我想要的 .html
文件。
我也尝试在 setup()
中使用 package_data
,但结果相同。
setup()
中的 data_files
有效。但它不会将 .html
文件复制到 site-packages
文件夹,而只是复制到环境的根目录,文件夹名称为 resource
,如配置中指定的那样。
有人知道我在这里遗漏了什么吗?
我有以下项目结构
ProjectA
- res/
- template_a.html
- template_b.html
- template_c.html
- tool/
- __init__.py
- modulea.py
- constant.py
- project_a.py
- ...
- MANIFEST.in
- setup.py
- ...
setup.py
from setuptools import setup, find_packages
# Read the contents of the README.md file
from pathlib import Path
current_directory = Path(__file__).parent
long_description = (current_directory/'README.md').read_text()
setup(
name = 'project_a',
version = '0.0.1',
# Dependency
install_requires = [
'requests',
],
# Metadata
author = '',
author_email = '',
description = 'Project A.',
long_description=long_description,
long_description_content_type='text/markdown',
packages = [
'tool',
],
py_modules = [
'project_a',
'constant',
'...'
],
# data_files = [
# ('resource', [
# 'res/template_a.html',
# 'res/template_b.html',
# 'res/template_c.html',
# ]),
# ],
python_requires = '>=3.7',
# include_package_data = True,
# package_data = {
# '': ['res/*.html']
# },
)
MANIFEST.in
include res/*.html
第一个问题是 res
未声明为包的一部分 - package_data
仅适用于作为 packages
的一部分包含的实体。
另一个问题是 package_data
的声明有一个空字符串作为键 - 它实际上并不引用根目录而是包目录,并且仅引用文件路径。它不对应site-packages
(或dist-packages
)的根目录。
MANIFEST.in
文件和 setup.py
中的 data_files
声明不是所需解决方案的一部分,因此可以省略。
要解决这些问题,您需要将 res
声明为包的一部分,并且 package_data
需要将该“包”引用为根(以限制包含文件)和所需文件的列表(在本例中,所有 html 文件通过 *.html
glob 语法)作为安装的一部分。更正后的 setup.py
需要包含更改以确保 python setup.py bdist_wheel
包含您希望包含在程序包中的文件:
setup(
name = 'project_a',
# ...
packages = [
'tool',
'res', # add this
],
# ...
include_package_data = True,
package_data = {
'res': ['*.html'], # include this; pairs with the entry in `packages`
# alternatively, uncomment the following to include any
# *.html files from any of the `packages` declared above,
# e.g tools/*.html and res/*.html will be included as tool
# and res are inside `packages`.
# '': ['*.html'],
},
)
运行 python setup.py bdist_wheel
现在应该产生:
$ python setup.py bdist_wheel
running bdist_wheel
...
writing manifest file 'project_a.egg-info/SOURCES.txt'
creating build/lib/res
copying res/template_a.html -> build/lib/res
copying res/template_b.html -> build/lib/res
copying res/template_c.html -> build/lib/res
...
copying build/lib/tool/modulea.py -> build/bdist.linux-x86_64/wheel/tool
copying build/lib/project_a.py -> build/bdist.linux-x86_64/wheel
creating build/bdist.linux-x86_64/wheel/res
copying build/lib/res/template_c.html -> build/bdist.linux-x86_64/wheel/res
copying build/lib/res/template_a.html -> build/bdist.linux-x86_64/wheel/res
copying build/lib/res/template_b.html -> build/bdist.linux-x86_64/wheel/res
copying build/lib/constant.py -> build/bdist.linux-x86_64/wheel
...
creating 'dist/project_a-0.0.1-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it
adding 'constant.py'
adding 'project_a.py'
adding 'res/template_a.html'
adding 'res/template_b.html'
adding 'res/template_c.html'
adding 'tool/__init__.py'
adding 'tool/modulea.py'
adding 'project_a-0.0.1.dist-info/METADATA'
adding 'project_a-0.0.1.dist-info/WHEEL'
adding 'project_a-0.0.1.dist-info/top_level.txt'
adding 'project_a-0.0.1.dist-info/RECORD'
removing build/bdist.linux-x86_64/wheel
请注意,与 packages
和 package_data
中没有 'res'
条目的版本相比,额外的输出已加粗。然后可以在 dist
中找到生成的 .whl
文件,它可以用于安装(例如通过 pip install -U dist/project_a-0.0.1-py3-none-any.whl
)。
我无法将其他(非Python)文件包含在 Python 项目中 pip install
。
我尝试在 setup()
中使用 include_package_data = True
和 MANIFEST.in
,但它没有包含我想要的 .html
文件。
我也尝试在 setup()
中使用 package_data
,但结果相同。
setup()
中的 data_files
有效。但它不会将 .html
文件复制到 site-packages
文件夹,而只是复制到环境的根目录,文件夹名称为 resource
,如配置中指定的那样。
有人知道我在这里遗漏了什么吗?
我有以下项目结构
ProjectA
- res/
- template_a.html
- template_b.html
- template_c.html
- tool/
- __init__.py
- modulea.py
- constant.py
- project_a.py
- ...
- MANIFEST.in
- setup.py
- ...
setup.py
from setuptools import setup, find_packages
# Read the contents of the README.md file
from pathlib import Path
current_directory = Path(__file__).parent
long_description = (current_directory/'README.md').read_text()
setup(
name = 'project_a',
version = '0.0.1',
# Dependency
install_requires = [
'requests',
],
# Metadata
author = '',
author_email = '',
description = 'Project A.',
long_description=long_description,
long_description_content_type='text/markdown',
packages = [
'tool',
],
py_modules = [
'project_a',
'constant',
'...'
],
# data_files = [
# ('resource', [
# 'res/template_a.html',
# 'res/template_b.html',
# 'res/template_c.html',
# ]),
# ],
python_requires = '>=3.7',
# include_package_data = True,
# package_data = {
# '': ['res/*.html']
# },
)
MANIFEST.in
include res/*.html
第一个问题是 res
未声明为包的一部分 - package_data
仅适用于作为 packages
的一部分包含的实体。
另一个问题是 package_data
的声明有一个空字符串作为键 - 它实际上并不引用根目录而是包目录,并且仅引用文件路径。它不对应site-packages
(或dist-packages
)的根目录。
MANIFEST.in
文件和 setup.py
中的 data_files
声明不是所需解决方案的一部分,因此可以省略。
要解决这些问题,您需要将 res
声明为包的一部分,并且 package_data
需要将该“包”引用为根(以限制包含文件)和所需文件的列表(在本例中,所有 html 文件通过 *.html
glob 语法)作为安装的一部分。更正后的 setup.py
需要包含更改以确保 python setup.py bdist_wheel
包含您希望包含在程序包中的文件:
setup(
name = 'project_a',
# ...
packages = [
'tool',
'res', # add this
],
# ...
include_package_data = True,
package_data = {
'res': ['*.html'], # include this; pairs with the entry in `packages`
# alternatively, uncomment the following to include any
# *.html files from any of the `packages` declared above,
# e.g tools/*.html and res/*.html will be included as tool
# and res are inside `packages`.
# '': ['*.html'],
},
)
运行 python setup.py bdist_wheel
现在应该产生:
$ python setup.py bdist_wheel running bdist_wheel ... writing manifest file 'project_a.egg-info/SOURCES.txt' creating build/lib/res copying res/template_a.html -> build/lib/res copying res/template_b.html -> build/lib/res copying res/template_c.html -> build/lib/res ... copying build/lib/tool/modulea.py -> build/bdist.linux-x86_64/wheel/tool copying build/lib/project_a.py -> build/bdist.linux-x86_64/wheel creating build/bdist.linux-x86_64/wheel/res copying build/lib/res/template_c.html -> build/bdist.linux-x86_64/wheel/res copying build/lib/res/template_a.html -> build/bdist.linux-x86_64/wheel/res copying build/lib/res/template_b.html -> build/bdist.linux-x86_64/wheel/res copying build/lib/constant.py -> build/bdist.linux-x86_64/wheel ... creating 'dist/project_a-0.0.1-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it adding 'constant.py' adding 'project_a.py' adding 'res/template_a.html' adding 'res/template_b.html' adding 'res/template_c.html' adding 'tool/__init__.py' adding 'tool/modulea.py' adding 'project_a-0.0.1.dist-info/METADATA' adding 'project_a-0.0.1.dist-info/WHEEL' adding 'project_a-0.0.1.dist-info/top_level.txt' adding 'project_a-0.0.1.dist-info/RECORD' removing build/bdist.linux-x86_64/wheel
请注意,与 packages
和 package_data
中没有 'res'
条目的版本相比,额外的输出已加粗。然后可以在 dist
中找到生成的 .whl
文件,它可以用于安装(例如通过 pip install -U dist/project_a-0.0.1-py3-none-any.whl
)。