Ipython: 带回 readline 功能?

创建于 2017-03-01  ·  38评论  ·  资料来源: ipython/ipython

即使它不是默认使用的,我也经历过并听说过足够多的其他人在使用基于 prompt_toolkit 的输入破坏人们的工作流程时遇到痛苦,我认为我们应该认真考虑重新引入该代码。

我认为完全删除它并同时更改默认值是错误的。

  • 最近 Sage 邮件列表上关于此的讨论
  • #9816 有几个用户报告破损
  • 与 #9388 中的 readline 相比,有几个用户提出了具有回归的提示工具包
  • 同样,#10075 包含来自用户的评论:“多行编辑是一个非常好的功能。但是,作为一个长期的 vim 和 bash 用户,切换到 IPython 5.x 和 prompt_toolkit 一直很不和谐。”
  • #10085 列出了 prompt_toolkit 的限制和不一致,这些问题不会在上游解决
  • #9944 是提示工具包转换的另一个问题,它曾经在旧的基于 readline 的代码中工作,(虽然我知道 Thomas 最近在 #10185 中提出了一个修复程序,那里有关于它的局限性的讨论,也)。
  • #10211 是 emacs 用户影响了一项更改,据我所知,这也归因于向提示工具包的过渡。
  • #10315 是 IPython 5 中的另一个意外中断,因为 prompt_toolkit 使用单独的线程进行完成(而完成必须在 readline 中同步,因此 jpype 完成在 IPython <= 4 中工作正常)。
  • #9948 - 用户无法使用 tmux 粘贴多行。
  • #10071 - 在 docker 中升级到 IPython 5 后随机丢失提示(因为终端大小报告为 0x0)
needs-decision

最有用的评论

对于仍然订阅此问题的任何人:我刚刚发布了rlipython 0.1.0 版,您现在可以pip install rlipython并在import rlipython; rlipython.install()之后让旧的 readline 在 IPython 中默认工作。

所有38条评论

我愿意为 6.0 及时完成这项工作,因此我将在此处标记 #10329。

我认为这是一个特别重要的问题,因为 IPython 的长期用户和拥护者发现自己对使用 IPython 5 感到沮丧甚至不愿意像现在这样使用。

我很高兴将其添加为一个选项,尽管大部分代码已被删除,并且重新集成 readline 可能需要付出很多努力。

