跳转到主要内容

PyInstaller社区维护的钩子

项目描述

pyinstaller-hooks-contrib: PyInstaller社区钩子仓库

当(你的?)包与PyInstaller不兼容时会发生什么?比如说,你需要运行时使用的数据文件?PyInstaller并没有捆绑这些文件。你的包需要PyInstaller看不到的其他内容?如何解决这个问题呢?

总结来说,一个“钩子”文件可以扩展PyInstaller,使其能够适应Python包的特殊需求和使用的特定方法。这个“钩子”一词用于两种类型的文件。运行时钩子帮助引导程序启动应用程序,设置环境。包钩子(有几种类型)告诉PyInstaller在最终应用程序中包含什么 - 例如上面提到数据文件和(隐藏的)导入。

这个仓库收集了许多包的钩子,使得PyInstaller可以无缝地与这些包一起工作。

安装

pyinstaller-hooks-contrib在安装PyInstaller时会自动安装,或者可以使用pip安装。

pip install -U pyinstaller-hooks-contrib

我看不到a-package的钩子。

要么a-package在不需要钩子的情况下工作良好,要么还没有人为其贡献钩子。如果你想添加钩子或查看有关钩子的信息,请参阅以下内容。

钩子配置(选项)

支持配置(选项)的钩子和它们的选项在支持的钩子和选项中有文档说明。

我想帮忙!

如果你有一个想要分享的钩子,那太好了!本页的其余部分将带你了解如何贡献钩子的过程。如果你之前来过这里,你可能想跳转到总结清单

除非你对git rebase -i非常熟悉,否则请为每个拉取请求提供单个钩子! 如果你有多个钩子,请分别提交它们。

设置

如果你还没有这样做,请Fork这个仓库。(如果你已经有了Fork但很旧,点击你Fork的主页上的“Fetch upstream”按钮。)通过运行以下命令来克隆你的Fork并进入(用你的github用户名替换bob-the-barnacle):

git clone https://github.com/bob-the-barnacle/pyinstaller-hoooks-contrib.git
cd pyinstaller-hooks-contrib

为你的更改创建一个新分支(用包的名字替换foo):你可以为这个分支命名任何你喜欢的名字。

git checkout -b hook-for-foo

如果你希望在下一步之前创建虚拟环境,现在就做。

以可编辑模式安装此仓库。这将覆盖你的当前安装。(注意,你可以使用pip install --force-reinstall pyinstaller-hooks-contrib来撤销此操作。)

pip install -e .
pip install -r requirements-test.txt
pip install flake8 pyinstaller

注意,在macOS和Linux上,pip可能被称为pip3。如果你通常使用pip3python3,那么这里也使用pip3。如果你没有打算提供测试,可以跳过第二行(但请提供测试!)。

添加钩子

标准钩子位于_pyinstaller_hooks_contrib/stdhooks/目录中。运行时钩子位于_pyinstaller_hooks_contrib/rthooks/目录中。只需将你的钩子复制到那里。如果你不确定你的钩子是否是运行时钩子,那么它几乎肯定是标准钩子。

请在钩子中注明(使用注释)任何异常情况。这里的“异常”定义为以下任何一种

  • 长长的hiddenimport子模块列表。如果你需要很多隐藏导入,请使用collect_submodules('foo')。为了加分,追踪为什么有这么多子模块被隐藏。常见的原因包括
    • 懒加载子模块(模块内的importlib.importmodule()__getattr__()中)。
    • 动态加载的后端。
    • 使用Cython或包含import语句的Python扩展模块。
  • 使用 collect_all()。这个函数的性能非常糟糕,并且因为它混淆了包和分发,所以它是有意设计成这样的。请确认您确实需要收集所有子模块、数据文件、二进制文件、元数据和依赖项。如果需要,请在注释中说明(如果您知道原因,请说明)。不要仅仅为了未来兼容性而使用collect_all()
  • 任何复杂的 os.path 运算(我这里说的就是过于复杂的文件名操作)。

添加版权头部

所有源文件都必须包含版权头部,才能符合我们的条款和条件。

