Pip: 新的解析器:推出、反馈循环和开发流程

创建于 2019-05-25  ·  83评论  ·  资料来源: pypa/pip

我一直在思考#988(呃!)——特别是如何推出它以最大限度地减少破损并最大限度地获得用户有用反馈的机会。

现在我终于有了两个拇指+时间来提交这个问题。 显然,接下来的所有内容都有待讨论。 :)


我目前推出新解析器的计划是基于将新解析器暴露在标志后面。 流程将是最初不记录它,并在使用标志时添加大量警告。 一旦它不再是实验性的并且更像是测试版,我们就可以开始邀请用户使用新的解析器。 这将涉及到用户的 CTA,要求他们尝试并提供反馈。 使用标志运行时也可能会打印此信息。

在反馈管理方面,我正在考虑请求对不同存储库的问题跟踪器的反馈。 将问题放在不同的问题跟踪器上的原因是在这里尽量减少噪音 + 允许更集中的讨论/调查。 我会将任何不仅仅是“解决方案中的错误”的东西都添加到主要问题跟踪器(这个)。

在过渡方面,我认为一旦对新的决议逻辑有足够的信心,我们就可以研究我们希望如何处理过渡。 将其置于标志后面后,我们将有 2 个选择——直接在一个版本中切换或“稳定”新的解析器并执行(可能是多个版本?)“过渡期”。 我确实认为,当我们更好地了解所涉及的确切权衡时,我们可以稍后进行过渡计划。

就 git/GitHub 而言,这可能是 pip 中的第一个“实验性”功能实现。 FWIW,我计划在我的 fork 上进行实验等,并定期将进度合并到 pip 的主存储库本身(仅代码,到 pip._internal.resolution)。 我不想在主存储库上吵闹,但我确实想让master与这方面的工作保持同步。


请注意,我将 #5051 作为这项工作的障碍,因为在构建原型时处理构建逻辑是多么痛苦。

dependency resolution maintenance

最有用的评论

我年轻、愚蠢和乐观

:-) 而且我有时太老了,疲倦和愤世嫉俗。 让我们继续你的哲学吧,听起来好多了:-)

所有83条评论

我不知道您是如何计划的,但有一条评论是,我鼓励您尝试在新代码和当前代码之间尽可能多地共享代码,并在您努力时重构当前代码允许在新代码路径和当前代码路径之间进行更多共享。

一个原因是,如果您要共享更多代码,那么在您关闭和打开新行为时,损坏的可能性就会较小,因为您将在两种状态下都使用该共享代码,而您不会拥有许多潜在的行为差异需要应对。

这将涉及 CTA 向用户要求他们尝试并提供反馈

我们在获得有关新功能的预先反馈方面的记录非常糟糕。 我们已经尝试了 beta 版本,发布了带有“选择退出”标志的新功能,如果他们遇到问题,人们可以使用这些新功能,大宣传推动了重大变化,但似乎都没有奏效。

我个人的感觉是“让它可用并征求反馈”是我们之前尝试过的一个有趣的变化,但最终它不会有太大的不同。 太多人在他们的自动构建管道中使用带有默认选项的最新 pip,并且在迁移到新的 pip 版本之前不进行测试(我们在 PEP 517 中看到了这一点)。

我想知道 - 我们能否获得 PSF 拨款以获取资源来为此功能进行大型“真实世界”测试练习,或者(更好地)为我们开发测试基础设施? 这样的项目可能包括要求项目让我们知道他们的工作流程和配置,以便我们可以设置测试路径,以确保新的 pip 版本不会破坏它们。 或者甚至只是使用赠款让某人在通信方面有经验,让 beta 测试人员获得新功能,以帮助我们建立更好的用户测试计划?

就 git/GitHub 而言,这可能是 pip 中的第一个“实验性”功能实现

我不是 100% 确定你的意思。 我们过去肯定已经添加了新功能,而“旧方式”仍然存在。 如果这就是您的意思,我们并不倾向于将它们“默认关闭,启用试用”,但这主要是因为我们从未找到任何获得反馈的好方法(见上文)。

我花了大约 60 分钟(re-re-re-re-re-)写了这篇文章,所以现在我要去看看纽约的地方! 如果您没有看到我的快速回复,那是因为我将处于旅游模式。


我鼓励您尝试在新代码和当前代码之间尽可能多地共享代码,并在您工作时重构当前代码以允许在新代码和当前代码路径之间进行更多共享。

确实! 这就是我将#5051 放在前面的原因的 80%——我打算偿还我们在构建逻辑中积累的大量技术债务,以便更容易重用(全部?)它。 一堆代码必须是 :fire: 并且我同意其余的绝对应该尽可能合理地重用。

如果这就是您的意思,我们并没有倾向于将它们“默认关闭,启用试用”

是的,确实。 我还暗示了这里的开发流程——IMO 可以合并空的基础架构(具有一堆方法的类,这些方法只是raise NotImplementedError()将在后续 PR 中充实)或者一个不合并将所有情况(半生不熟的实现)覆盖到master分支中,只要它仅在明确标记为“实验/阿尔法”的标志后面使用。

回复:反馈

我年轻、愚蠢和乐观——我想让这个推出成为一种选择,以获得积极的反馈并采取行动。 我所说的“积极主动”是指那些愿意花一些额外时间来尝试 alpha/beta 功能并告知我们它是怎样的人。 我认为,如果我们发出足够多的声音并战略性地针对/接触人们,我们可以从有时间和精力尝试新功能以帮助解决细节/问题的人们那里获得良好的“主动”反馈。

看看我们最近的“重大”变化,我认为我们收到的大多数反馈都是被动的——用户在工作流程出现问题时意识到他们的工作流程出现问题,然后联系我们告知我们。 他们中的许多人可能没有时间帮助解决新功能的细节,这会引起很多摩擦。 这些也花费了我们大量的“流失预算”[1],我不想花更多的钱,因为 Python Packaging 并没有真正剩下多少 [2]。

FWIW,我计划从 PyPI 发布中借鉴一些想法,比如在相当明显的位置(即不是我的个人博客)发布博客文章,可能会继续播客,适时可操作的电子邮件等。我也在寻找更多现有技术/avenues 进行通信。 我在 PyCon 学到的(很多!)事情之一是,有些渠道我们不使用,这将有助于传播信息,但不会检查我们是否有任何要传播的东西。

需要明确的是,我并不是在批评我们为 PEP 517 采取的推出方法,我认为它进展顺利,特别是考虑到我们都是志愿者这一事实。 我试图看看我们可以学到什么和可行的项目来避免我们遇到的问题。 这些项目中的大多数确实涉及维护人员的更多工作,我什至花所有时间思考这个的主要原因是因为我认为这是一个有趣的学习练习如何进行变更管理。

回复:赠款

是的,我认为我们绝对可以使用授权/更有经验的人来帮助我们弄清楚沟通、推广和测试基础设施。 然而,这确实需要有人来做资助写作工作,并找出比我现在能做的更具体的计划,因为我没有更稳定的小时数/周数可以保证。

FWIW,PSF 与 Changeset Consulting 签订了一份持续合同,以帮助确定与 PyPA/Packaging 相关的通信,所以也许我们可以利用它?


我故意不@-提及人,因为这是在计划状态的早期阶段,以便在对话中增加更多人。

脚注:

  1. @pganssle 使用的一个非常好的术语,我肯定会使用。
  2. 这就是为什么我把#3164 放在次要位置,尽管在那里提出了“pip-cli”包的实现,并且对我们希望推出的外观达成了合理的共识。

我年轻、愚蠢和乐观

:-) 而且我有时太老了,疲倦和愤世嫉俗。 让我们继续你的哲学吧,听起来好多了:-)

确实! 这就是我将#5051 放在前面的原因的 80%——我打算偿还我们在构建逻辑中积累的大量技术债务,以便更容易重用(全部?)它。

