Ipython: ¿Recuperar la capacidad de readline?

Creado en 1 mar. 2017  ·  38Comentarios  ·  Fuente: ipython/ipython

Incluso si no es lo que se usa de forma predeterminada, he experimentado y escuchado acerca de suficientes personas que experimentan problemas con la entrada basada en prompt_toolkit que rompe los flujos de trabajo de las personas, y creo que deberíamos considerar seriamente traer ese código nuevamente.

Creo que fue un error eliminarlo por completo y cambiar el valor predeterminado al mismo tiempo.

  • discusión reciente en la lista de correo de Sage sobre esto
  • # 9816 tiene varios usuarios que informan roturas
  • Hay varios usuarios que muestran un kit de herramientas rápido que tiene regresiones en comparación con readline en # 9388
  • y de manera similar # 10075 contiene la opinión de un usuario que dice esto: "La edición multilínea es una característica muy buena. Sin embargo, como usuario de vim y bash desde hace mucho tiempo, el cambio a IPython 5.xy prompt_toolkit ha sido discordante".
  • # 10085 enumera una limitación e incoherencia de prompt_toolkit que no se abordará en sentido ascendente .
  • # 9944 es otro problema que surgió con la transición del kit de herramientas rápido, que solía funcionar en el código antiguo basado en readline, (aunque tengo entendido que Thomas propuso recientemente una solución para esto en # 10185, existe una discusión sobre las limitaciones de eso, también).
  • # 10211 es un usuario de emacs afectado por un cambio que, por lo que puedo decir, también es atribuible a la transición al kit de herramientas rápido.
  • # 10315 es otra rotura inesperada en IPython 5, porque prompt_toolkit usa un hilo separado para finalizaciones (mientras que las finalizaciones tenían que ser sincrónicas en readline, por lo que las finalizaciones jpype funcionaron bien en IPython <= 4).
  • # 9948 - el usuario no puede pegar varias líneas usando tmux.
  • # 10071: mensaje que falta al azar después de la actualización a IPython 5 dentro de la ventana acoplable (porque el tamaño de la terminal se informó como 0x0)
needs-decision

Comentario más útil

Para cualquiera que todavía esté suscrito a este tema: Acabo de lanzar rlipython versión 0.1.0, ahora puede pip install rlipython y hacer que la antigua línea de lectura funcione de forma predeterminada en IPython después de import rlipython; rlipython.install() .

Todos 38 comentarios

Estoy dispuesto a hacer el trabajo para recuperar esto a tiempo para 6.0, así que etiquetaré # 10329 aquí.

Creo que este es un tema particularmente importante porque los usuarios y defensores de IPython desde hace mucho tiempo se sienten frustrados o incluso no están dispuestos a usar IPython 5 como está ahora.

Me complace volver a agregar eso como una opción, aunque la mayor parte del código se ha eliminado y es probable que haya muchos esfuerzos para reintegrar readline.