如果您正在添加一个新的钩子(或任何新的Python文件),请将以下适当的版权头部复制/粘贴到顶部,并用当前年份替换2021年。

标准钩子或其他Python文件的GPL 2头部。
# ------------------------------------------------------------------
# Copyright (c) 2024 PyInstaller Development Team.
#
# This file is distributed under the terms of the GNU General Public
# License (version 2.0 or later).
#
# The full license is available in LICENSE, distributed with
# this software.
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ------------------------------------------------------------------
仅运行时钩子的Apache头部。再次提醒,如果您不确定您的钩子是否是运行时钩子,那么它将是标准钩子。
# ------------------------------------------------------------------
# Copyright (c) 2024 PyInstaller Development Team.
#
# This file is distributed under the terms of the Apache License 2.0
#
# The full license is available in LICENSE, distributed with
# this software.
#
# SPDX-License-Identifier: Apache-2.0
# ------------------------------------------------------------------

如果您正在更新一个钩子,请跳过此步骤。不要更新版权头部年份,即使它已经过时。

测试

测试对我们持续集成至关重要。有了它们,我们可以自动验证您的钩子是否在所有平台、所有Python版本以及库发布的新版本上正常工作。没有它们,我们不知道钩子是否损坏,直到有人用困难的方式发现。请编写测试!!!

某些用户界面库可能无法在不进行用户交互或某些Web API的包装库需要凭证(以及可能需要付费订阅)的情况下进行测试。在这种情况下,请不要提供测试。相反,在提交信息中或在您打开拉取请求时解释为什么自动测试不切实际,然后跳转到下一步

编写测试(s)

测试应该是最少的代码,如果您没有您所贡献的钩子,就会导致故障。例如,如果您正在编写一个名为foo的库的钩子,该库在PyInstaller上import foo时立即崩溃,那么import foo就是您的测试。如果import foo在没有钩子的情况下也能正常工作,那么您需要更有创造力。这种最小测试的良好来源是您要为它编写钩子的库的文档中的入门示例。包的内部数据文件和隐藏依赖项容易移动,因此测试不应直接检查数据文件或隐藏模块的存在,而应使用库的预期会使用这些数据文件或隐藏模块的部分。

测试通常位于tests/test_libraries.py。导航到那里,并添加以下内容,用库的真实名称替换所有foo出现的地方。(注意,你在这个文件中的位置并不重要。)

@importorskip('foo')
def test_foo(pyi_builder):
    pyi_builder.test_source("""

        # Your test here!
        import foo

        foo.something_fooey()

    """)

如果库在过去版本中发生了重大变化,您可能需要在测试中添加版本约束。要做到这一点,将@importorskip("foo")替换为对PyInstaller.utils.tests.requires()的调用(例如,@requires("foo >= 1.4")),只有当给定的版本约束得到满足时才运行测试。请注意,@importorskip使用模块名(您会import) whereas @requires使用分发名称(您会pip install),因此您会使用@importorskip("PIL")@requires("pillow")。对于大多数包,分发和包的名称是相同的。

在本地运行测试

不推荐运行完整的测试套件,因为这会花费很长时间测试你未修改的代码。相反,可以使用-k选项来搜索测试名称,单独运行测试

pytest -k test_foo

或者使用完整路径

pytest tests/test_libraries.py::test_foo

固定测试要求

获取你正在工作的软件包版本(使用pip show foo),并将其添加到requirements-test-libraries.txt文件中。现有的要求将指导你使用正确的语法。

在CI/CD上运行测试

现在,当你打开pull request时,CI/CD会自动触发。除非在罕见情况下,这些手动触发作业的说明已不再适用。

为了在所有平台上测试钩子,我们使用Github的持续集成(CI/CD)。我们的CI/CD有些不同,因为它需要手动触发,并带有限制运行哪些测试的参数。这与我们在本地运行测试时过滤测试的原因相同——完整的测试套件需要花费很长时间。

首先推送你到目前为止所做的更改。

git push --set-upstream origin hook-for-foo

将以下URL中的billy-the-buffalo替换为你的Github用户名,然后打开它。它应该带你到你的fork中的oneshot-test操作工作流程。你可能会被问是否想要在fork上启用操作——回答是。

