整理 | 苏宓
出品 | CSDN(ID:CSDNnews)
只因升级一下编程语言的版本,就导致开发的应用被拒、审核不通过、上架不了应用商店,这种鲜少发生的事情如今正在一些 Python 开发者身上上演。近日,据外媒 LWN 报道,一些开发者在将他们的应用程序中使用的 Python 版本从 3.11 升级到 3.12 版本后,重新提交到苹果 App Store 时,遭到了苹果审核团队的拒绝。这也引起了许多开发者的关注。那么,问题究竟出在 Python 3.12 还是苹果审核团队?回看事情经过,起因是一位名为 Eric Froemling 的开发者在 GitHub Python 仓库的 issue 中分享了他的遭遇,其表示:“这并不是一个传统意义上的 bug,但我最近经历了一场磨难。我的应用在苹果的 App Store(具体是 Mac App Store)上更新之后,因为我将使用的 Python 版本从 3.11 更新到 3.12,导致更新被拒绝了。”
起初,Eric Froemling 也并不明白此前可以正常上架的应用程序,为什么做了一下迭代后就不可以了。与此同时,App Store 审核团队在拒绝 Eric Froemling 的 App 时也没有直接说明原因,只冰冷地回复一句「我们无法为您提供更多信息」。几经折腾,Eric Froemling 终于忍无可忍,向苹果团队提交了一份申诉邮件,苹果这才给他一定的提示:应用程序安装或启动了可执行代码。具体来说,该应用程序使用 itms-services URL 方案安装应用程序。稍作解释,itms-services URL 方案是苹果公司提供的一种用于分发和安装 iOS 应用程序的方式,通常用于分发不在 App Store 上发布的应用,如企业内部应用或测试版应用。它允许用户通过点击一个链接直接在他们的 iOS 设备上安装应用程序,而无需通过 App Store。以下是一个基本的 itms-services URL 结构:itms-services://?action=download-manifest&url=https://example.com/manifest.plist
- itms-services://:这是 URL 方案,用于告诉 iOS 设备这是一个应用安装请求。
- ?action=download-manifest:指定要执行的操作,这里是下载应用的清单文件。
- url=https://example.com/manifest.plist:指定清单文件(manifest file)的 URL,清单文件包含应用的详细信息,包括应用包的下载地址。
经过大量的排查,Eric Froemling 发现违规文件是 Lib/urllib/parse.py(Python 标准库的 Urllib 解析器)及其关联的 .pyc。在 Python 3.12 代码中,似乎添加了一个“itms-services”字符串,而苹果 App Store 似乎正在扫描这个字符串,并自动拒绝包含它的任何内容(Eric Froemling 称至少在他的案例中是这样)。
最终,Eric Froemling 从他的 Python 代码中删除该字符串后,更新后的 App 终于通过了审核,成功上架 App Store。
令 Eric Froemling 郁闷的其实并非是“itms-services”字符串埋下的“坑”,而是苹果 App Store 的审核规则。他表示,“当苹果公司最终告诉我,Lib/urllib/parse.py 及其关联的 .pyc 是有问题的文件时,此时追踪到底发生了什么并不难。现在回想起来,我感到很沮丧,我没有想到早点通过 Python 本身对 itms-services 进行全文搜索,也没有偶然发现其他人遇到这种情况。”众所周知,相比写代码,Debug 才是让很多开发者头疼的问题,正因此,也才有了前几日我们报道过的“调查 7 年的 Bug 时,花费了三个月时间来排查,最终只修改了一行代码”事件的发生。时下,Eric Froemling 耗费了大量的精力进行 Debug,只删除了一个字符串就解决问题,在不少开发者看来,「其实本可以通过苹果透明的审核机制来避免的,然而现实就是,苹果的审核机制不透明」。CPython 核心开发者:App Store 审核规则既偏执又难以捉摸!
对此,CPython 核心开发者 Russell Keith-Magee 在看到 Eric Froemling 提交的 issue 后,随即发布了一篇《处理与 App Store 审核流程不兼容的问题》文章,把这个事情单独拧出来说了一遍。Russell Keith-Magee 称,这个问题也为 CPython 核心开发团队提出了一个有趣的哲学问题:我们愿意为适应 App Store 审核流程付出多大努力?Russell Keith-Magee 解释称,之所以发生这种情况,问题在于苹果公司的 macOS App Store 会自动拒绝任何包含 itms-services 字符串的应用程序。苹果的 macOS 商店分发的软件是经过沙盒处理的,经过沙盒处理的应用程序禁止使用带有 itms-services 方案的 URL。苹果的自动审查程序会捕捉到 urllib 解析器中处理这些 URL 的代码,即使相关应用程序从未使用过 itms-services:// URL 也是如此。标准库中就有这样的代码,因此应用程序会被拒。「对字符串进行一些轻度混淆似乎可以避免这一问题。不过,这并不能保证永远都能解决这个问题,而且可能会引发混乱,也不能保证这将是我们需要解决的唯一一个应用程序验证问题」,Russell Keith-Magee 说,「虽然现在引发问题的是一个 macOS 应用,但类似的 App Store 自动审核流程也存在于 iOS、Android 和微软平台应用商店中。苹果的审核无疑是其中最......偏执和高深莫测的......,它们的验证和验收流程完全不透明」。回归问题本身,这次导致 App 审核不通过的原因是 Python 3.12 中包含了“itms-services”字符串,作为官方如何解决这一问题,Russell Keith-Magee 给出了两个建议:- 新增编程语言设计的目标:将“符合应用程序商店要求”作为 CPython 的设计目标,并整合任何必要的补丁来满足这一要求。这意味着用户不需要进行任何特殊的补丁处理来使 CPython“兼容应用商店”;但这也意味着有时会合并一些丑陋的混淆代码。如果某个时点规则发生变化,可能需要更多的补丁;而如果某个旧规则被移除,我们将没有明确的信号来表明某个特定的混淆代码不再需要。
- 把这个视为一个分发问题。开发时,使用 CPython 就正常用,只不过后面要使用生成打包应用程序的工具(如 Briefcase、Py2app、Buildozer 等)负责对 CPython 进行补丁,使其符合应用商店的要求。就 Briefcase 和 Bulldozer 而言,这些工具还会修补和构建自定义 CPython 库。从过往历史上看,这是因为 CPython 并不支持 iOS 和 Android;Python 3.13 版本源码现在无需打补丁即可运行......但如果我们将此视为分发问题,那么打补丁将成为一项持续性要求。
不过,这两种方式也可能会导致两个新问题的出现,Russell Keith-Magee表示:-
(1) 的方式这也意味着分发的 Python 并不是“官方”的 Python,因为它们已经被修改以供分发;我不知道我们应该如何考虑这是否存在安全或品牌风险。我猜,Linux 发行版在发布 Python 时打的补丁与此类似,也许这并不是一个问题。
- 对于(2),还有一个额外的问题,即 CPython 是否应该记录它所知道的 App Store 审核的各种限制。
对此,另一位 CPython 核心开发者 Alex Gaynor 提出了第三种方案:灵感来源于我们在 pyca/cryptography 上的经验启发。我们经常收到错误报告,说“你拒绝解析这张证书,虽然它在技术上是无效的,但它是由[某个广泛使用的设备或 CA]签发的”。我们得出的答案是:一般来说,我们会接受能解决这类问题的 PR,前提是这些 PR 要小,要本地化,而且一般不会太糟糕。但是,在我们合并 PR 之前,需要有人向第三方投诉(如苹果 App Store),并确保他们意识到了这个问题,并表示他们会采取一些措施来解决这个问题。我们接受的任何解决方法都会有一定的时间限制(即我们会在几个版本中删除解决方法)。这样既能让用户获得良好的 OOTB 体验,又不会让大公司简单地将其怪异问题外部化到 OSS 项目中,从而在两者之间保持平衡。6 月 20 日,Keith-Magee 写道,他想到了另一种方法:与其混淆源代码(苹果可能会认为这是“试图规避合法的安全审查程序”),不如在构建时添加一个选项,删除我们知道有问题的代码。Mac 文件夹将包含一个 diff,其中描述了需要应用到源代码树中的改动(在本例中,删除了 parse.py 中对 itms-server URL 的支持;但如果需要,也可以扩展)。configure 将获得一个 --with-app-store-patch 选项。在大多数平台(包括 macOS)上,该选项默认为禁用,但在 iOS 上会启用。如果启用,它将在构建标准库之前应用补丁。该选项也可以接受一个文件(即,--with-app-store-patch=path/to/patch),这样,如果在特定 Python 版本的维护窗口关闭后,App Store 的规则在未来某个时间发生了变化,发行商仍有一个受支持的选项来提供更新的补丁。是的,这实质上是复制了分销商可以轻易复制的东西,但它的好处是,CPython 作为一个项目,可以提供一个官方列表,列出 App Store 合规性所需的更改。
最终,结果几天内部思考,Keith-Magee 在 6 月 25 日回复道,「感谢大家的意见,我刚刚提交了#120984(https://github.com/python/cpython/pull/120984)来实现该--with-app-store-compliance 选项」,以此解决因字符串导致 App 被 App Store 拒之门外的事情。他在请求中提到,这个选项可以用于 iOS 和 macOS 以外的平台,但目前没有这样的使用案例。如果一切顺利,它将在 Python 3.13 中可用。令人沮丧的是,不少开发者反馈,像 Python 这样的自由软件项目不得不浪费时间,想方设法绕过不透明的审查程序,以便开发人员能够为非自由平台编写软件。HN 网友评价道:试试用 PyInstaller 编译 Python 应用程序,同时开启 Windows Defender 实时扫描(默认设置)。如果没有 Defender 的阻止,你甚至无法编译二进制文件。同样,尝试在打开 Windows Defender 的情况下运行 PyInstaller 生成的二进制文件。Defender 会说这是恶意程序,不会运行它。两个主要的操作系统平台都不遗余力地阻止你发布和运行 Python 应用程序,这有点反乌托邦。在这一次经历中,CPython 核心开发者 Keith-Magee 和其他 CPython 开发者还能果断站出来,其所采取的方法似乎是为 Python 应用程序开发者提供最佳体验的最省事的选择。然而,几乎可以肯定,这不会是最后一次有项目遇到这个问题。来源:
https://lwn.net/SubscriberLink/979671/4fb7c1827536d1ae/
https://discuss.python.org/t/handling-incompatibilities-with-app-store-review-processes/56011/15
https://news.ycombinator.com/item?id=40815130
好啦,今天的内容分享就到这,感觉不错的同学记得分享点赞哦!PS:程序员好物馆 持续分享程序员学习、面试相关干货,不见不散!