Si podemos descubrir cómo hacer que eso sea opcional (para que pueda evolucionar más rápido que el núcleo para corregir un error potencial que se introdujo con el resurgimiento, sería genial.

Es posible que deseemos retrasar # 10356 si recuperamos RL.

Consulte también el n. ° 9260.

Y el # 9399 es la mayor parte de la eliminación.

Estoy fuertemente -1 en esto. Pudimos eliminar una gran cantidad de código y complejidad cuando abandonamos readline (y estamos trabajando para eliminar aún más), al tiempo que mejoramos drásticamente la experiencia del usuario para la mayoría de los usuarios. Si recuperamos una opción de readline, tendremos toda la complejidad de ambas interfaces para mantener ~ para siempre. Siempre supimos que un cambio tan grande rompería algunos flujos de trabajo, pero estoy seguro de que es una mejora neta y no quiero que estemos en el negocio de mantener dos interfaces de terminal alternativas.

Preferiría que nosotros:

  1. Continúe trabajando en cualquier cosa que podamos mejorar tanto en IPython como en prompt_toolkit para eliminar los obstáculos al cambio. En general, Jonathan ha respondido de forma impresionante y ha sido de gran ayuda cada vez que le hemos hecho ping sobre cuestiones relacionadas con PTK, por lo que creo que tenemos muchas posibilidades de que se acepten los cambios que necesitamos. Esto incluye cosas como documentar mejor cómo establecer accesos directos personalizados y tal vez experimentar con la lectura de .inputrc (aunque preferiría que fuera una opción predeterminada, por razones que he explicado en otra parte). Si le damos a la gente una opción fácil para volver a la línea de lectura, estas mejoras no sucederán.
  2. Si todavía hay personas que realmente insisten en usar readline, cree un paquete separado como rlipython que proporciona la interfaz del terminal, pero deje muy claro que es mantenido por la comunidad, no algo que estemos respaldando oficialmente.

Dado que siempre hubo una serie de problemas con pyreadline en Windows (no menos importante, el hecho de que afectó globalmente al estándar Python REPL así como a IPython), preferiría que no requerir (py) readline permanezca como predeterminado, en menos en Windows. Si un usuario prefiere instalar pyreadline manualmente y habilitarlo, está bien, pero IPython debería funcionar sin pyreadline presente y no incluirlo como una dependencia de una instalación normal.

Si todavía hay personas que realmente insisten en usar readline, cree un paquete separado como rlipython que proporciona la interfaz de terminal, pero deje muy claro que es mantenido por la comunidad, no algo que estemos apoyando oficialmente.

Creo que es razonable, aunque creo que tener alguna integración (como una bandera y / o una variable env) con IPython que restaure el comportamiento anterior es razonable. El objetivo sería tener scripts y recetas bien difundidos que se basen en la línea de lectura de IPython y que sigan funcionando con un simple interruptor.

Supongo que una configuración simple en IPythonApp, que hace que la clase TerminalInteractiveShell use un traitlet, más un indicador --readline que tiene un valor preestablecido para un paquete externo conocido, sería suficiente.

El ipython como paquete separado también permitirá no bloquear IPython 6 y obtener un ciclo de iteración rápido si es necesario.

Si le damos a la gente una opción fácil para volver a la línea de lectura, estas mejoras no sucederán.

Dudo que sea completamente cierto. La multilínea, el resaltado y ahora la finalización siguen siendo una gran ventaja de la interfaz PTK. Y los usuarios que están fijando a 4.x porque ni siquiera pueden usar ambos RL / PTK en paralelo no tienen ningún incentivo para enviar un parche a IPython / PTK para suavizar el comportamiento.

No lo integraría con un conmutador, porque eso hace que parezca una opción compatible, y la gente presentará errores al respecto aquí. rlipython es menos tipeado que ipython --readline todos modos, y si las personas desean usarlo como ipython , pueden usar un alias.

Solo una nota sobre la experiencia actual de ctrl-r :

En Bash, cuando presionas ctrl-r y luego presionas escapar, te saldrá.

En este no hace nada cuando debería cerrar el área de búsqueda.

Solo una nota sobre la experiencia actual de ctrl-r:
En Bash, cuando presionas ctrl-r y luego presionas escapar, te saldrá.
En este no hace nada cuando debería cerrar el área de búsqueda.

Este es fácil de arreglar, pero no del todo:

 ~/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)

Eso funcionará, pero el I-search-backward: seguirá estando visible hasta que presione una nueva tecla. Esta nueva clave se comportará como si se descartara la búsqueda hacia atrás, pero se siente extremadamente extraño.

¡Gracias por abrir esto, @ivanov! Voy a repasar los detalles con un poco más de cuidado, también voy a alentar más comentarios sobre esto en la lista. Evidentemente, es un equilibrio complicado y polémico, por lo que es una buena señal de que más voces pueden al menos informar nuestro proceso de decisión.

Solo una actualización sobre el posible camino a seguir para este esfuerzo: en lugar de llevar el código eliminado a IPython propiamente dicho, @Carreau hizo un nuevo proyecto con solo el código antiguo basado en readline en Carreau / rlipython , y creó el # 10373 que permite a los usuarios personaliza esta pieza.

FYI: el problema que se describe en la lista de correo:

Pregunto principalmente porque en SMC al menos, si intenta pegar en múltiples
líneas que pega en la primera línea y silenciosamente ignora todomás . Esto puede ser un problema con el nivel de soporte de xterm en SMC
(es decir, term.js). Sin embargo, es bastante frustrante.

Esto indica que este terminal no admite la pasta entre corchetes.
En mi humilde opinión: Creo que en estos días podemos esperar que cualquier terminal lo admita: https://cirw.in/blog/bracketed-paste (al menos prompt_toolkit requerirá pegar entre corchetes, para pegar texto de varias líneas).

Podría valer la pena volver a agregar compatibilidad con readline, pero tenga en cuenta que varios de los errores mencionados ya están corregidos o recibirán una corrección. Los problemas más grandes son probablemente el terminal Emacs (que no es realmente un terminal compatible con xterm y nunca será compatible), y el soporte .inputrc que eventualmente vendrá, pero debido a problemas de ancho de banda / prioridad de mi lado, llevará algún tiempo.