伟大的!

刚刚来自 IRC

[sumanah] pradyunsg:我们 pip 和打包社区可以做些什么来帮助您在解析器上更快地完成更多工作?
……
[pradyunsg] 实际上,现在, https://github.com/pypa/pip/issues/6536上的输入可能会帮助我弄清楚如何处理工作/从人们那里获得反馈等。
……
[sumanah] pradyunsg: re: New Resolver: Rollout, Feedback Loops and Development Flow #6536 -- 你想要的输入是这样的:特性标志方法是个好主意吗? 通过 pip GitHub 问题以外的其他机制获得反馈是个好主意吗? 获得赠款或类似的东西来建立真实世界的手动测试和强大的测试基础设施和/或主动通信是一个好主意吗?
...
[pradyunsg] 是的——我建议的想法是否好。 此外,任何可能有助于推出 + 反馈更顺畅的其他想法/方法/想法都会很棒。

所以:

功能标志方法是个好主意吗? 是的。

通过 pip GitHub 问题以外的其他机制获得反馈是个好主意吗? 是的。 我们应该找到自动化的方法来接受来自不太专业的用户的结构较少的错误报告。

更强大的测试基础设施会有所帮助吗? 是的,很多,这是我们的赞助商可以帮助我们的地方。

Changeset(我)能否根据与 PSF 的现有合同帮助 PyPA 协调/通信,帮助 pip 进行主动通信以使我们更系统地进行现实世界的手动测试? 假设在我们想要开始此部署时,我的合同中还有几个小时,是的。

在用户体验、沟通/宣传和测试方面获得更多帮助是否是一个好主意? 是的。 PSF 赠款可能会引起人们的兴趣NLNet 赠款(对于30,000 欧元以下的请求)、 Chan Zuckerberg 的科学赠款必不可少的开源软件Mozilla 的 MOSS也可能会引起兴趣。 包装工作组可以是备案申请人。 如果@pradyunsg@pfmoore想要“是的,听起来很有趣”点头,我可以开始与工作组一起调查这些可能性。

如果@pradyunsg@pfmoore想要“是的,听起来很有趣”点头,

这对我来说绝对听起来很有趣:-)

@pradyunsg@pfmoore想要“是的,听起来很有趣”点头

_点头_是的,这听起来很有趣

更强大的测试基础设施会有所帮助吗? 是的,很多,这是我们的赞助商可以帮助我们的地方。

@brainwane这里也相关的是https://github.com/pypa/integration-test。 我认为进行此设置是另一个潜在的融资领域——我们应该将其添加到https://wiki.python.org/psf/Fundable%20Packaging%20Improvements。

行! 我已经开始与 PSF 和 Chan Zuckerberg Initiative 的人们讨论如何通过包装工作组申请 CZI 资助。 我在 Fundable Packaging Improvements 页面中添加了一些详细信息,说明为什么新的 pip 解析器很重要,并将integration-test项目添加到该列表中。 我已经开始收集用户体验专家的名字,他们有能力研究我们复杂的全命令行包分发/安装工具链,与用户交谈以了解他们对正在发生的事情和应该发生的事情的心理模型,并建议维护者。

如果我们通过 MOSS、CZI 或 NLNET 的资助获得资金,我想我们会获得资金……最早可能是 10 月。 直接来自 PSF 的拨款可能会更快,但“我们目前的重点是 Python 研讨会、会议(尤其是经济援助)和 Python 多样性/包容性工作。”

一个考虑因素是,我知道 Brett 和指导委员会的其他人正在谈论投资于项目管理,并考虑使用某种付费资源来管理这些项目(分类、项目管理等),他们正在与 PSF直接地。 可能值得接触并了解他们在做什么或在想什么,因为我听到了一些关于长期可持续性的讨论,参与其中会是一件好事。

功能标志很好,选择加入很好。 您可能会考虑的一件事是您是否可以随机提示用户试用解析器(例如,非常非常非常罕见并且一次仅用于安装,即不强制他们永久打开它)。 然后你可以指出解析器是如何提供帮助的(例如,它为他们做了什么?它遇到并解决了哪些冲突?)

例如,来自 javascript 或 rust 的人也会期望某种锁文件,所以这可能是需要考虑的事情......

很抱歉跳进去,很高兴看到这向前发展!

我个人的感觉是“让它可用并征求反馈”是我们之前尝试过的一个有趣的变化,但最终它不会有太大的不同。 太多人在他们的自动构建管道中使用带有默认选项的最新 pip,并且在迁移到新的 pip 版本之前不进行测试(我们在 PEP 517 中看到了这一点)。

作为因这个原因而被一些 PEP 517 问题所困扰的人之一,我实际上很想看到一种选择加入的方式来测试。 但我只知道这种东西,因为在--no-use-pep517标志问题之后我订阅了所有 python 打包新闻源。 我要说的是传播这种新闻很难,这可能是很难获得反馈的原因。

我认为如果信息能够更好地传播,会有更多的人对此感兴趣。 这就是您正在寻找的资源所允许的吗?

继续 jriddy 所说的话,我还觉得如果人们必须了解各种功能标志、为每个新标志更改他们的 CI 设置等,就很难让他们测试它们。

然而,看起来更可行的是,如果只有 _one_ 功能标志需要了解,就需要测试的更改来测试“接下来会发生什么”。 然后人们和公司可以设置他们的 CI 来运行它(不会因错误而导致构建失败)。 我正在考虑类似于 Rust 的东西,这些变化在工具链的“beta”通道中烘焙,并且很容易设置另一个 CI 通道来在 beta 工具链上运行东西,并将错误发送给某人。

关键是,这个设置需要学习并完成一次,而不是不断地学习新的单个功能标志、修改 CI 设置或手动测试它们。

然而,看起来更可行的是,如果只有 _one_ 功能标志需要了解,

从某种意义上说,这不是已经以--pre的形式存在了吗? pip 的 beta 发布通道是否只是运行pip install --upgrade --pre pip的问题?

很抱歉跳进去,很高兴看到这向前发展!

@techalchemy ,在所有人中,_you_ 绝对不必为在这个讨论中投球​​而感到抱歉。

这就是您正在寻找的资源所允许的吗?

在某种程度上,是的。

reg: 用于 pip 的 beta 版本/“频道”

感谢您加入@jriddy和@chrish42。 虽然我认为通常这绝对是一个有用/重要的对话,但我也觉得这个问题有点过时。 尽管如此,我会在这里回复一次; 如果我们想进一步讨论这个问题,让我们开一个新问题。

我们过去曾尝试过——最近一次是使用 pip 10——但效果不佳。 我也对未来的效果持怀疑态度,但我也可以想象,对我们的流程进行一些更改可能会导致我们顺利进行。 也许我们可以做一组“仅限测试版”的功能或其他东西? 我曾将-X all想象为 #5727 中的语法。 也许我们可以把它作为这个推出计划的一部分? 同上。 我们需要投入时间和精力来解决这个问题。 :)

https://github.com/pypa/packaging-problems/issues/25#issuecomment -520167480 中所述,我认为对求解器如何改变点子体验进行综合解释很重要。 很多人会因为转向更严格的系统而感到沮丧(尽管总体上事情应该更可靠,但他们会在他们目前没有被阻止的地方被阻止。

对事情如何发生变化以及为什么这是一个好的变化有一个中心解释,这将使对那些愤怒的人的反应变得更加简单。 发布链接,看看他们是否还有其他问题。

