在 PEP518 环境中从另一个包访问非 Python 文件 (pyproject.toml)
Accessing non-Python files from another package in PEP518 environment (pyproject.toml)
我想制作一个 Python 包(从这里开始 mypackage
),其中包括非 Python 文件(在我的例子中,这些是 C++ 头文件)在安装其他使用它作为依赖项的软件包期间可用(从这里开始 other_package
)。
为了 mypackage
将文件包含在源分发中并使相同的文件可安装,我做了以下操作:
- 包含在
MANIFEST.in
包文件中的文件:
graft <folder_with_files>
- 在
data_files
下的 setup.py
文件中包含文件。
setup(
name = 'mypackage',
packages = ['mypackage'],
...
data_files = ["folder_path", ("the", "files")]
)
到目前为止,在这两个地方都有它们使得 mypackage
在使用 distutils
、setuptools
或 [=26] 时可以正确安装非 Python 文件=](本地和来自 PyPI)。使用 setuptools
和 pip
时,我可以在 sys.prefix
中的 folder_path
下找到非 Python 文件 - 例如:
import sys, os
os.path.join(sys.prefix, "folder_path")
并且在使用 distutils
时,它们与 python 文件位于同一文件夹下,因此可以通过 mypackage.__file__
找到它们 - 例如
import re, mypackage
re.sub(r"__init__\.py$", "", mypackage.__file__) + "folder_path"
但问题是:当另一个使用它作为依赖项的包通过 PEP518 和 pyproject.toml
文件指定了这个依赖项时,mypackage
从 PyPI 下载,并安装在临时环境中PEP518 生成的,但非 Python 文件不在 sys.prefix
下 - 相反,它们安装在一些随机命名的临时文件夹下,如下所示:
$TEMP_FOLDER/pip-build-env-otci9gxx/overlay/folder_path
因此,我试图在 sys.prefix
或 mypackage.__file__
的根目录下查找文件的脚本不会选择这些文件。
如何以编程方式确定性地从 other_package
的 setup.py
获取这些文件在 PEP518 环境中的安装路径?
你真的要使用data_files
吗?
我建议改用 package_data
。这样文件就是 Python 包 本身的一部分(例如安装在 site-packages
中)并且一旦安装就很容易检索。
资源:
- https://sinoroc.gitlab.io/kb/python/package_data.html
- https://docs.python.org/3/distutils/setupscript.html#installing-package-data
- https://setuptools.readthedocs.io/en/latest/setuptools.html#including-data-files
- https://packaging.python.org/guides/distributing-packages-using-setuptools/#package-data
使用以下任一方法访问已安装的 包数据:
1. pkgutil
import pkgutil
pkgutil.get_data('my_top_level_package.my_sub_package', 'file.bin')
importlib.resources.read_binary('my_top_level_package.my_sub_package', 'file.bin')
我想制作一个 Python 包(从这里开始 mypackage
),其中包括非 Python 文件(在我的例子中,这些是 C++ 头文件)在安装其他使用它作为依赖项的软件包期间可用(从这里开始 other_package
)。
为了 mypackage
将文件包含在源分发中并使相同的文件可安装,我做了以下操作:
- 包含在
MANIFEST.in
包文件中的文件:
graft <folder_with_files>
- 在
data_files
下的setup.py
文件中包含文件。
setup(
name = 'mypackage',
packages = ['mypackage'],
...
data_files = ["folder_path", ("the", "files")]
)
到目前为止,在这两个地方都有它们使得 mypackage
在使用 distutils
、setuptools
或 [=26] 时可以正确安装非 Python 文件=](本地和来自 PyPI)。使用 setuptools
和 pip
时,我可以在 sys.prefix
中的 folder_path
下找到非 Python 文件 - 例如:
import sys, os
os.path.join(sys.prefix, "folder_path")
并且在使用 distutils
时,它们与 python 文件位于同一文件夹下,因此可以通过 mypackage.__file__
找到它们 - 例如
import re, mypackage
re.sub(r"__init__\.py$", "", mypackage.__file__) + "folder_path"
但问题是:当另一个使用它作为依赖项的包通过 PEP518 和 pyproject.toml
文件指定了这个依赖项时,mypackage
从 PyPI 下载,并安装在临时环境中PEP518 生成的,但非 Python 文件不在 sys.prefix
下 - 相反,它们安装在一些随机命名的临时文件夹下,如下所示:
$TEMP_FOLDER/pip-build-env-otci9gxx/overlay/folder_path
因此,我试图在 sys.prefix
或 mypackage.__file__
的根目录下查找文件的脚本不会选择这些文件。
如何以编程方式确定性地从 other_package
的 setup.py
获取这些文件在 PEP518 环境中的安装路径?
你真的要使用data_files
吗?
我建议改用 package_data
。这样文件就是 Python 包 本身的一部分(例如安装在 site-packages
中)并且一旦安装就很容易检索。
资源:
- https://sinoroc.gitlab.io/kb/python/package_data.html
- https://docs.python.org/3/distutils/setupscript.html#installing-package-data
- https://setuptools.readthedocs.io/en/latest/setuptools.html#including-data-files
- https://packaging.python.org/guides/distributing-packages-using-setuptools/#package-data
使用以下任一方法访问已安装的 包数据:
1. pkgutil
import pkgutil
pkgutil.get_data('my_top_level_package.my_sub_package', 'file.bin')
importlib.resources.read_binary('my_top_level_package.my_sub_package', 'file.bin')