如何创建假装提供 Python 模块的虚拟 RPM?

How to create dummy RPM which pretends to provide Python modules?

我需要创建一个虚拟 RPM,它似乎在站点包中安装了一些 Python 模块,以解决 RPM 依赖性问题。

真正的模块将在 Python 虚拟环境中使用 PIP 安装,但为了使系统工作,需要在全局站点包中提供导入的模块,因此需要被伪造。

导入如下(示例):from pear.apple.peach import Fruit

当对具有这些导入的包执行 RPM 构建时,依赖项生成失败,因此我需要本地存储库中的 RPM 假装提供这些,以便依赖项生成通过。

你在问题中提出的方法对我来说没有多大意义,要么你用 python 模块创建 rpm 包,你需要其他系统 rpm 包(你计划创建或安装的包)或者你只是使用虚拟环境然后你不需要太关心你在系统站点包中有什么,只要你安装了特定版本的 python 本身。虽然您可以使系统站点包在特定的虚拟环境中可见(例如,当依赖项中有 lxml 模块时,您可以从 rpm 包安装它,然后使虚拟环境可以访问系统站点包,这样您就不会需要在 virtualenv 中再次安装它),在虚拟 rpm 包中提供特定模块会破坏它,所以这也没有意义。

换句话说,在虚拟环境中安装一些东西然后期望通过 rpm 包安装系统 python 模块以依赖于来自该虚拟环境的东西是行不通的(恕我直言)。

所以我建议执行以下操作之一:

  • 构建您需要安装的模块的 rpm 包,其他包才能工作。只要你有一些 rpmbuild 的经验,它应该不会那么难,你可以使用 pyp2rpm 工具来创建你需要稍微调整的初始规范文件。但这也取决于您需要构建多少个包以及您计划更新它们的频率(因为这意味着更新规范文件并重建)。
  • 仅使用虚拟环境,可以访问或不访问系统站点包。这样,您将依赖项和应用程序都安装到虚拟环境中,并且根本不需要处理 rpm 包(只要您从 rpm 包安装 python 和 virtualenv)。

在你的情况下哪种方式更有意义在很大程度上取决于你想做什么(你打算如何维护 python 模块,你打算在多少台机器上安装它,如果你打算自己安装还是提供给别人自己安装等等...)。

我能够通过使用空文件复制每个导入并在每个文件夹级别使用空 __init__.py 文件来解决这个问题。

例如,要解析 from pear.apple.peach import Fruit,我需要在站点包中安装以下文件树:

-> pear
  -> __init__.py
  -> apple
    -> peach.py

虚拟 rpm 规范文件的相关行:

...
source:FruitDummy.tar.gz    
...
% install
mkdir -p $RPM_BUILD_ROOT%{python_sitelib}/pear/apple/

install __init__.py $RPM_BUILD_ROOT%{python_sitelib}/pear/
install peach.py $RPM_BUILD_ROOT%{python_sitelib}/pear/apple/
...
%files
%defattr(-,root,root,-)
%{python_sitelib}/pear/__init__.py*
%{python_sitelib}/pear/apple/peach.py*
...

__init__.pypeach.py 存储在用于构建 RPM 的 FruitDummy.tar.gz 中。