En cualquier caso, siga informando problemas relacionados con la experiencia del usuario. Esto es importante.

@pfmoore ese es un buen punto. Dudo que los entornos de Windows se vean perjudicados por la falta de pyreadline. Si recuperamos la interfaz de usuario de readline, probablemente tenga sentido hacer esto solo para readline 'verdadero', ya sea en IPython o en el paquete rlipython .

Una ventaja del paquete rlipython separado es que se puede usar con la versión existente de IPython 5, mientras que hacerlo en IPython obviamente solo funcionaría para las nuevas versiones de IPython.

Me gustaría agregar # 9799 como otra fuente de incomodidad con los valores predeterminados de prompt_toolkit. Estaría perfectamente feliz con un paquete externo adicional para instalar.

pyreadline es un problema en Windows, pero el kit de herramientas prompt también tiene problemas. Entonces, entre 2 soluciones insatisfactorias, la solución con menos "deuda técnica" parece la mejor solución: el kit de herramientas rápido.

Creo que el punto es que prompt_toolkit es mejor para algunas personas y readline es mejor para otras. Entonces, la pregunta es, ¿es necesario eliminar a la gente de readline para evitar mantener el código adicional?

pyreadline es un problema en Windows, pero el kit de herramientas prompt también tiene problemas. Entonces, entre 2 soluciones insatisfactorias, la solución con menos "deuda técnica" parece la mejor solución: el kit de herramientas rápido.

Creo que el punto es que prompt_toolkit es mejor para algunas personas y readline es mejor para otras. Entonces, la pregunta es, ¿es necesario eliminar a la gente de readline para evitar mantener el código adicional?