预发布是个好主意。 在 conda 中,我们有一个预发布频道 conda-canary。 我们鼓励人们设置一个 CI 作业来对抗 canary,以帮助他们查看 conda 更改是否会破坏它们。 理想情况下,他们会在我们发布该版本之前通知我们。 该频道是一个相当惨淡的失败。 人们似乎真正使用它的唯一一次是当他们想要获得最新版本来修复他们正在努力解决的一些错误时。 我们没有从我们的预期早期采用者那里得到很多报告。 我仍然认为预发布是一个好主意,因为当一个发布很糟糕并且人们因为你破坏了他们的 700 个托管节点而对你生气时,你可以说“好吧,它在我们发布前一周就可以使用。为什么不你在将它们推广到 700 个节点之前测试这些东西吗?” 你正在给人们一个让事情变得更好的机会。 帮助他们意识到,放弃这个机会对他们来说意味着更多的痛苦。 这对他们来说是值得的投资,如果他们将其作为 CI 的一部分,那么除了设置之外,他们不会花费任何时间。

关于标志:我认为最好有一个配置选项(也许除了标志之外)。 我不想一直传递旗帜。 我不确定 pip 是否有这种能力——也许你告诉想要更永久开关的人使用相应的 env var?

关于国旗:

pip 的 CLI 选项会自动映射到配置文件选项和环境变量,并具有适当的名称。

@msarahan感谢您的参与,非常感谢! :)

关于忽略损坏的依赖项的“让我做我想做的事”选项,我认为最好构造功能标志,以便在默认情况下打开解析器后它也可以用作选择退出(例如,启动以--avoid-conflicts作为选择加入,最终移至--no-avoid-conflicts作为选择退出,但从一开始就接受这两个选项)

您还需要考虑--ignore-installed如何与求解器交互 - 当它通过时,您可能应该忽略已安装包的所有要求。

除此之外,将事情作为较小的重构补丁处理以使解析器的集成更容易是一个很好的方法(这就是使 CPython 的新配置 API 成为可能的方法:许多私有重构最终足够稳定以公开)

@ncoghlan解析器的“选择退出”是什么意思? 完全避免依赖解析(以及解析器)是--no-deps 。 我知道需要“忽略此软件包上的版本冲突”或类似的东西。

就我个人而言,我认为将“保持先见”解析逻辑的时间长于向新解析器的过渡期没有任何意义。

但是,如果有这两个选项无法涵盖的用例,我真的很想了解它们。 :)


更广泛地说,如果存在与严格解析器的行为有关的工作流,我很想尽早知道它们是什么样子,以便能够弄清楚是否/如何支持它们。

就我个人而言,我认为将“保持先见”解析逻辑的时间长于向新解析器的过渡期没有任何意义。

IDK,我使用这个“功能”来做一些非常疯狂的构建,比如......

# install just the packages I've built specifically
pip install --no-index --no-deps --find-links=/path/to/my/local/build/cache -r local-reqs.txt

# ...snip to later in a dockerfile, etc...

# install the deps from public PyPI
pip install -r local-reqs.txt

在这种情况下,我要求它在我从本地操舵室安装一些非常预先确定的软件包后解决我的依赖关系。 我想我可以将我的确切版本读入该 local-reqs 文件以使解析器满意,但实际上我发现 pip 的当前行为在允许这些任意构建注入步骤方面非常有用。 我承认,这可能是空格键加热工作流程的一个例子。

但也许“幼稚的解决方案”行为仍然有用。

我同意@pradyunsg。 我认为无限期地维护现有代码新的解析器是不可行的。 当然,作为 pip 维护者,我对此没有兴趣。

从最终用户 POV 来看,我接受新的解析器可能不会做正确的事情的奇怪场景。 并且有一个紧急的“把旧的行为还给我”标志是一个重要的过渡机制(尽管“暂时回滚到以前版本的 pip”是否不一样好是有争议的——即使像 CI 的常见使用这样的事情自动使用最新的 pip 使提倡该选项有问题)。 但从长远来看,为什么我们需要保留当前的行为? 我可以想象以下主要情况:

  1. 解决程序错误。 明显的可能性,易于修复 - 在 pip 的下一个版本中更正错误。
  2. 旧解析器错误的情况(生成无法满足约束的结果)。 当然,我们不打算支持这一点,对吧? (至少不是通过任何比用户固定他们想要的东西并使用--no-deps关闭解析器更极端的方法)。
  3. 新旧解析器给出不同结果的情况,两者都满足给定的约束。 用户可以添加约束来强制执行旧结果(如果他们不能,这会让我们回到 (2))。 我们应该给他们时间这样做,但随后放弃旧的解析器,就像任何其他已弃用的功能一样。
  4. 我们认为过于复杂/奇怪而无法支持的边缘案例。 这就像 (3),但我们没有断言新的解析器给出了“正确”的结果。 用户仍然可以修改约束以避免奇怪的情况,或者固定并使用--no-deps 。 但最终,我们会说“不要那样做”,如果用户忽略该消息,那么在某个时候我们会再次删除旧的解析器,说“我们警告过你”。

还有其他我错过的吗? 特别是在不可能弃用然后删除旧解析器的任何地方?

顺便说一句,在哪里发布“这是我想到的一个极端案例”场景的最佳位置,这样他们就不会迷路? 我认为提前收集尽可能多的奇怪情况会很有用,如果这样我们可以尽早开始编写测试用例:-)

PS 我们可能还应该作为新解析器准备工作的一部分,调查什么是“典型”约束问题(基于 PyPI 上的内容)。 就我自己而言,我很少有比“pip install”更复杂的东西”。在复杂的案件中陷入如此困境以至于我们忽视了绝大多数简单案件,这将是一种耻辱。

  1. 解析器太慢(参见 conda)。 如果我必须在 20 分钟以上的解析器或当前行为之间进行选择,我通常想要当前行为(或者至少尝试一下;在许多情况下,它会碰巧给出一个很好的结果)。

  2. 元数据错误。 今天不是什么大问题,但很容易想象应该可以解决但没有解决的案例。 PyPI 元数据的状况比 conda/conda-forge 元数据更糟糕,这对 conda 来说已经是个问题了。 如果它是错误的并且作为用户我无法获得解决方案,我会想要一些选择退出。

@rgommers对于 6,“忽略此包上的版本冲突”样式选项可以工作,对吗?

谢谢, @rgommers - 这些都是好点。

解析器太慢,我算作解析器错误。 如果它不能在简单的情况下给出足够的性能结果,那么在我看来这不符合目的。 另一方面,如果您有一个非常复杂的约束网络,并且使用完整的解析器需要更长的时间(我希望 20 分钟是夸大其词,我认为在任何情况下都不能接受!),那么我们将进入“我们的考虑过于复杂,无法支持”领域。 换句话说,有没有人尝试过要求 conda 提供一个“快速而肮脏”的不准确但快速的解析器? 如果他们不这样做(我很确定他们不会),那么为什么期望 pip 是合理的呢?

糟糕的元数据绝对是我认为“我们不会支持”的东西(请记住,我在这里谈论的是“在弃用期之后”!)。 给用户时间来修复元数据,并提供“忽略包 X 上的版本冲突”转义子句选项就足够了 IMO,我们不应该仅仅因为有些人不会修复他们的元数据而保留所有旧机器。

但是,是的,宣传我们需要良好的元数据这一事实,因为准确的解析器遵循“垃圾输入,垃圾输出”规则,并监控人们如何响应该消息,这是部署过程的重要组成部分。

在我从本地操舵室安装了一些非常预先确定的软件包后,我要求它解决我的依赖关系。

@jriddy “如果兼容则使用现有安装”的解决策略将适用于此。

在哪里发布“这是我想到的一个边缘案例”场景的最佳位置,这样他们就不会迷路?

https://github.com/pradyunsg/zazo/

对于 6,“忽略此包上的版本冲突”样式选项可以工作,对吗?

是的,这听起来是正确的选择

(我希望 20 分钟有点夸张,我认为在任何情况下都不能接受!),然后我们就进入了“我们认为太复杂而无法支持的事情”的领域。 换句话说,有没有人尝试过要求 conda 提供一个“快速而肮脏”的不准确但快速的解析器? 如果他们不这样做(我很确定他们不会),那么为什么期望 pip 是合理的呢?

