Ipython: Rétablir la capacité de lecture ?

Créé le 1 mars 2017  ·  38Commentaires  ·  Source: ipython/ipython

Même si ce n'est pas ce qui est utilisé par défaut, j'ai connu et entendu parler de suffisamment d'autres personnes éprouvant des difficultés avec l'entrée basée sur prompt_toolkit interrompant les flux de travail des personnes, que je pense que nous devrions sérieusement envisager de ramener ce code.

Je pense que c'était une erreur de le supprimer complètement et de changer la valeur par défaut en même temps.

  • discussion récente sur la liste de diffusion Sage à ce sujet
  • #9816 a plusieurs utilisateurs signalant une rupture
  • il y a plusieurs utilisateurs qui ont mis en place une boîte à outils rapide ayant des régressions par rapport à readline dans # 9388
  • et de même #10075 contient le sentiment d'un utilisateur disant ceci: "L'édition multiligne est une fonctionnalité très intéressante. En tant qu'utilisateur de longue date de vim et bash, le passage à IPython 5.x et prompt_toolkit a été choquant."
  • #10085 répertorie une limitation et une incohérence de prompt_toolkit qui ne seront pas traitées en amont .
  • # 9944 est un autre problème qui est survenu avec la transition prompt-toolkit, qui fonctionnait dans l'ancien code basé sur readline (bien que je comprenne que Thomas a récemment proposé un correctif pour cela dans #10185, il y a une discussion sur les limitations de cela, trop).
  • #10211 est un utilisateur d'emacs affecté par un changement qui, pour autant que je sache, est également attribuable à la transition vers la boîte à outils rapide.
  • #10315 est une autre rupture inattendue dans IPython 5, car prompt_toolkit utilise un thread séparé pour les complétions (alors que les complétions devaient être synchrones dans readline, donc les complétions jpype fonctionnaient bien dans IPython <= 4).
  • #9948 - utilisateur incapable de coller plusieurs lignes à l'aide de tmux.
  • #10071 - Invite manquante au hasard après la mise à niveau vers IPython 5 dans le docker (car la taille du terminal a été signalée comme 0x0)
needs-decision

Commentaire le plus utile

Pour tous ceux qui sont encore abonnés à ce problème : je viens de publier rlipython version 0.1.0, vous pouvez maintenant pip install rlipython et faire fonctionner l'ancienne ligne de lecture par défaut dans IPython après import rlipython; rlipython.install() .

Tous les 38 commentaires

Je suis prêt à faire le travail pour revenir à temps pour la version 6.0, donc je vais marquer le #10329 ici.

Je pense qu'il s'agit d'un problème particulièrement important car les utilisateurs de longue date et les défenseurs d'IPython se sentent frustrés ou même peu disposés à utiliser IPython 5 tel qu'il est actuellement.

Je suis heureux de l'ajouter à nouveau en option, bien que la plupart du code ait été supprimé et que cela demandera probablement beaucoup d'efforts pour réintégrer readline.

Si nous pouvons trouver comment rendre cela facultatif (afin qu'il puisse évoluer plus rapidement que le noyau pour corriger à nouveau les bogues potentiels introduits par la renaissance, ce serait formidable.

Nous voudrons peut-être retarder le #10356 si nous ramenons RL.

Voir aussi #9260.

Et #9399 est le gros de la suppression.

Je suis fortement -1 sur ce point. Nous avons pu supprimer beaucoup de code et de complexité lorsque nous avons abandonné readline (et nous travaillons à en supprimer encore plus), tout en améliorant considérablement l'expérience utilisateur pour la plupart des utilisateurs. Si nous ramenons une option readline, nous avons toute la complexité des deux interfaces à maintenir ~pour toujours. Nous avons toujours su qu'un changement aussi important briserait certains flux de travail, mais je suis convaincu qu'il s'agit d'une nette amélioration et je ne veux pas que nous soyons en train de maintenir deux interfaces de terminal alternatives.

Je préfère que nous :

  1. Continuez à travailler sur tout ce que nous pouvons améliorer à la fois dans IPython et dans prompt_toolkit pour éliminer les obstacles au changement. Jonathan a généralement été incroyablement réactif et utile chaque fois que nous l'avons interrogé sur des problèmes liés à PTK, donc je pense que nous avons de bonnes chances de faire accepter les changements dont nous avons besoin. Cela inclut des choses comme une meilleure documentation sur la façon de définir des raccourcis personnalisés, et peut-être expérimenter la lecture de .inputrc (bien que je préfère que ce soit une option par défaut, pour des raisons que j'ai expliquées ailleurs). Si nous donnons aux gens une option facile pour revenir à readline, ces améliorations ne se produiront pas.
  2. S'il y a encore des gens qui insistent vraiment pour utiliser readline, créez un paquet séparé comme rlipython qui fournit l'interface du terminal, mais indiquez très clairement qu'il est maintenu par la communauté, pas quelque chose que nous soutenons officiellement.