https://github.com/billy-the-buffalo/pyinstaller-hooks-contrib/actions/workflows/oneshot-test.yml

找到“运行工作流程”按钮并点击它。如果你看不到按钮,从页面左侧的工作流程列表中选择“Oneshot测试”标签,它应该就会出现。一个包含一个下拉菜单和5个行编辑字段的对话框应该会出现。在这个对话框中,你可以指定要测试的内容,以及要测试的平台和Python版本。其字段如下

  1. 要运行的分支。将其设置为正在使用的分支(例如hook-for-foo),
  2. 要安装的包及其版本。要测试的包是从已安装的包中推断出来的。通常,你只需将你的更改复制到requirements-test-libraries.txt文件中的这个框中。
    • 设置为foo以测试foo的最新版本,
    • 设置为foo==1.2, foo==2.3(注意逗号)以在单独的作业中测试foo的两个不同版本,
    • 设置为foo bar(注意没有逗号)以在同一个作业中测试foobar
  3. 要运行的操作系统或操作系统
    • 设置为ubuntu以仅测试ubuntu
    • 设置为ubuntu, macos, windows(顺序不重要)以测试所有三个操作系统。
  4. 要运行的Python版本
    • 设置为3.9以仅测试Python 3.9,
    • 设置为3.8, 3.9, 3.10, 3.11以测试所有当前支持的Python版本。
  5. 最后两个选项通常可以保持不变。

点击对话框底部的绿色“运行工作流程”按钮,等待几秒钟然后刷新页面。你的工作流程运行应该会出现。

我们最终希望看到在所有操作系统和所有Python版本上通过的所有构建(或构建集合)。一旦你有了一个,保留它的URL——提交pull request时你需要它。如果你无法让它工作——没关系。打开一个草稿pull request,展示你拥有的内容,我们会尽力帮助。

从终端触发CI/CD

如果你发现反复在Github的“运行工作流程”对话框中输入配置很费力,我们还有一个CLI脚本来启动它。运行python scripts/cloud-test.py --help,它应该会引导你完成操作。你将不得不再次输入所有详细信息,但,多亏了终端历史记录的奇妙之处,重新运行配置只需按下上箭头然后回车即可。

运行Linter

我们使用flake8来强制执行代码风格。如果你还没有安装,请使用以下命令安装flake8,然后使用以下命令运行它。

flake8

没有消息就是好消息。如果它对您的更改有抱怨,请按照它要求去做,然后再次运行。如果您不理解出现的错误,可以查找每行中的错误代码(例如,大写字母后跟数字,例如 W391)。

请勿修复存储库中除您正在工作的部分之外的flake8问题。这不仅对您来说非常无聊,而且由于许多问题与您添加或更改的钩子无关,这会使维护者更难审查您的更改。

添加新闻条目

在提交您的pull request之前,请先阅读news/README.txt。这要求您在提交pull request之前知道pull request编号。您通常可以通过将最新问题或pull request的数量加一来猜测。或者,您可以以草稿形式提交pull request,然后在知道您的pull request编号后添加、提交并推送新闻条目。

摘要

提交pull request前的简要清单

提交pull request

完成上述所有操作后,运行git push --set-upstream origin hook-for-foo,然后继续创建pull request。如果您在进行上述任何步骤时遇到困难,请创建一个草稿pull request并说明问题 - 我们会帮助您的...您可以将提交消息复制/粘贴到Github pull request的标题和描述中。如果您从未进行过pull request,请注意,您只需再次运行git push即可简单地编辑它。无需关闭旧的并启动一个新的。


如果您计划经常贡献或对成为开发者感兴趣,请发送电子邮件至legorooj@protonmail.com告知我们。

项目详情


下载文件

下载您平台对应的文件。如果您不确定选择哪一个,请了解更多关于安装包的信息。

源代码分布

pyinstaller_hooks_contrib-2024.8.tar.gz (131.8 kB 查看散列)

上传时间 源代码

构建分布

pyinstaller_hooks_contrib-2024.8-py3-none-any.whl (322.8 kB 查看散列)

上传时间 Python 3

由以下支持