有很多人抱怨conda的性能,他们正在倾听 - 但这是很多工作,请参阅他们最近的博客文章。 我不知道是否会有一个快速而肮脏的 conda 选项。 但是,有一些相关的解决方案(黑客),比如conda-metachannel ,它可以让您修剪依赖关系图(手动包含/排除包)以更快地获得解决方案。 所以我认为这也是一样的。

但是,请记住,这绝对是需要的,除非您:

  • 立即比 conda 做得更好(不太可能,这并不是说那些人不知道他们在做什么 - 这只是一个非常棘手的问题)。
  • 只有较小的问题要解决(希望不是真的,PyPI 很大,而且元数据很好,问题应该很大)

糟糕的元数据绝对是我认为“我们不支持”的东西

很公平。 不过,关于“我们不强制执行正确的元数据”的整个立场在这里并没有帮助。 除非最近发生了变化? (而且我知道,这是 PyPI 的事情,而不是 pip 的事情——但它是相关的)。

我不确定你是否真的有你认为的选择。

快速而肮脏的解析器与准确的解析器有何不同? 更快的下降是什么? 约束就是约束——它们没有等级。 你要么满足他们,要么不满足。 也许您只能通过名称开始满足他们,然后按版本等。

当人们对 Conda 运行缓慢感到不满时,基本上都是因为元数据不好。 请记住,无论根本原因如何,您都会因任何感知到的缓慢而受到指责。 错误的元数据有时是不正确的约束,但更常见的是缺少允许考虑更旧的、不受欢迎的选项的约束。 Conda 最近通过做一件小事大幅改进:删除我们旧的软件集合,这些软件的约束不足(大多过于开放)。 这些开放的约束导致 conda 探索需要大量降级的非常糟糕的解决方案。 这就是解决问题需要几个小时的地方。 降级是非常非常昂贵的操作,因为它们可以级​​联,每个步骤的限制越来越少,成本也越来越高。

以“垃圾进,垃圾出”为心态的问题在于,作为求解器的维护者,你拿着袋子。 除非你对垃圾有很好的启发,否则你是无能为力的。 您最终必须调查解决程序为何缓慢,隔离问题包,然后要求问题根源解决问题。 这不是一个很好的位置,相信我。 我们花费大量时间试图向人们解释为什么 conda 会永远占用或者无法与 conda-forge、bioconda 或其他 3rd 方渠道的混合使用。 我们最终不得不做侦探工作并告诉那些第 3 方渠道他们需要修复什么。 糟透了。

任何与 conda 的比较都需要考虑 conda 对问题采取了非常不同的方法。 Conda 有一个巨大的元数据来源,可以一次解决所有问题,但 pip 一次递归地解决和优化每一件事(必要时回溯)。 这可能会为您提供不同的优化路径。

@wolfv最近探索了将 libsolv 用于 conda。 他最终很沮丧,因为他无法给出与 conda 相同的答案。 它归结为方法之间的这种差异。 Libsolv 是一个回溯求解器。 它可以作为 pip 的可选编译附加组件来加快速度,尽管我知道您对不直接将编译代码包含在 pip 中很敏感。

@pradyunsg刚刚在他的博客上发布了他 8 月的更新。)

人们现在提出的一些问题和需求是我们现在需要开始收集的东西,例如测试用例。

而且:我们认为什么样的时间表对于此次推出是现实的? 这在很大程度上取决于 Pradyun 的健康状况和空闲时间,以及来自其他 pip 维护者的代码审查可用性,以及我们是否获得了我们正在申请的一些资助,但我认为顺序如下:

  • 构建逻辑重构:正在进行中,在 12 月至 2 月的某个时间完成
  • 用户体验研究和设计、测试基础设施建设、与下游和用户讨论配置标志和过渡时间表:我们需要为此提供资金; 最早开始可能是12月,需要2-3个月
  • 在进行 alpha 测试时引入resolvelib/zazo中定义的抽象:需要几个月,所以保守估计,2020 年 5 月?
  • 采用更好的依赖解决方案并进行 beta 测试: ?

这是正确的吗? 我错过了什么?

我问是因为一些信息收集工作是项目经理和/或 UX 研究人员应该做的事情,在我看来,并且因为https://github.com/pypa/packaging-problems/issues/264和其他问题可能有助于解决人们在这里提出的担忧。

错误的元数据有时是不正确的约束,但更常见的是缺少允许考虑更旧的、不受欢迎的选项的约束。

由于使用不受约束的依赖项或>= some_old_version是规则而不是setup.py / pyproject.toml的例外,这将是一个问题。 我真的不在乎它是“不正确的约束”还是求解器需要做出不同的选择——这是 PyPI 上元数据的状态。

这些开放的约束导致 conda 探索需要大量降级的非常糟糕的解决方案。

你是这里的专家,但没有实用的解决方案吗? 在大多数情况下,不需要降级,因此请先尝试。 然后,每个包只降级 1 个版本。 如果您需要进一步降级,这几乎总是错误的解决方案(可能是由于元数据错误或其他原因)。

实际上,我不确定pip _can_ 是否会降级。 它最初有一个过于激进的“升级一切”策略,现在“按需升级”效果很好。 我从未见过它降级任何东西,实际上它非常适合常规使用。

conda 必须应对的降级示例,但 pip 不会:使用 python 3 的 anaconda 或 miniconda 用户从 python 3.7 开始。 用户有时需要安装仅适用于 python 3.6 的东西。 求解器必须降级 python 和所有其他非 noarch 包。 这是一种特殊情况,也许可以通过对 python 版本更改的特殊行为进行优化,但它说明了一个包中的更改可能需要降级到另一个包的要点。 “到目前为止它一直有效”是愚蠢的运气,而不是一直有效的方法。

至于限制版本,您不能将其应用于解决方案本身。 你有你的限制,任何一种“由一个版本打开”都不能希望足够通用,因为每个包都不同。 不过,您可以在求解器之前按版本剪切元数据。 这就是 conda 的“current_repodata.json”。 只有最新版本。 当它工作时,它会让事情变得非常快,但如果这是唯一的 repodata,人们会非常生气。 事情是不可重现的,他们会感到沮丧的是,前一天有效的规范可能在下一天无效。 我们提供对完整 repodata 的回退,并计划引入基于时间的子集,在给定的时间点仅提供最新版本。 对于回溯求解器,增量开放可用索引数据可能是一个更有用的概念。

pip _can_ 甚至可以降级。

它可以——对于 pip,降级只是一个卸载安装步骤,就像升级一样。 当它看到要求它满足的约束时,它会降级。

以下确实降级了 setuptools - 只要它是 pip 看到的第一件事:

pip install "setuptools < 20.0"

在哪里发布“这是我想到的一个边缘案例”场景的最佳位置,这样他们就不会迷路?

https://github.com/pradyunsg/zazo/

谢谢,我会记住的。 尽管重新思考,我的“病态案例”实际上并不是那么病态。 这主要是一个极端情况,为了了解包的依赖元数据,您必须下载并解包包,在某些情况下,这可能会触发下载大量包而拒绝它们。 这可能是我们需要解决的“简单索引”协议的一个重要限制,但它不是直接的解析器问题。

conda 必须应对的降级示例,但 pip 不会:使用 python 3 的 anaconda 或 miniconda 用户从 python 3.7 开始。 用户有时需要安装仅适用于 python 3.6 的东西。 求解器必须降级 python 和所有其他非 noarch 包。 这是一种特殊情况,也许可以通过对 python 版本更改的特殊行为进行优化,但它说明了一个包中的更改可能需要降级到另一个包的要点。 “到目前为止它一直有效”是愚蠢的运气,而不是一直有效的方法。