Étant donné qu'il y avait toujours un certain nombre de problèmes avec pyreadline sous Windows (notamment le fait qu'il affectait globalement la norme Python REPL ainsi que IPython), je préférerais que ne pas exiger (py)readline reste la valeur par défaut, à au moins sous Windows. Si un utilisateur préfère installer pyreadline manuellement et l'activer, c'est bien, mais IPython devrait fonctionner sans pyreadline présent et ne pas l'inclure en tant que dépendance d'une installation normale.

S'il y a encore des gens qui insistent vraiment pour utiliser readline, créez un paquet séparé comme rlipython qui fournit l'interface du terminal, mais indiquez très clairement qu'il est maintenu par la communauté, et non quelque chose que nous soutenons officiellement.

Je pense que c'est raisonnable, bien que je pense avoir une certaine intégration (comme un indicateur et/ou une variable d'environnement) avec IPython qui restaure le comportement précédent est raisonnable. L'objectif serait d'avoir des scripts et des recettes déjà bien diffusés qui reposent sur IPython readline fonctionnant toujours avec un simple commutateur.

Je suppose qu'une simple configuration dans IPythonApp, qui oblige la classe TerminalInteractiveShell à utiliser un traitlet, plus un indicateur --readline ayant une valeur prédéfinie pour un package externe connu serait suffisant.

L'ipython en tant que package séparé permettra également de ne pas bloquer IPython 6 et d'obtenir un cycle d'itération rapide si nécessaire.

Si nous donnons aux gens une option facile pour revenir à readline, ces améliorations ne se produiront pas.

Je doute que ce soit tout à fait vrai. La multiligne, la surbrillance et maintenant la complétion sont toujours un grand avantage de l'interface PTK. Et les utilisateurs qui épinglent à 4.x parce qu'ils ne peuvent même pas utiliser les deux RL/PTK en parallèle n'ont aucune incitation à envoyer un correctif à IPython/PTK pour lisser le comportement.

Je ne l'intégrerais pas à un commutateur, car cela le fait ressembler à une option prise en charge, et les gens signaleront des bogues à ce sujet ici. rlipython est de toute façon moins typé que ipython --readline , et si les gens souhaitent l'utiliser comme ipython , ils peuvent l'aliaser.

Juste une note sur l'expérience actuelle de ctrl-r :

Dans Bash, lorsque vous appuyez sur ctrl-r puis sur Échap, cela vous quittera.

Dans celui-ci, il ne fait rien alors qu'il devrait fermer la zone de recherche.

Juste une note sur l'expérience actuelle de ctrl-r :
Dans Bash, lorsque vous appuyez sur ctrl-r puis sur Échap, cela vous quittera.
Dans celui-ci, il ne fait rien alors qu'il devrait fermer la zone de recherche.

Celui-ci est facile à corriger, mais pas totalement :

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

Cela fonctionnera, mais le I-search-backward: sera toujours visible jusqu'à ce que vous appuyiez sur une nouvelle touche. Cette nouvelle clé se comportera comme si la recherche en arrière était rejetée, mais cela semble extrêmement étrange.