如果我们能弄清楚如何使其成为可选(以便它可以比核心更快地重新修复由复兴引入的潜在错误,那就太好了。

如果我们将 RL 带回来,我们可能想延迟 #10356。

参见#9260。

#9399 是大部分删除。

我对此强烈-1。 当我们放弃 readline 时,我们能够减少大量代码和复杂性(我们正在努力减少更多),同时显着改善大多数用户的用户体验。 如果我们带回 readline 选项,我们将永远维护两个接口的所有复杂性。 我们一直都知道这么大的变化会破坏一些工作流程,但我相信这是一个净改进,我不希望我们从事维护两个替代终端接口的业务。

我宁愿我们:

  1. 继续致力于我们可以在 IPython 和 prompt_toolkit 中改进的任何内容,以消除切换障碍。 每当我们向他询问与 PTK 相关的问题时,乔纳森通常都会做出令人印象深刻的响应和帮助,因此我认为我们很有可能获得我们需要接受的任何更改。 这包括更好地记录如何设置自定义快捷方式,以及尝试读取.inputrc (尽管我宁愿这是默认选项,原因我在别处解释过)。 如果我们给人们一个简单的选择来返回 readline,这些改进就不会发生。
  2. 如果还有人真的坚持使用 readline,可以分出一个单独的包,如rlipython提供终端接口,但要明确说明它是社区维护的,而不是我们正式支持的东西。

鉴于 Windows 上的 pyreadline 总是存在许多问题(尤其是它在全局范围内影响了标准 Python REPL 以及 IPython),我希望不需要 (py)readline 保持默认值,在至少在 Windows 上。 如果用户更喜欢手动安装 pyreadline 并启用它,那很好,但是 IPython 应该在没有 pyreadline 的情况下工作,而不是将其作为正常安装的依赖项包含在内。

如果还有人真的坚持使用 readline,可以分出一个像 rlipython 这样的单独的包来提供终端接口,但要明确表示它是社区维护的,而不是我们正式支持的东西。

我认为这是合理的,尽管我相信与 IPython 有一些集成(如标志和/或环境变量)可以恢复以前的行为是合理的。 目标是已经很好地传播了依赖 IPython readline 的脚本和配方,但仍然可以使用简单的开关。

我的猜测是 IPythonApp 中的一个简单配置,使 TerminalInteractiveShell 类使用 traitlet,加上一个具有已知外部包预设值的 --readline 标志就足够了。

作为一个单独的包,ipython 也将允许不阻塞 IPython 6,并在必要时获得快速迭代周期。

如果我们给人们一个简单的选择来返回 readline,这些改进就不会发生。

我怀疑这是完全正确的。 多行、突出显示和现在完成仍然是 PTK 界面的一大优势。 并且因为他们甚至不能同时使用 RL/PTK 而固定到 4.x 的用户没有动力向 IPython/PTK 发送补丁来平滑行为。

我不会将它与开关集成,因为这使它看起来像是一个受支持的选项,人们会在这里提交有关它的错误。 无论如何, rlipython的输入量比ipython --readline ,如果人们热衷于将它用作ipython ,他们可以将其别名化。

只是对ctrl-r当前体验的说明:

在 Bash 中,当您按 ctrl-r 然后按 Esc 键时,它会将您退出。

在这个中,它应该关闭搜索区域时什么也不做。

简单说明一下当前 ctrl-r 的体验:
在 Bash 中,当您按 ctrl-r 然后按 Esc 键时,它会将您退出。
在这个中,它应该关闭搜索区域时什么也不做。

这个很容易修复,但并不完全:

 ~/dev/ipython master [1]"!!" $ git diff
diff --git a/IPython/terminal/shortcuts.py b/IPython/terminal/shortcuts.py
index 22ad111..89713cd 100644
--- a/IPython/terminal/shortcuts.py
+++ b/IPython/terminal/shortcuts.py
@@ -54,6 +54,10 @@ def register_ipython_shortcuts(registry, shell):
     registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)
                         )(reset_buffer)

+
+    registry.add_binding(Keys.Escape, filter=HasFocus(SEARCH_BUFFER)
+                        )(reset_search_buffer)
+
     registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER)
                         )(reset_search_buffer)

这会起作用,但在您按下新键之前, I-search-backward:仍然可见。 如果取消向后搜索,这个新键的行为将是 has,但感觉非常奇怪。

感谢您打开这个,@ivanov! 我将更仔细地讨论细节,我也将鼓励对此列表提供更多反馈。 这显然是一个棘手的平衡和争议,因此一个好兆头,更多的声音至少可以为我们的决策过程提供信息。

只是关于这项工作可能的前进方向的更新: @Carreau没有将已删除的代码适当地引入 IPython,Carreau/rlipython 上创建了一个新项目,其中仅包含基于 readline 的旧代码,并创建了 #10373,允许用户定制这件作品。

仅供参考:邮件列表中描述的问题:

我问主要是因为至少在 SMC 中,如果您尝试粘贴多个
它粘贴在第一行并默默地忽略所有内容别的。 这可能是 SMC 中 xterm 支持级别的问题
(即 term.js)。 然而,这很令人沮丧。

这表示该终端不支持括号粘贴。
恕我直言:我认为现在我们可以期望任何终端都支持它: https ://cirw.in/blog/bracketed-paste(至少 prompt_toolkit 将需要括号内的粘贴,用于粘贴多行文本。)

