PyPI releases now reject new files after 14 days

PyPI releases now reject new files after 14 days

PyPI 发布现已拒绝 14 天后的新文件上传

Releases now reject new files after 14 days The Python Package Index (PyPI) now rejects new files being uploaded to releases that are older than 14 days. This restriction was put in place to prevent old and long-stable releases from being poisoned in case publishing tokens or workflows of PyPI projects were compromised. Python 包索引(PyPI)现在拒绝向发布超过 14 天的版本上传新文件。实施这一限制是为了防止在 PyPI 项目的发布令牌或工作流遭到破坏时,旧的、长期稳定的版本被恶意篡改。

As far as we are aware this has not yet been abused, but there is no technical reason beyond that attackers weren’t aware it was possible. Users should not yet rely on this behavior as there are no defined semantics for “releases no longer accepting new files” or APIs available to confirm the state of the release. Instead, these semantics will be defined once “Upload 2.0 API” and “Staged Previews” have been standardized by PEP 694. 据我们所知,目前尚未出现此类滥用情况,但这仅仅是因为攻击者尚未意识到这种可能性,而非存在技术上的阻碍。用户目前不应依赖此行为,因为目前尚无关于“不再接受新文件的发布”的明确语义,也没有可用于确认发布状态的 API。相反,这些语义将在 PEP 694 标准化“Upload 2.0 API”和“Staged Previews”后进行定义。

The discussion of this behavior began during PEP 740 (Digital Attestations) back in January 2024. The discussion was restarted in March 2026 after the popular packages LiteLLM and Telnyx were compromised. These packages were compromised due to a “mutable reference” in these projects’ usage of the Trivy GitHub Action. 关于此行为的讨论始于 2024 年 1 月的 PEP 740(数字认证)。在 2026 年 3 月,热门包 LiteLLM 和 Telnyx 遭到破坏后,相关讨论被重新提起。这些包的受损是由于这些项目在使用 Trivy GitHub Action 时存在“可变引用(mutable reference)”问题。

Originally the discussion stalled due to some projects depending on this behavior to add support for new Python versions to already-published releases. To quantify how disruptive this change would be to existing workflows, the PyPI database was queried for projects that have published new files to old releases (bucketed by number of days since the release). Later, specifically cp314 wheels were queried for the top 15,000 packages, revealing that only 56 projects of 15,000 had published a 3.14-compatible wheel more than 14 days after a release was available. 最初,讨论因一些项目依赖此行为来为已发布的版本添加对新 Python 版本的支持而陷入停滞。为了量化这一变更对现有工作流的干扰程度,PyPI 数据库查询了那些向旧版本发布新文件的项目(按发布后的天数进行分桶统计)。随后,针对前 15,000 个包专门查询了 cp314 wheel 文件,结果显示在 15,000 个项目中,仅有 56 个项目在版本发布 14 天后才发布了兼容 3.14 的 wheel 文件。

This topic was brought to the Packaging Summit at PyCon US 2026 by PyPI Safety & Security Engineer, Mike Fiedler. The rough consensus of the discussion was that the summit attendees thought it was “acceptable to require users to bump to the next version” to support new Python versions. With the data and consensus in hand, Seth moved forward with a patch to reject new files on old releases which was merged July 8th, 2026. 该议题由 PyPI 安全工程师 Mike Fiedler 在 PyCon US 2026 的打包峰会上提出。讨论达成的初步共识是,与会者认为“要求用户升级到下一个版本”以支持新 Python 版本是“可以接受的”。在掌握了数据并达成共识后,Seth 推进了拒绝向旧版本上传新文件的补丁,该补丁已于 2026 年 7 月 8 日合并。

This change will protect Python users and reduce the amount of “cleanup” work associated with project compromises for PyPI admins. This restriction also means that compromises don’t put releases into an indeterminate and confusing state of both “compromised” and “not compromised”, where only a subset of files could be poisoned with malware. Stay tuned for the future where Upload 2.0 API provides semantics for releases that are “closed” instead of “open”. Seth Larson and Mike Fiedler’s work at the Python Software Foundation is supported by Alpha-Omega. 此项变更将保护 Python 用户,并减少 PyPI 管理员在项目受损后所需的“清理”工作量。这一限制还意味着,项目受损不会导致发布版本陷入“既受损又未受损”这种不确定且令人困惑的状态(即只有部分文件被植入恶意软件)。敬请期待未来 Upload 2.0 API 为“已关闭”而非“开放”的发布版本提供明确语义。Seth Larson 和 Mike Fiedler 在 Python 软件基金会的工作得到了 Alpha-Omega 的支持。