Merci d'avoir ouvert ça, @ivanov ! Je vais passer en revue les détails un peu plus attentivement, je vais également encourager plus de commentaires sur la liste à ce sujet. C'est évidemment un équilibre délicat et controversé, donc un bon signe que plus de voix peuvent au moins éclairer notre processus de décision.

Juste une mise à jour sur la voie à suivre pour cet effort : au lieu d'apporter le code supprimé dans IPython proprement dit, @Carreau a créé un nouveau projet avec uniquement l'ancien code basé sur readline sur Carreau/rlipython , et a créé #10373 qui permet aux utilisateurs de personnaliser cette pièce.

Pour info : le problème qui est décrit dans la liste de diffusion :

Je demande principalement parce que dans SMC au moins, si vous essayez de coller plusieurs
lignes qu'il colle dans la première ligne et ignore tout en silenced'autre . Cela peut être un problème avec le niveau de prise en charge de xterm dans SMC
(c'est-à-dire, term.js). Cependant, c'est assez frustrant.

Cela indique que ce terminal ne prend pas en charge le collage entre crochets.
IMHO: Je pense que ces jours-ci, nous pouvons nous attendre à ce que n'importe quel terminal le prenne en charge: https://cirw.in/blog/bracketed-paste (Au moins prompt_toolkit nécessitera un collage entre crochets, pour coller du texte multiligne.)

Cela pourrait valoir la peine d'ajouter à nouveau le support readline, mais notez que plusieurs des bogues mentionnés sont déjà corrigés ou recevront un correctif. Les plus gros problèmes sont probablement le terminal Emacs (qui n'est pas vraiment un terminal compatible xterm et ne sera jamais pris en charge), et le support .inputrc qui finira par arriver, mais en raison de problèmes de bande passante/priorité de mon côté, prendra un certain temps.

Dans tous les cas, continuez à signaler les problèmes d'expérience utilisateur. C'est important.

@pfmoore c'est un bon point. Je douterais que les environnements Windows souffrent du manque de pyreadline. Si nous ramenons l'interface utilisateur de readline, il est probablement logique de le faire uniquement pour la "vraie" ligne de lecture, que ce soit dans IPython ou dans le package rlipython .

L'un des avantages du package rlipython séparé est qu'il peut être utilisé avec la version IPython 5 existante, alors que le faire dans IPython lui-même ne fonctionnerait évidemment que pour les nouvelles versions IPython.

J'aimerais ajouter #9799 comme autre source d'inconfort avec les valeurs par défaut de prompt_toolkit. Je serais parfaitement heureux avec un package externe supplémentaire à installer.

pyreadline est pénible sous Windows, mais prompt-toolkit a également des problèmes. Ainsi entre 2 solutions insatisfaisantes, la solution la moins "dette technique" apparaît comme la meilleure solution : prompt-toolkit.

Je pense que le fait est que prompt_toolkit est meilleur pour certaines personnes et readline est meilleur pour d'autres. Donc la question est, est-il nécessaire de couper les gens readline pour éviter de maintenir le code supplémentaire ?

pyreadline est pénible sous Windows, mais prompt-toolkit a également des problèmes. Ainsi entre 2 solutions insatisfaisantes, la solution la moins "dette technique" apparaît comme la meilleure solution : prompt-toolkit.

Je pense que le fait est que prompt_toolkit est meilleur pour certaines personnes et readline est meilleur pour d'autres. Donc la question est, est-il nécessaire de couper les gens readline pour éviter de maintenir le code supplémentaire ?