可能值得再次添加 readline 支持,但请注意,多个提到的错误已经修复或将收到修复。 最大的问题可能是 Emacs 终端(它不是真正的 xterm 兼容终端,永远不会得到支持)和 .inputrc 支持最终会出现,但由于我这边的带宽/优先级问题,需要一些时间。

无论如何,请继续报告用户体验问题。 这个很重要。

@pfmoore这是一个很好的观点。 我怀疑任何 Windows 环境都因缺乏 pyreadline 而受到伤害。 如果我们带回 readline UI,那么仅对“true” readline 执行此操作可能是有意义的,无论是在 IPython 中还是在rlipython包中。

单独的 rlipython 包的一个优点是它可以与现有的 IPython 5 版本一起使用,而在 IPython 本身中这样做显然只适用于新的 IPython 版本。

我想添加 #9799 作为对 prompt_toolkit 默认值的另一个不舒服的来源。 如果安装额外的外部软件包,我会非常满意。

pyreadline 在 Windows 上很麻烦,但 prompt-toolkit 也有问题。 因此,在 2 个不令人满意的解决方案之间,“技术债务”较少的解决方案看起来是最好的解决方案:提示工具包。

我认为关键是 prompt_toolkit 对某些人更好,而 readline 对其他人更好。 所以问题是,是否有必要将 readline 人员松散以避免维护额外的代码?

pyreadline 在 Windows 上很麻烦,但 prompt-toolkit 也有问题。 因此,在 2 个不令人满意的解决方案之间,“技术债务”较少的解决方案看起来是最好的解决方案:提示工具包。

我认为关键是 prompt_toolkit 对某些人更好,而 readline 对其他人更好。 所以问题是,是否有必要将 readline 人员松散以避免维护额外的代码?