Tenga en cuenta que en este momento el PR adjunto (# 10373) es de 4 líneas, y es solo una opción de configuración para convertirlo en una opción de configuración. El código de readline ni siquiera estaría en IPython y sería una extensión.

La verdadera pregunta es:

  • R: ¿Está bien si readline-ipython es un ejecutable separado con una ortografía diferente?
  • B: O para secuencias de comandos y extensiones que se envían a IPython (emacs, por ejemplo), en caso de que sea una opción de configuración de IPython.

En ambos casos, readline no volverá a ser una dependencia de IPython.

Influye en un par de funcionalidades que son más simples de mantener en IPython, pero el argumento principal en este momento es A o B.

Desde el lado de emacs, cualquiera de los dos está bien. B parece más flexible a largo plazo.

Supongo que, para aquellos de nosotros que preferimos readline, también querríamos que readline para IPython se derrumbara, así que B.

He estado pensando en esto por un tiempo y hablando con algunas personas del equipo con el que tuve la oportunidad de participar en persona. Aquí está mi opinión sobre el asunto. Todavía no estoy llamando a una decisión final, pero estoy tratando de acercarnos a una resolución. Por cierto, quiero enfatizar que estoy muy agradecido con el equipo de Prompt Toolkit, ya que nos ha brindado en la gran mayoría de los casos una experiencia de usuario increíble, moderna y de alta calidad. Pasando al asunto que nos ocupa:

  • las preocupaciones de los usuarios que necesitan readline son muy reales, y creo que deberíamos encontrar una buena solución para ellos ahora, incluso si el costo es llevar algún código adicional en / alrededor de IPython.

  • Continuaremos trabajando con el equipo de PT para mejorarlo hacia la paridad de características con readline donde eso es un problema (soy consciente de que tiene una amplia colección de características que RL no tiene).

  • Incluso si el PT mejora aún más, todavía puedo ver situaciones en las que la línea de lectura simple será valiosa. PT, en virtud de su sofisticación, es probable que sea más lento o más frágil cuando se ejecuta dentro de tmux sobre ssh dentro de un shell ipython dentro de Emacs. Ese es un caso de uso válido que deberíamos soportar bien, y que solíamos hacerlo.

Ante esto, creo que una buena solución de compromiso está en la línea de lo que @Carreau ha propuesto en su PR:

  • admitimos readline, pero solo a través de un paquete de terceros que el usuario debe instalar manualmente.

  • el usuario puede entonces establecer el uso de este paquete en su archivo de configuración, llamarlo en la línea de comandos o escribir un alias de shell o un pequeño script de envoltura. Sí, esto requiere un poco de trabajo adicional por parte de los usuarios de este estuche de esquina, pero les brinda una solución limpia a un costo mínimo, mientras que la mayoría de los usuarios que pueden usar PT (y beneficiarse de sus características) continúan haciéndolo ininterrumpidamente. .

Esto significa admitir por un tiempo este paquete adicional, pero no imagino que será tanto trabajo: ese código apenas cambió en bastante tiempo, y no estamos hablando de agregar muchas características nuevas. Simplemente manteniendo la compatibilidad con el comportamiento de referencia histórico existente.

El único costo que veo como algo significativo es que (mencionado por @Carreau) puede haber un código que nos gustaría eliminar y que esto evitaría que lo eliminemos. Veo que es un precio que deberíamos pagar en beneficio de nuestros usuarios, al menos por ahora. Si en algún momento futuro nos encontramos realmente en una situación en la que PT es un reemplazo del 100% para RL en todos los casos imaginables, podemos volver a visitarlo. Pero por ahora, mantener un poco de código obsoleto y de propósito especial para el beneficio de algún subconjunto de nuestros usuarios es lo correcto. A lo largo de los años, hemos tenido varios tipos de códigos de casos especiales (windows, py2 / 3, etc.) y estoy seguro de que los volveremos a tener en el futuro. Servir a los flujos de trabajo de nuestros usuarios debería, creo, tener prioridad sobre una limpieza de código (en esta situación, no hacer una declaración general).

¿Como suena esto?

Por cierto, creo que esta 'solución' debería ser retroportada a la serie 5.x: en todo caso, sospecho que la población de usuarios que todavía usa python 2.x tiene una buena superposición con la de las personas que trabajan de forma remota en servidores más antiguos. Entonces mi voto sería hacer que el paquete externo sea compatible con Python 2-3, y volver a exportar el lado ipython del código a 5.x.

Gracias Fernando por tomarse el tiempo para responder, y especialmente por llegar a varias personas.
Trabajaré en pulir mi PR, fusionarlo y retrocederlo a 5.0.

Tengo rlipython en GitHub para cualquiera que esté interesado en mantener la interfaz readline. No lo mantendré ni lo publicaré en PyPI, pero puede hacerlo, y podría ser bueno moverlo a https://github.com/ipython-contrib si necesita una organización. .

Gracias !

De hecho, creo que deberíamos alojar esto en la organización principal de IPython y ponerlo en pypi. También podemos enviar un mensaje un poco más acogedor a la comunidad, en la línea de:

esto es algo que ofrecemos para respaldar la compatibilidad histórica y ciertos casos de uso específicos en los que nuestra interfaz principal (kit de herramientas de solicitud) no es la óptima. Pero no prevemos ningún desarrollo significativo más allá de corregir errores críticos. Solo tenemos los recursos para ofrecer esto como una solución de mejor esfuerzo. Si está interesado en realizar un desarrollo significativo en esta herramienta, háganoslo saber a través de un problema y podemos explorar la posibilidad de transferirle el mantenimiento del paquete ".

Si @ivanov tiene algunos ciclos para poner en esta dirección, sería genial, pero si no, estoy dispuesto a hacerlo en las próximas semanas. Creo que es una parte importante de interactuar con todos los rincones de nuestra comunidad de usuarios.

¡Gracias @Carreau por

Gracias a todos, especialmente a @Carreau por rlipython . Empecé a trabajar en él y a darle forma. En caso de que alguien se lo haya perdido, ahora vive bajo ipython / rlipython . Intentaré publicar un lanzamiento en las próximas dos semanas cuando empiece a trabajar con él, ¡pero por ahora puedo decir que funciona! Hay un problema conocido en este momento: las indicaciones de entrada / salida no están coloreadas, lo que estoy rastreando en ipython / rlipython # 3, pero aparte de eso, parece genial.

@ivanov ,

Cerrado por # 10373 y respaldado como # 10463

Hola, con este problema cerrado, ¿hay alguna forma de deshabilitar prompt_toolkit completo?

Hola, con este problema cerrado, ¿hay alguna forma de deshabilitar el prompt_toolkit por completo?

sí, si configura TerminalIPythonApp.interactive_shell_class en rlipython en su archivo de configuración, entonces prompt_toolkit ni siquiera debería ser importado. El archivo Léame de rlipython brinda más información sobre cómo hacer esto.

Para cualquiera que todavía esté suscrito a este tema: Acabo de lanzar rlipython versión 0.1.0, ahora puede pip install rlipython y hacer que la antigua línea de lectura funcione de forma predeterminada en IPython después de import rlipython; rlipython.install() .

Tarde para la fiesta, pero permítanme reiterar que RT en la actualidad es un no-no para proyectos que tienen módulos que no están diseñados para inicialización multiproceso, vea el boleto 22766 de Sage. (Y esta es la razón principal por la que necesitamos hacer algo al respecto en Sage).

Además, un comentario sobre un problema general con el RT actual: desencadena la importación de múltiples subprocesos de módulos de Python mientras se completa la pestaña. Dudamos mucho que sea seguro.

Por último, pero no menos importante, dado que la finalización de la pestaña de IPython causa segfaults, ¿qué tal un medio para realizar pruebas no interactivas?

@jonathanslenders, ¿ se ha encontrado con algún problema con la finalización que se ejecuta en un hilo separado? ¿Existe una opción para que se ejecute sincrónicamente?

Hola @takluyver ,

Disculpe la tardía respuesta. Me casé el mes pasado, así que he estado desconectado por un tiempo. ;)