Notez qu'à l'heure actuelle, le PR joint (#10373) fait 4 lignes et n'est qu'une option de configuration pour en faire une option de configuration. Le code readline ne serait même pas dans IPython et serait une extension.

La vraie question est :

  • R : Est-il possible que readline-ipython soit un exécutable distinct avec une orthographe différente ?
  • B : Ou pour les scripts et les extensions qui s'intègrent à IPython (emacs par exemple), s'il s'agit d'une option de configuration IPython.

Dans les deux cas, readline ne deviendra plus une dépendance d'IPython.

Cela influence quelques fonctionnalités qui sont plus simples à conserver dans IPython, mais la principale controverse à l'heure actuelle est A ou B.

Du côté d'Emacs, c'est bien. B semble plus flexible sur le long terme.

Je suppose que, pour ceux d'entre nous qui préfèrent readline, nous voudrions également que readline pour IPython s'exécute - donc B.

J'ai réfléchi à celui-ci pendant un certain temps et j'ai parlé à quelques membres de l'équipe avec laquelle j'ai eu la chance de m'engager en personne. Voici mon avis sur la question. Je ne suis pas encore appeler une décision finale, mais je suis en train de nous rapprocher d'une résolution. D'ailleurs, je tiens à souligner que je suis très reconnaissant envers l'équipe Prompt Toolkit, car elle nous a offert dans la grande majorité des cas une expérience utilisateur incroyable, moderne et de haute qualité. Sur le sujet en question :

  • les inquiétudes des utilisateurs qui ont besoin de readline sont très réelles, et je pense que nous devrions trouver une bonne solution pour eux maintenant, même si le coût consiste à transporter du code supplémentaire dans/autour d'IPython.

  • Nous continuerons à travailler avec l'équipe PT pour l'améliorer vers la parité des fonctionnalités avec readline là où c'est un problème (je suis conscient qu'il a une vaste collection de fonctionnalités que RL n'a pas).

  • Même si PT s'améliore encore, je peux toujours voir des situations où l'ancienne ligne de lecture simple sera précieuse. PT, en raison de sa sophistication, est susceptible d'être plus lent ou plus fragile lorsqu'il s'exécute dans tmux sur ssh dans un shell ipython dans Emacs. C'est un cas d'utilisation valable que nous devrions bien prendre en charge, et que nous avions l'habitude de faire.

Compte tenu de cela, je pense qu'une bonne solution de compromis va dans le sens de ce que @Carreau a proposé dans son PR :

  • nous prenons en charge readline mais uniquement via un package tiers qui doit être installé manuellement par l'utilisateur.

  • l'utilisateur peut alors soit définir l'utilisation de ce package dans son fichier de configuration, l'appeler en ligne de commande, soit écrire un alias shell ou un petit script wrapper. Oui, cela nécessite un peu de travail supplémentaire de la part des utilisateurs de ce boîtier d'angle, mais cela leur donne une solution propre à un coût minime, tandis que la majorité des utilisateurs qui peuvent utiliser PT (et bénéficier de ses fonctionnalités) continuent de le faire sans interruption .

Cela signifie prendre en charge pendant un certain temps ce paquet supplémentaire, mais je n'imagine pas que ce sera autant de travail : ce code a à peine changé depuis un certain temps, et nous ne parlons pas d'ajouter beaucoup de nouvelles fonctionnalités. Maintenir simplement la compatibilité avec le comportement de base historique existant.

Le seul coût que je considère comme quelque peu important est que (mentionné par @Carreau) il peut y avoir du code que nous aimerions extraire que cela nous empêcherait de supprimer. Je vois cela comme un prix que nous devrions payer pour le bénéfice de nos utilisateurs, du moins pour l'instant. Si, à un moment donné, nous nous retrouvons vraiment dans une situation où PT remplace à 100% le RL dans tous les cas imaginables, nous pouvons revoir. Mais pour l'instant, garder un peu de code un peu périmé et à usage spécial au profit de certains sous-ensembles de nos utilisateurs est la bonne chose à faire. Au fil des ans, nous avons eu plusieurs types de code pour des cas particuliers (windows, py2/3, etc.) et je suis sûr que nous le ferons à nouveau à l'avenir. Servir les flux de travail de nos utilisateurs devrait, je pense, avoir la priorité sur un nettoyage de code (dans cette situation, ne pas faire de déclaration générale).

Comment ça sonne ?

BTW, je pense que ce "correctif" devrait être rétroporté sur la série 5.x : si quoi que ce soit, je soupçonne que la population d'utilisateurs toujours sur python 2.x a un bon chevauchement avec celle des personnes travaillant à distance sur des serveurs plus anciens. Mon vote serait donc de rendre le package externe compatible avec python 2-3 et de rétroporter le côté ipython du code vers 5.x.

Merci Fernando d'avoir pris le temps de répondre, et surtout d'avoir contacté plusieurs personnes.
Je vais travailler sur le polissage de mon PR, le fusionner et le rétroporter vers 5.0.

J'ai rlipython sur GitHub pour tous ceux qui sont intéressés par la maintenance de l'interface readline. Je ne le maintiendrai pas et ne le publierai pas sur PyPI, mais vous êtes invités à le faire, et ce pourrait être une bonne chose de déplacer cela vers https://github.com/ipython-contrib si vous avez besoin d'une organisation .

Merci !

En fait, je pense que nous devrions héberger cela sur l'organisation IPython principale et le mettre sur pypi. Nous pouvons également envoyer un message un peu plus accueillant à la communauté, du genre :

c'est quelque chose que nous proposons pour prendre en charge la compatibilité historique et certains cas d'utilisation spécifiques où notre interface principale (prompt-toolkit) n'est pas optimale. Mais nous n'envisageons pas de développement significatif au-delà de la correction de bogues critiques. Nous n'avons que les ressources pour proposer cette solution au mieux. Si vous êtes intéressé à faire un développement significatif sur cet outil, veuillez nous le faire savoir via un problème, et nous pourrons explorer le transfert de la maintenance du paquet vers vous."

Si @ivanov a quelques cycles à mettre dans cette direction, ce serait formidable, mais sinon, je suis prêt à le faire au cours des deux prochaines semaines. Je pense que c'est une partie importante de l'engagement avec tous les coins de notre communauté d'utilisateurs.

Merci @Carreau d' avoir poussé le travail jusqu'ici !

Merci à tous, en particulier @Carreau pour avoir rlipython . J'ai commencé à travailler dessus et à le mettre en forme. Au cas où quelqu'un l'aurait manqué, il vit maintenant sous ipython/rlipython . J'essaierai de sortir une version dans les deux prochaines semaines au fur et à mesure que je commencerai à travailler dessus, mais pour l'instant je peux dire que ça marche ! Il y a un problème connu en ce moment - les invites d'entrée/sortie ne sont pas colorées, que je suis en train de suivre dans ipython/rlipython#3, mais à part ça, cela semble génial.

@ivanov ,

Fermé par #10373 et rétroporté comme #10463

Bonjour, avec ce problème résolu, existe-t-il un moyen de désactiver complètement prompt_toolkit ?

Bonjour, avec ce problème résolu, existe-t-il un moyen de désactiver complètement prompt_toolkit ?

oui, si vous définissez le TerminalIPythonApp.interactive_shell_class sur rlipython dans votre fichier de configuration, alors prompt_toolkit ne devrait même pas être importé. Le fichier readme de rlipython donne plus d'informations sur la façon de procéder.

Pour tous ceux qui sont encore abonnés à ce problème : je viens de publier rlipython version 0.1.0, vous pouvez maintenant pip install rlipython et faire fonctionner l'ancienne ligne de lecture par défaut dans IPython après import rlipython; rlipython.install() .

En retard à la fête, mais permettez-moi de réitérer que RT à l'heure actuelle est un non-non pour les projets qui ont des modules non conçus pour une initialisation multithread, voir le ticket de Sage

De plus, un commentaire sur un problème général avec le RT actuel : il déclenche l'importation multi-thread de modules Python tout en effectuant la complétion par tabulation. Nous doutons fort qu'il soit sûr.

Dernier point mais non le moindre - étant donné que l'achèvement de l'onglet IPython provoque des erreurs de segmentation, que diriez-vous d'un moyen de le tester non interactif ?

@jonathanslenders avez-vous rencontré des problèmes d'exécution dans un fil distinct ? Existe-t-il une option pour le faire fonctionner de manière synchrone?

Salut @takluyver ,

Excusez-moi pour la réponse tardive. Je me suis marié le mois dernier et je suis donc hors ligne depuis un moment. ;)