请注意,现在附加的 PR (#10373) 是 4 行,并且只是一个配置选项,使其成为配置选项。 readline 代码甚至不会在 IPython 中,而是一个扩展。

真正的问题是:

  • A: 如果 readline-ipython 是一个具有不同拼写的单独可执行文件,是否可以。
  • B:或者对于脚本和扩展到 IPython(例如 emacs),如果它是 IPython 配置选项。

在这两种情况下, readline 都不会再次成为 IPython 的依赖项。

它确实影响了一些在 IPython 中更容易保留的功能,但现在主要的争论是 A 或 B。

从 emacs 方面来看,两者都很好。 从长远来看,B 似乎更灵活。

我想,对于我们这些喜欢 readline 的人来说,我们也希望 IPython 脱壳的 readline - 所以 B.

我一直在考虑这个问题,并与我有机会亲自参与的团队中的一些人交谈。 这是我对此事的看法。 我还没有做出最终决定,但我正在努力让我们更接近解决方案。 顺便说一句,我想强调的是,我非常感谢 Prompt Toolkit 团队,因为它在绝大多数情况下为我们提供了令人惊叹的、现代的和高质量的用户体验。 关于手头的问题:

  • 需要 readline 的用户的担忧是非常真实的,我认为我们现在应该为他们找到一个好的解决方案,即使成本是在 IPython 中/周围携带一些额外的代码。

  • 我们将继续与 PT 团队合作,将其改进为与 readline 相同的功能,这是一个问题(我知道它有大量 RL 没有的功能)。

  • 即使 PT 进一步改进,我仍然可以看到普通旧 readline 有价值的情况。 PT 凭借其复杂性,在 Emacs 内的 ipython shell 内通过 ssh 在 tmux 内运行时可能会更慢或更脆弱。 这是一个有效的用例,我们应该很好地支持它,而且我们曾经这样做过。

鉴于此,我认为一个好的折衷解决方案与@Carreau在他的 PR 中提出的建议一致:

  • 我们支持 readline 但只能通过必须由用户手动安装的第三方包。

  • 然后用户可以在他们的配置文件中设置这个包的使用,在命令行调用它,或者编写一个 shell 别名或小包装脚本。 是的,这需要这个角落案例的用户做一些额外的工作,但它以最低的成本为他们提供了一个干净的解决方案,而大多数可以使用 PT(并从其功能中受益)的用户继续不间断地这样做.

这确实意味着支持这个额外的包一段时间,但我不认为它会有那么多工作:代码在很长一段时间内几乎没有改变,而且我们不是在谈论添加很多新功能。 只需保持与现有历史基线行为的兼容性。

我认为有些重要的一个成本是(@Carreau 提到的)可能有一些我们想要撕掉的代码,这会阻止我们删除。 我认为这是我们应该为用户的利益付出的代价,至少目前是这样。 如果在未来的某个时间我们真的发现自己处于 PT 在每种可能的情况下 100% 替代 RL 的情况,我们可以重新审视。 但就目前而言,为了我们的某些用户子集的利益而保留一些略显陈旧的专用代码是正确的做法。 多年来,我们有多种特殊情况代码(windows、py2/3 等),我相信将来还会有。 我认为,为我们用户的工作流程提供服务应该优先于代码清理(在这种情况下,不要一概而论)。

这听起来如何?

顺便说一句,我认为这个“修复”应该被移植到 5.x 系列:如果有的话,我怀疑仍然使用 python 2.x 的用户群与在旧服务器上远程工作的用户群有很好的重叠。 所以我的投票是让外部包兼容 python 2-3,并将代码的 ipython 端向后移植到 5.x。

感谢 Fernando 抽出时间做出回应,尤其是与几个人取得联系。
我将努力完善我的 PR,合并它并将其向后移植到 5.0。

我在 GitHub 上为任何对维护 readline 界面感兴趣的人提供了rlipython 。 我不会维护,也不会在 PyPI 上发布它,但欢迎你这样做,如果你需要一个组织,把它移到https://github.com/ipython-contrib可能是一件好事.

谢谢 !

我实际上认为我们应该将它托管在主要的 IPython 组织上,并将其放在 pypi 上。 我们还可以向社区发送稍微更受欢迎的信息,例如:

这是我们为支持历史兼容性和某些特定用例而提供的东西,其中我们的主界面(提示工具包)不是最佳的。 但是,除了修复关键错误之外,我们不打算进行任何重大的开发。 我们只有资源来提供这种尽力而为的解决方案。 如果您有兴趣对此工具进行任何重大开发,请通过问题告诉我们,我们可以探索将软件包的维护权转让给您。”

如果@ivanov有几个周期可以朝这个方向发展,那就太好了,但如果没有,我愿意在接下来的几周内这样做。 我认为这是与我们用户社区的各个角落进行互动的重要组成部分。

感谢@Carreau将工作推到这么远!

谢谢大家,尤其是@Carreau获得了rlipython 。 我已经开始研究它并将其塑造成形状。 如果有人错过了它,它现在位于ipython/rlipython 下。 当我开始使用它时,我将在接下来的两周内尝试发布一个版本,但现在我可以说它有效! 现在有一个已知问题 - 输入/输出提示没有被着色,我正在 ipython/rlipython#3 中跟踪,但除此之外,它看起来很棒。

@ivanov ,如果你想要一只手,请联系我......我在上面提供了,但在过去几周我对我的时间可用性有点天真。 尽管如此,我想帮助所有 cmd line 用户找到一个可靠的解决方案,所以如果你需要帮助,我仍然愿意参与(并且会喜欢这样做:)

由 #10373 关闭并反向移植为 #10463

嗨,这个问题已经解决了,有什么办法可以完全禁用prompt_toolkit吗?

嗨,这个问题已经解决了,有什么办法可以完全禁用 prompt_toolkit 吗?

是的,如果您在配置文件中将TerminalIPythonApp.interactive_shell_classrlipython ,则甚至不应导入 prompt_toolkit。 rlipython 的自述文件提供了有关如何执行此操作的更多信息。

对于仍然订阅此问题的任何人:我刚刚发布了rlipython 0.1.0 版,您现在可以pip install rlipython并在import rlipython; rlipython.install()之后让旧的 readline 在 IPython 中默认工作。

迟到了,但让我重申一下,RT 目前对于那些模块不是为多线程初始化而设计的项目来说是禁忌,请参阅 Sage 的

同样,对当前 RT 的一个普遍问题的评论:它在执行制表符完成时触发 Python 模块的多线程导入。 我们非常怀疑它是否安全。

最后但并非最不重要的 - 鉴于 IPython 选项卡完成会导致段错误,那么对它进行非交互式测试的方法如何?

@jonathanslenders您是否遇到过在单独线程中运行完成的任何问题? 有没有让它同步运行的选项?

@takluyver

抱歉回复晚了。 我上个月结婚了,所以我有一段时间没上网了。 ;)