这也是您通常_不想降级_的情况。 作为用户,我宁愿得到一个异常,告诉我包不可用,如果我想要的话,让我明确安装 3.6。

另一个例子是渠道之间的不一致。 最近的例子:我们在 Python 3.7.3,然后base得到3.7.4 。 我不在乎那些版本差异,大多数用户也不会。 默认的“什么都不做”比“嘿.4 > .3 ,让我们升级它,然后如果必须的话将其他包的频道更改为base (即使这会降级)”要好得多。

我们提供完整 repodata 的回退,并计划引入基于时间的子集,在给定时间点仅提供最新版本

这听起来像是一个非常有用的改进。

以“垃圾进,垃圾出”为心态的问题在于,作为求解器的维护者,你拿着袋子。 除非你对垃圾有很好的启发,否则你是无能为力的。

对,是真的。 我认为每个 IDE、发行版或“一堆东西的通用接口”都有这个问题。

以下确实降级setuptools

这是用户请求的降级。 我的意思是间接的(例如 pyproject.toml 中的setuptools<20.0 )。 我猜这也可以,但在实践中很少见。

以“垃圾进,垃圾出”为心态的问题在于,作为求解器的维护者,你拿着袋子。

100% 同意。 这是必须非常小心处理的事情。 但相反,试图为任何旧垃圾制定一个理智的行为是不可行的——我们必须在某处划清界限。

提醒一下,这个讨论是由我们是否需要无限期保留现有解析器的问题引发的。 我不确定这些点中的任何一个是否真的会影响这个问题——现有的解析器是不正确的,你能说的最好的就是人们熟悉的破坏行为。 所以我坚持我上面所说的,没有理由在初始过渡期之后保留旧的解析器。

实际上,对于大部分用例,新旧解析器可能会给出相同的结果。

当用户被您的更改破坏时,“正确”对他们来说并不重要。 行为上的任何改变都会激怒一些用户。 告诉他们他们的工作流程是错误的并且他们需要改变对我来说并不是一个非常有效的策略。 我想你需要靠耳朵来玩。 我当然不想永远维护旧的解析器,但你可能需要给人们一条保留它的途径——比如让它成为其他人采用和维护的插件,人们可以将它与 pip 分开安装。

试图为任何旧垃圾制定一个理智的行为是不可行的——我们必须在某个地方划清界限。

是的,但什么是“旧垃圾”? 它有什么区别? 坏垃圾与好垃圾怎么样(请记住,更新并不总是更好)? 我的建议是花大量时间使求解器非常易于调试。 让用户(不仅仅是作为专家的您)可以轻松地跟踪事情的发展方向,以便轻松识别错误的元数据何时是问题,以及错误的元数据是什么。 这是目前大多数用户都没有的技能,老实说,我见过的大多数用户都不想拥有这个技能。 我认为您(或就此而言的 conda)将永远无法对坏与好进行完全准确的自动启发式。

这也是您通常不想降级的情况。 作为用户,我宁愿得到一个异常,告诉我包不可用,如果我想要的话,让我明确安装 3.6。

@rgommers ,conda 4.7 移至此 - 需要明确的 python 规范来更改次要版本。 人们讨厌它。 我不知道发声的人占人口的多少,但是很多人真的,真的不喜欢他们过去能够conda install的东西,而现在他们不能。 他们不太在乎原因,而且他们大多被答案所抚慰,但与此同时,我们仍然需要处理敌意。 只是另一个例子

当用户被您的更改破坏时,“正确”对他们来说并不重要。

另一个例子是渠道之间的不一致。 最近的例子:我们在 Python 3.7.3,然后 base 得到了 3.7.4。 我不在乎那些版本差异,大多数用户也不会。 默认的“什么都不做”比“嘿 .4 > .3,让我们升级它,然后如果我们必须将其他包的频道更改为基础(即使这会降级)”要好得多。

这是一个复杂得多的点。 您基本上是在提出不同的优化标准。 您可能已经在我们位于https://www.anaconda.com/understanding-and-improving-condas-performance/的博客文章中看到了当前的 11 个步骤

这些都非常棘手,并且没有满足所有情况的全局最优值。 考虑到二进制兼容性,以及通道作为所述兼容性的孤岛,通道的强优先级是非常重要的。 Python 构建无关紧要,你是对的,但目前没有办法表达二进制兼容性约束与普通和简单的版本约束。 你需要它来思考你不理会事情的想法。 否则,你很快就会陷入二进制不兼容的地狱。

嗨,感谢@msarahan在这个问题上提到我。 我想早点说,但没有找到时间。

事实上,我尝试了很多使用libsolv作为 conda 规范的求解器。 它确实有效——现在剩下的区别是 conda 不太关心内部版本号,但 libsolv 的编码方式(以及使用回溯求解器)会。 即使使用完整的 repodata,libsolv 也非常快——我什至会说 libsolv 的速度足够快,不会令人讨厌:)

我对 libsolv 的最大贡献是使其跨平台兼容,以便它现在可以在 Windows、OS X 和 Linux 上编译。

我完全提倡将libsolv用于新的解析器,即使它是一大堆编译代码(至少它很快)并且@mlschroe可能会提供帮助——他在 libsolv 支持方面提供了很多帮助conda 匹配规范。

另一方面,我不确定解析器开发处于什么阶段,现在是否为时已晚,编译后的代码是否可以接受。

您可能已经在我们位于https://www.anaconda.com/understanding-and-improving-condas-performance/的博客文章中看到了当前的 11 个步骤

确实我做到了。 那是一篇不错的博文。

您基本上是在提出不同的优化标准。

并不真地。 我认为您的_“二进制兼容性约束与简单的版本约束”_ 只是指向我可能缺少的东西。 我期望的是,任何包都不应该在其元数据中包含python >= 3.7.4== 3.7.4 ,它总是== 3.7 (刚刚检查了 scipy, meta.yamlpythonconda_forge.ymlmax_py_ver: '37' - 有道理)。 因此,引入3.7.4应该什么都不做 - 选择3.7.3并且不更改任何其他内容的解析器比强制3.7.4并触发升/降级链。

猜猜这部分对于pip的推出计划来说已经离题了,很高兴把它带到其他地方。

我的建议是花大量时间使求解器非常易于调试。

+1

另外:使(保持)它尽可能可修复。 这是现在pip的好处,如果它搞砸了,通常可以做cd site-packages && rm -rf troublesome_package (可能随后用--no-deps重新安装)并且事情再次起作用。 像condaapt和朋友这样的东西更难修复。

您基本上是在提出不同的优化标准。

我认为您没有将渠道的概念充分考虑到您的思考中。 我不知道点子有多重要。 绝对比 conda 少得多,但我不确定它是否完全无关紧要。 人们仍然可以一次从多个索引中收集包裹,对吧?

包没有 python >=3.7.4,也没有 ==3.7.4。 conda 包装的标准是有上限和下限。 这些通常由 conda-build 使用配方作者提供的关于版本的多少位置考虑兼容范围的信息自动确定。 包有 >=3.7.2,<3.8.0a0 之类的约束,其中 0a0 的尴尬是为了说明预发布版本低于 .0 版本的事实,因此将匹配人们不匹配的 <3.8.0 规范真的很期待。

包也有一个与之关联的通道。 该频道实际上是版本优化的一部分: https ://github.com/conda/conda/blob/4.6.7/conda/resolve.py#L1074 - 该频道就像一个超级版本,领先于包的主要版本。 如果求解不应该改变 python,那么 python 规范不能是 python ==3.7 - 那是一个范围,通道会影响那个范围。 具体来说,拥有 python ==3.7 规范并从defaults频道安装开始,然后添加conda-forge频道将导致大量流失,因为您引入了新的 python 包“版本”(包括频道)更高,并且您的 python 规范允许该更改。