Je travaille sur prompt_toolkit 2.0 qui prend déjà en charge la complétion synchrone (dans le thread principal) et asynchrone (dans un autre thread). Je travaille sur 2.0 depuis presque un an et j'espère le sortir dans quelques mois.

Pour la complétion synchrone, vous devez garder à l'esprit que si le compléteur n'est pas très rapide, cela introduira un délai après chaque frappe de touche (si vous avez terminé pendant la frappe). Je crois que Jedi par exemple n'est pas super rapide.

Je sais que certaines bibliothèques ont des problèmes avec l'achèvement asynchrone. Je pense que nous devrions encourager les auteurs de ces bibliothèques à s'assurer que leur importation en premier lieu peut être effectuée à partir de n'importe quel fil. À l'avenir, je ferais une option pour exécuter la synchronisation ou l'async des achèvements, mais je préfère toujours que l'achèvement asynchrone par défaut. Cela rend l'expérience utilisateur tellement plus agréable.

Le sam. 21 oct. 2017 à 14:47, Jonathan Slenders < [email protected]

a écrit:

Je sais que certaines bibliothèques ont des problèmes avec l'asynchrone
achèvement. Je pense que nous devrions encourager les auteurs de ces bibliothèques à
assurez-vous que l'importation en premier lieu peut être effectuée à partir de n'importe quel
fil.