我正在研究 prompt_toolkit 2.0,它已经支持同步(在主线程中)和异步(在其他线程中)完成。 我已经在 2.0 上工作了将近一年,并希望在几个月内发布它。

对于同步完成,您必须记住,如果完成器不是超快,这将在每次击键后引入延迟(如果您在输入时完成)。 我相信绝地武士不是超级快。

我知道某些库在异步完成方面存在一些问题。 我认为我们应该鼓励这些库的作者确保首先可以从任何线程导入它们。 将来,我会将其作为运行完成同步或异步的选项,但仍然更喜欢默认情况下使用异步完成。 它使用户体验变得更好。

2017 年 10 月 21 日星期六下午 2:47,Jonathan Slenders < [email protected]

写道:

我知道某些库在异步方面存在一些问题
完成。 我认为我们应该鼓励这些库的作者
确保首先可以从任何地方导入它们
线。

恕我直言,这是一厢情愿的想法,这总是很容易实现。
有 Python 库基本上包装了非常复杂的 3rd
方代码,线程安全初始化所需的更改必须
上游完成。
一个具体的例子,我们正在敲我们的头
是在(嵌入到 Python 中的)Lisp 系统 ECL 中运行的 Maxima。
后者,和所有 Lisps 一样,需要一个 garbade 收集器,它使用BoehmGC 。 在某些平台上,后者必须是
在主线程中初始化---或者它曾经是这种情况,例如
FreeBSD,直到我指出它,它很快就被
如果这样的修复程序可能完全不走运,因为它需要专家
一个相当复杂的系统的知识。

有几个问题需要解决,其中之一是在一个
在单线程场景中,库可以进行自己的信号处理,而
在多线程场景中,信号处理必须集中。 这
另一个更难解决的问题是,第 3 方代码可能不是
线程安全。
(回到上面的例子,我们看到了所有这些......)

看来最好的选择是
让 PT 在主线程中执行所有导入---我不知道是否
不过,实施起来很容易,甚至可行。

最后,让我指出实际上 PT 执行多线程导入。
由于导入是大型系统的启动瓶颈,它非常
很想允许多线程导入。
我真的很想听听 CPython 的人们会怎么说; 一世
如果答案是不能这样做,也不会感到惊讶。

附注。 我不是要毁了你的蜜月,恭喜:-)

恭喜! 当然没有必要道歉 - 我们免费为您提供很棒的图书馆,因此任何支持都必须在您方便的时候提供。 向您和您的伴侣致以最良好的祝愿。

我认为我们可能会在它们可用时切换到同步完成。 我们不使用 complete-as-you-type,因为我们启用了与此互斥的历史搜索功能。

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

相关问题

sataliulan picture sataliulan  ·  4评论

ghost picture ghost  ·  4评论

jwkvam picture jwkvam  ·  4评论

ederag picture ederag  ·  3评论

ipython picture ipython  ·  3评论