Estoy trabajando en prompt_toolkit 2.0, que ya admite la finalización sincrónica (en el hilo principal) y asincrónica (en otro hilo). He estado trabajando en 2.0 durante casi un año y espero lanzarlo en un par de meses.

Para la finalización sincrónica, debe tener en cuenta que si el finalizador no es muy rápido, esto introducirá un retraso después de cada pulsación de tecla (si ha activado la función de completar mientras escribe). Creo que Jedi, por ejemplo, no es súper rápido.

Sé que ciertas bibliotecas tienen algunos problemas con la finalización asincrónica. Creo que deberíamos animar a los autores de estas bibliotecas a asegurarse de que, en primer lugar, se puedan importar desde cualquier hilo. En el futuro, lo convertiría en una opción para ejecutar la sincronización de compleciones o async, pero aún prefiero tener la finalización async de forma predeterminada. Hace que la experiencia del usuario sea mucho más agradable.

El sábado 21 de octubre de 2017 a las 2:47 p.m., Jonathan Slenders < [email protected]

escribió:

Sé que ciertas bibliotecas tienen algunos problemas con asincrónica
terminación. Creo que deberíamos animar a los autores de estas bibliotecas a
asegúrese de que la importación en primer lugar se puede hacer desde cualquier
hilo.

En mi humilde opinión, es una ilusión que esto siempre sea fácil de lograr.
Hay bibliotecas de Python que básicamente están envolviendo muy complejas en tercer lugar.
código de fiesta, y los cambios necesarios para la inicialización segura para subprocesos deben ser
hecho aguas arriba.
Un ejemplo concreto nos estamos golpeando la cabeza
Maxima se ejecuta en un ECL del sistema Lisp (incrustado en Python).
Este último, como todos los Lisps, necesita un recolector de garbade, y está usando BoehmGC . En algunas plataformas, este último debe ser
inicializado en el hilo principal --- o solía ser el caso, por ejemplo, para
FreeBSD, hasta que lo señalé, y se solucionó rápidamente . Como puedes imaginar, en otros
casos en los que uno podría no tener suerte con una solución de este tipo, ya que necesitaba un experto
conocimiento de un sistema bastante complicado.

Y hay varios problemas por resolver, uno de los cuales es que en un
Escenario de un solo subproceso, una biblioteca puede hacer su propio manejo de señales, mientras que
en un escenario de subprocesos múltiples, el manejo de la señal debe estar centralizado. los
otro, aún más difícil de resolver, es que ese código de terceros podría no ser
a salvo de amenazas.
(volviendo al ejemplo anterior, vemos todo esto ...)

Parece que la mejor opción sería
para que PT haga todas las importaciones en el hilo principal --- no tengo ni idea de si
sin embargo, es fácil o incluso factible de implementar.

Finalmente, permítame señalar que, en efecto, PT realiza una importación multiproceso.
Como la importación es un cuello de botella de inicio para sistemas grandes, es muy
tentador permitir la importación multiproceso.
Realmente me gustaría escuchar lo que diría la gente de CPython al respecto; I
No se sorprenderá si la respuesta fuera que no debe hacerse.

PD. No pretendo arruinar tu luna de miel, felicitaciones :-)

¡Felicidades! Por supuesto, no hay necesidad de disculparse: obtenemos su increíble biblioteca de forma gratuita, por lo que cualquier soporte debe ser cuando sea conveniente para usted. Mis mejores deseos para usted y su pareja.

Creo que es probable que cambiemos a finalizaciones sincrónicas cuando estén disponibles. No usamos completar a medida que escribe, porque habilitamos la función de búsqueda de historial que es mutuamente excluyente con eso.

¿Fue útil esta página
0 / 5 - 0 calificaciones