À mon humble avis, c'est un vœu pieux que cela est toujours facile à réaliser.
Il existe des bibliothèques Python qui enveloppent essentiellement des 3èmes très complexes
code de partie, et les modifications nécessaires pour l'initialisation thread-safe doivent être
fait en amont.
Un exemple concret on se tape la tête
est Maxima exécuté dans un système Lisp (intégré dans Python) ECL.
Ce dernier, comme tous les Lisps, a besoin d'un collecteur de déchets, et il utilise BoehmGC . Sur certaines plateformes, ce dernier doit être
initialisé dans le thread principal --- ou c'était le cas, par exemple pour
FreeBSD, jusqu'à ce que je le signale, et cela a été rapidement corrigé . Comme vous pouvez l'imaginer, dans d'autres
cas, on pourrait être totalement malchanceux avec un tel correctif, car il fallait un expert
connaissance d'un système assez compliqué.

Et il y a plusieurs problèmes à résoudre, dont l'un est que dans un
scénario monothread, une bibliothèque peut faire sa propre gestion du signal, alors que
dans un scénario multithread, la gestion du signal doit être centralisée. Les
autre, encore plus difficile à résoudre, est que ce code tiers pourrait ne pas être
thread-safe.
(en revenant à l'exemple ci-dessus, on voit tout ça...)

Il semble que la meilleure option serait
pour que PT fasse toutes les importations dans le thread principal --- je ne sais pas si
c'est facile ou même faisable à mettre en œuvre, cependant.

Enfin, permettez-moi de souligner qu'en fait, PT effectue une importation multithread.
L'importation étant un goulot d'étranglement au démarrage pour les systèmes de grande taille, il est très
tentant d'autoriser l'importation multithread.
J'aimerais vraiment entendre ce que les gens de CPython en diraient ; je
ne sera pas surpris si la réponse était qu'il ne faut pas le faire.

PS. Je ne veux pas gâcher ta lune de miel, félicitations :-)

Toutes nos félicitations! Bien sûr, il n'y a pas besoin de s'excuser - nous obtenons votre bibliothèque géniale gratuitement, donc tout support doit être comme et quand cela vous convient. Meilleurs voeux à vous et votre partenaire.

Je pense que nous passerons probablement aux complétions synchrones lorsqu'elles seront disponibles. Nous n'utilisons pas la saisie complète, car nous activons la fonction de recherche d'historique qui s'exclut mutuellement.

Cette page vous a été utile?
0 / 5 - 0 notes