Conda 4.7 引入了更加激进的规范“冻结”,我很确定这种行为是你所追求的。 不过,这很复杂。 它归结为仅冻结与您的明确规范不冲突的事物。 如何确定“冲突”是困难的部分。 我们认为最好不要冻​​结会阻止求解器向用户提供最新包的东西,这些包是该包的依赖关系图的一部分。 这种冻结是值得一提的,因为它可以在 pip 的每个规范的基础上以 conda 无法做到的方式完成。 我认为这可能是回溯求解器的一个很好的优化。

另外:使(保持)它尽可能可修复。 这就是 pip 现在的好处,如果它搞砸了,通常可以执行 cd site-packages && rm -rf troublesome_package (可能随后使用 --no-deps 重新安装),然后事情又会恢复正常。 conda、apt 和friends 之类的东西很难以这种方式修复。

是的,这非常重要。 我认为 pip 在明智地出售东西方面做得很好,因此更难破解。 这是非常明智的,conda 正在从中学习。 如果您最终使用了任何已编译的代码,请确保它是静态链接的,否则动态加载不可能导致问题。

(libsolv tangent:当我以前为 RH 工作时,我抓住 https://pypi.org/project/solv/ 来关闭 Fedora 上的“pip install solv”安全漏洞,因为 libsolv 构建过程不会生成sdist 或 wheel 存档,更不用说将其发布到 PyPI。很高兴与任何可能有兴趣使用 libsolv 的捆绑副本而不是现在的无害占位符进行真正的库绑定的人聊天)

关于我的“选择退出”评论,我的意思不是“退回到旧的安装逻辑”,我的意思是“提供一个选项来跳过安装会导致违反约束的软件包,而不是使整个安装请求失败”。

Yum/DNF 通过他们的--skip-broken选项提供该选项(在 DNF 中,该标志是--setopt=strict=0的别名),我认为pip的解析器应该提供类似的选项。

@ncoghlan是的。 这就说得通了。

“忽略此包上的版本冲突”样式选项

我已经提到我们会这样做,这就是为什么我对你的评论感到困惑。

我们在同一页上。 :)

@ncoghlandistutils-sig上回复了我提出的时间表,并说这听起来很合理。

@pradyunsg - 期待您的下一次每月更新!

我花了一些时间再次查看这个,并提交了#7317。

我认为我们几乎已经完成了抽象——这要归功于在 pip 的索引交互、依赖解析 + 构建逻辑分离和大量常规清理方面的大量工作。

我刚刚关闭了#7317。 据我所知,依赖解析现在已经从元数据构建逻辑中解耦(足够)了。 构建逻辑重构进展顺利,现在不再是进一步进展的障碍。

我们现在可以开始在 pip 中实现 [resolvelib] 抽象,在适当的情况下从 [passa] 和诗歌的解析器中获取参考。 :)

@pradyunsg我计划从 Poetry 代码库中提取基本解析器(基于 PubGrub)(参见 https://github.com/sdispater/poetry/tree/master/poetry/mixology)。 它主要与其余代码分离,但仍然有对我需要抽象的内部部分的引用。

如果您有兴趣提供帮助,请告诉我。 我们的想法是拥有一个可供第三方使用的 PubGrub 算法的独立实现,并将放在https://pypi.org/project/mixology/中,其中当前包含旧解析器的代码。

@sdispater绝对! 我不知道我是否可以直接提供帮助(时间限制),但如果您可以将 PubGrub 端口与其他诗歌分离,那就太棒了!

其中一件非常棒的事情是拥有一个一致的抽象层,这样 pip、poetry 和 pipenv 使用相同的抽象。 现在,我们有 zazo(我的)、mixology(诗歌的)和 resolvelib(pipenv 的)——它们都定义了某种抽象层,它们略有不同,但(可笑!)相似。 如果您对此持开放态度,请告诉我们!

仅供参考,我们( @wolfv和一般的@QuantStack团队)已经响应了 pip 依赖解析器的 RfP。

建议的方法是采用libsolv C 库,并将对 pip 的版本约束格式的支持贡献给 libsolv。 我们将通过新的 Python 绑定公开 C 库。

Libsolv 是 RPM 生态系统下久经考验的库,因此已经在工业规模上使用。

  • Libsolv 是在 BSD-3-Clause 许可下分发的。
  • Libsolv 支持多种包和存储库格式,例如rpmdeb
    haikucondaarch 。 重要的是,表达形式和方式的多样性
    依赖约束表明它是一个可插拔的系统,应该能够
    以适应 pip 对依赖版本的约束的语法..
  • 在瘦 mamba 包装器中使用 libsolv 而不是 conda 的求解器,我们
    能够显着提高 conda 的性能。 (conda 在大通道的包解析方面的缓慢是我们开发 mamba 的主要动机)。
  • 它可以在 Windows、OS X 和 Linux 上跨平台运行。 ( @wolfv做了 libsolv 的 windows 端口)
  • 它执行完整的 SAT 求解以找到最佳依赖组合,如果不成功,它会返回可操作的提示以解决冲突。

建议的方法是采用 libsolv C 库

对于 libsolv 不支持的平台,需要有一个备用方案(例如,pip 中的 AIX 支持正在积极开发中,而您没有提到 BSD)。 所以 libsolv 作为可用的性能选项对我来说是合理的,但我们并不是真的只能使用它。 (是否有 libsolve 的纯 Python 版本,即给出相同结果的东西,只是速度较慢?)

另外,get-pip.py 将如何工作? 我们是否必须为所有可能的平台包含 libsolv 的二进制文件? 同样,我假设不是,我们将使用纯 python 后备。

长期以来,无法使用外部 C 代码一直是 pip 的烦恼。 我希望看到一个好的解决方案,但是(a)我不确定是否有一个(缺少某种形式的“mini-pip”引导程序解决方案,允许我们完全取消供应商)和(b)这是一项足够大的工作,我讨厌新的解析器依赖它。

@pfmoore

我认为额外的平台支持不应该那么难实现,因为 libsolv 是相当简单的 C 代码。 我很确定没有纯 Python 版本的 libsolv(我理解这是一个缺点,但也没有纯 Python 版本的 Python 或 Python 标准库,所以在我看来它不应该是拦截器)。

我认为对于引导程序,可以有一个纯 Python pip,它使用当前的解析机制,然后基于 libsolv 安装必要的解析器库。 例如,可以固定 libsolv + pip 特定 Python 绑定的确切包,并按照您的描述从 boostrap-pip 安装它们。 这对我来说听起来完全可行,但你可能更清楚会涉及到什么......

我认为额外的平台支持应该不难实现

需要明确的是,我对更小众的平台没有既得利益,我只是认为我们必须非常清楚我们是否要影响支持 pip 的平台(目前基本上是“任何可以运行 Python 的平台” )。 还有我们如何发布 C 扩展的部署问题(因为 pip 目前是作为“通用”轮子发布的,这对于像get-pip.py这样的用例很重要)

我认为对于引导,可以有一个纯 Python pip,它使用当前机制来解决

我在上面已经争论过了,我会在这里重复一遍,我真的不想无限期地在 pip 中维护两个解析器。

但我不想对提案过于消极——我只是想指出我们目前不允许依赖 C 扩展的一些原因,以防你不知道它们。

讨论可能更适合其他地方,并且当/如果揭示更多细节时可能完全多余,但我真的想现在就提出我的问题。

据我了解,libsolv 使用完全 SAT 求解器进行依赖解析,并且需要在开始求解之前先加载依赖信息。 但是 PyPI 现在存储每个包的依赖元数据。 即使您忽略setup.py的运行时依赖性质,也很难有效地获取 SAT 求解器所需的信息。

你打算如何处理这个问题? 您是否计划实施基础架构(并为第三方回购实施提出额外规范)以在上传包时生成.solv文件? 或者您是否有一些策略可以在求解器运行时生成适当的可解数据,并且可能会在新的依赖数据出现时实施一些回溯?

我不知道这方面的任何现有工作,我能找到的大多数资源都表明 Python 打包环境需要其他东西/不仅仅是一个直接的 SAT 求解器。 所以我对这里的任何可能性都非常感兴趣。

这些 .solv 文件仅用于缓存,libsolv 不需要它们来解决。 但我确实同意 PyPI 依赖项的动态特性使得很难使用 SAT 求解器。

(有关更多信息,请参阅 https://docs.google.com/document/d/1x_VrNtXCup75qA3glDd2fQOB2TakldwjKZ6pXaAjAfg/edit)

(请注意,SAT 求解器只是一个回溯求解器,如果遇到冲突,它也会进行子句学习,所以我认为可以将 SAT 求解器用于 PyPI。但它需要是一个允许动态添加子句的求解器解决时。)

如今,SAT 求解器具有一些重要功能,包括动态添加、重新启动、回溯、随机重新启动等。但我认为这里的挑战部分将是与支持平台相关的技术挑战,而这些平台无法保证可以构建基于 C 的求解器。

我现在在机场,所以我无法回应现在提出的观点,但是......我敢肯定我们不应该在这里讨论技术选择/权衡——这更适用于我们如何沟通和管理推出与我们推出什么。 :)

我提交了 #7406 以进一步讨论技术权衡 - @sdispater@techalchemy@uranusjr 、@ wolfv如果我们能就解析器设计的各种选择进行进一步讨论,我将不胜感激。

为了尽早设定期望,我将在接下来的 2 周内出差,希望能够赶上 12 月 9 日的所有讨论。

状态更新: PSF 能够从 Mozilla 开源支持和 Chan Zuckerberg Initiative 获得一些资金来聘请承包商来解决 pip 解析器和相关的用户体验问题。 您可以查看我们的路线图(我需要对其进行完善)以及博客和论坛以及邮件列表的帖子和最近会议的笔记,以随时了解情况。 我很快就会在distutils-sigPython 的 Discourse 实例上的 Packaging 论坛上发布一些关于此的内容。

我们的目标是准备好 pip 的解析器功能,以便在 7 月的 pip 20.2 中发布。 (根据 pip 的季度发布节奏,不可预见的困难可能会延迟到下一季度的 20.3。)

@uranusjr

据我了解,libsolv 使用完全 SAT 求解器进行依赖解析,并且需要在开始求解之前先加载依赖信息。 但是 PyPI 现在存储每个包的依赖元数据。 即使您忽略 setup.py 依赖于运行时的性质,也很难有效地获取 SAT 求解器所需的信息。

#7819 中的原型pip resolve命令使用两种技术来高效地获取此信息(有关详细信息,请参阅该问题):

  1. > 从一个轮子的 URL 中提取 METADATA 文件的内容,而不需要实际下载轮子。
  2. > 将每个 self._resolve_one() 调用的结果缓存在一个持久的 json 文件中。

用于 (1) 的技术能够非常快速地将轮 URL 转换为它所依赖的需求字符串列表,同时仅下载轮子本身的几 KB 内容。 #7819 中的原型然后确保在req.populate_link()返回的每个依赖需求上调用self._resolve_one() ,并将(==Requirement, url) -> [list of (==Requirement, url) non-transitive dependencies]的映射存储在持久 json 缓存文件中。 (1) 快速获取新信息,(2) 快速查询旧信息。

虽然我还不熟悉 libsolv,但我相信从需求 URL 到依赖项及其 URL 的映射条目可能正是 SAT 求解器所需的原子输入。 如 #7189 所示,持久的 json 依赖缓存文件导致pip resolve调用在第一次运行后变为完全无操作,从那时起在命令行上花费 800-900 毫秒。 如果使用(1)和(2)中的技术,我相信每次调用 pip 时都可以让 SAT 求解器运行完成,而无需等待非常长的时间。 尝试在 #7189 的原型之上破解 libsolv 以使这个数字更加具体可能不会太难。

@techalchemy

如今,SAT 求解器具有一些重要功能,包括动态添加、重新启动、回溯、随机重新启动等。但我认为这里的挑战部分将是与支持平台相关的技术挑战,而这些平台无法保证可以构建基于 C 的求解器。

裤子曾经有一些代码可以更容易地将编译器和链接器暴露给基于setup.py的项目(#6273),但我们后来删除了它(参见#7016),以便能够构建不使用setup.py的 C/C++ 裤子,这适用于我们在 Twitter 中的用例,它只需要为TensorFlow 自定义运算符构建一个共享库。 我们在 OSX 和 Linux 的 s3 上托管静态链接的 GCC 和 binutils 存档的预构建二进制文件(请参阅 https://github.com/pantsbuild/binaries/),这样裤子用户无需安装除 python 和 JDK 之外的任何东西完全使用裤子。

我有兴趣帮助集思广益和/或开发任何类型的工具,以可移植地构建 C 和 C++,这可能使 pip 在所有支持的平台上可靠地依赖 libsolv。

@cosmicexplorer

裤子曾经有一些代码可以更容易地将编译器和链接器公开到基于 setup.py 的项目 (#6273),但我们后来删除了这个 (参见 #7016) 以支持构建 C/C++在不使用 setup.py 的情况下穿裤子,这适用于我们在 Twitter 中的用例,它只需要为 TensorFlow 自定义运算符构建一个共享库。 我们在 OSX 和 Linux 的 s3 上为静态链接的 GCC 和 binutils 存档托管预构建的二进制文件(请参阅pantsbuild/binaries),因此除了 python 和 JDK 之外,pants 用户无需安装任何东西即可使用pants。

编译器/链接器的工作非常有趣! 还有关于将编译器与 setup.py (或一般的 PEP 517 构建后端)解耦的讨论。 它与解析器并不真正相关(至少不直接相关),但您可能会感兴趣: https ://discuss.python.org/t/how-do-we-get-out-of-the-business-of-

@cosmicexplorer

我有兴趣帮助集思广益和/或开发任何类型的工具,以可移植地构建 C 和 C++,这可能使 pip 在所有支持的平台上可靠地依赖 libsolv。

我自己和@wolfv一直在研究这个,以便在所有主要支持的mamba平台上构建 DNF 包管理器堆栈的一部分,以及我自己与 DNF 的个人工作。 在这个时间点上,libsolv 现在能够为 Windows、Linux、macOS、BSD、Haiku OS 构建,而且我隐约知道它被放在各种 UNIX 系统上,作为在 UNIX 上使用DNF的一部分。 我知道@dralley使用manylinux2014 on PyPI 为 PyPI~ Linux 支持的主要平台提供了solv二进制轮子

我们现在发布了 pip 20.1b1,这是一个 beta 版本,其中包括新解析器的非常早期 (alpha) 版本(有关此内容的上下文,请参见 #8099,以及人们可以提供反馈的调查)。 这是公告。 并且https://github.com/pypa/pip/issues/7951#issuecomment -617851381 列出了到目前为止我们已经发布了测试版的一些地方。

pip 20.1 现已推出,包括解析器的 alpha 版本。

我们正在讨论在 5 月发布另一个 pip 版本,其中包括解析器的进一步 alpha。 我们正在确定何时发布新解析器的测试版并进行“请测试”推送。

我们在弄清楚#8371、如何更好地显示某些错误消息以及处理一堆其他毛茸茸的东西时遇到了延误; 有关我们进展的更多信息,请参见https://github.com/pypa/pip/projects/6https://github.com/pypa/pip/projects/5 。 #8206 正在讨论即将发布的 beta 版本,pip 20.2b2,我希望我们能在 6 月底之前发布它。

我已经在 PSF 博客上发布了我们的年中报告。 要知道的关键一件事:本月晚些时候,我们将发布 pip 20.2 ,它将通过可选标志“ --use-feature=2020-resolver ”提供新依赖解析器的 beta 版本(pip 20.1 有 alpha 版本)。 我们将大量宣传 pip 20.2,并要求很多用户试用新的解析器。

根据 #8511,我们现在发布了pip 20.2 。 此版本包括下一代依赖解析器的测试版。 当它接收到不兼容的指令时,它会变得更加严格和一致,并减少对某些类型的约束文件的支持,因此一些变通方法和工作流可能会中断。 使用--use-feature=2020-resolver标志对其进行测试。 请参阅我们的指南,了解如何测试和迁移,以及如何报告问题。 新的依赖解析器默认关闭,因为它还没有为日常使用做好准备

我们计划在 2020 年 10 月发布 pip 的下一个季度版本 20.3。我们正准备更改默认的依赖解析行为,并将新的解析器设为 pip 20.3 中的默认值。

请通过指向此博客文章传播信息——在 Hacker News、Reddit、Twitter、Facebook、Dev.to、Telegram、相关的 Stack Overflow 答案以及您最喜欢的 Slack 和 Discords 上传播信息。 这将影响到的大多数人都不会跟上特定于 Python 的开发人员新闻。 帮助他们在 10 月之前获得提醒,并帮助我们获得他们的错误报告。

(从 #988 复制我的笔记。)

@zooba

你认为我们应该在这个阶段更新与 Python 3.9 捆绑的 pip 版本(对于第一个 RC)吗?

同样,是否需要为下一个版本更新 Python 3.8?

我的假设是,是的,在下周初发布错误修复之后,是的,但是@pfmoore @xavfernandez @cjerdonek @uranusjr @pradyunsg @dstufft你怎么看?

抱歉,发帖太早了。 我的理由是捆绑 pip 20.2 将使经验丰富的开发人员在测试最新版本的 Python 时更容易轻松地测试新的依赖关系解析器。 但我不知道更新捆绑版本需要做多少工作,或者你想多久更新一次。

同样在这里,最好在 3.9 中包含 20.2.x 以便更轻松地访问新的解析器。

你怎么看?

你是对的,这就是计划。 :)

好的,在 python-dev 上回答——是的,Python 3.8 和 3.9 中捆绑的 pip 版本应该更新到 20.2.x。

另外,在宣传方面,我会在这里指出一些正在进行的工作:

在接下来的 6 到 8 周内,我将努力获得广泛的宣传,以便用户尝试使用新的 pip。 我怀疑问题不会是“这个单独的包不会安装”; 这将是特定包之间的意外冲突,可能取决于环境和特定的约束文件。 我们正在尝试通过调查获得一些早期反馈,以便我们可以修复错误,设置更多自动化测试等,以便那些上游包可以在 pip 20.3 之前得到提醒并推出已修复的包(例如:https://github.com/pypa/pip/issues/8076#issuecomment-666493069 中的 TensorFlow/numpy/scipy 问题)。

无论我们为此付出多少努力,都会有处理不一致问题的用户被 20.3 绊倒,他们会感到沮丧、困惑和伤害,这会给我们和他们所有的上游带来支持负担。 我们的目标是通过让用户进行测试并引起上游的注意来减少这种情况。

因此,我计划联系并利用关注自己特定领域特定角落的群体——数据科学家、教师、艺术家、DevOps 专家等等。

我假设引起他们注意的一种方法是通过他们所依赖的特定软件包。

昨天我查看了一些广泛使用的软件包列表,并手动给几个人发了电子邮件,并在一些存储库上创建了问题,建议他们要求他们的用户使用新解析器的 beta 进行测试,开始滚动并尝试一些获得更多宣传和测试的措辞/方法。 这至少在一种情况下导致了混乱——请参阅 https://github.com/sqlalchemy/mako/issues/322#issuecomment-667546739——一旦 20.2 的错误修复版本发布,我会多一点系统化和清晰

  • 为什么我们要伸出援手
  • 我们选择联系的人/时间(链接到公共媒体策略会有所帮助)
  • 为什么我们不能使用自动化测试来自己发现这些问题

我们在 Twitter ( 1 , 2 ) 和Reddit上得到了一些关注(有人想回答这个关于 PyPA 资金的问题吗?)。

@zooba写道(关于捆绑):

谢谢。 看起来我们可以在本周晚些时候完成并发布下一轮版本。 如果出现任何您不想被释放的情况,请尽快通知我们。

我发现--use-feature=2020-resolver对我来说通常解决的问题多于它导致的问题。

现在建议通过以下方式进行初始部署是否为时已晚:

提议的20.3伪代码

try:
    _2020_resolver()
except:
    legacy_resolver()

这意味着至少对于我的项目来说,它们都可以不加修改地通过

之后,一旦默认禁用旧版解析器,我可能会在一段时间内有一些项目在 2020-resolver 下工作,而有些项目不在 legacy-resolver 下,我希望能够设置一个标志来启用后备:

提议的20.4伪代码

try:
    _2020_resolver()
except:
    if not use_legacy_resolver:
        raise
    legacy_resolver()

我们计划在本月晚些时候推出 20.3。 我们预计这将需要大量用户支持,因为困惑的用户会向我们提问。

@di自愿帮助召集一些志愿者来帮助做出第一反应。 一旦新的 pip 出现(在 Twitter、StackOverflow 和 GitHub 上),这些志愿者将回答问题并帮助用户支持负载,并将真正的错误上报给维护者/贡献者团队的注意。

达斯汀,我认为你对它的工作方式有一个粗略的计划 - 你介意在这里发布,然后我会从其他 pip 维护者那里得到一些共识吗? 深深的感谢。

这是我的粗略计划:

  • 在讨论.python.org 上发起讨论以寻求支持
  • 将人们引导到一个 Slack 频道,该频道可以作为每个人之间的沟通渠道
  • 开始一份文件,概述一些常见问题解答和我们的回复
  • 包括新问题的决策树 -> 分类问题
  • 一旦我们知道发布日期,请与频道分享此内容
  • 尝试并大致安排志愿者在发布后的几天内在线和分类

谢谢,@di。 我们等到明天才能从其他维护者那里获得 OK。 我们的目标是在 10 月 28 日或 29 日星期三或星期四发布 pip 20.3。

@di我看到您的计划获得批准。 请继续!

@di 提醒发布可能会延迟

万一我们能够发布 20.3(我们希望下周发布)时我没空,这里有一个宣传计划

正如我在其他地方的评论中所讨论的那样,由于一些 CI 问题的出现以及一些外部因素,我们决定稍微推迟发布。

在今天的团队会议上,我们同意 20.3 版本可能会在明天或周五发布。 您可以关注#8936 了解更多信息。


我没有像我在之前的评论中建议的那样对每个包裹进行外展。 但这并不意味着我们没有进行外展。 我们所做的一些外展活动(其中一些在 #8511 或此 wiki 页面中进行了编目):

在过去的几个月里,我们不断收到来自人们在 20.2 和20.3 beta 中测试新解析器 pip 20.3b1的新问题。 这些报告帮助我们改进了解析器,修复了错误并改进了其输出的用户体验。 我们还大幅改进了“有什么变化”用户指南,部分是为了响应测试版反馈。

这是我的粗略计划:

* Start a discussion on discuss.python.org asking for support

* Direct folks to a Slack channel that could serve as a communication channel between everyone

* Start a document outlining some FAQ and our responses

* Include a decision tree for new issue -> triaged issue

* Share this with the channel once we have a known release date

* Try and roughly schedule volunteers to be online & triaging in the days following the release

@di我认识到持续的不确定性和延误可能使您无法进行日程安排。 新的发布日期是明天,11 月 30 日,星期一。 如果您现在有要分享的讨论主题和决策树,请继续分享!

pip 20.3 已经发布,默认有新的解析器! 这是 PSF 博客上的发布公告: https ://blog.python.org/2020/11/pip-20-3-release-new-resolver.html

此页面是否有帮助?
0 / 5 - 0 等级