Ipython: Trazer de volta a capacidade de leitura?

Criado em 1 mar. 2017  ·  38Comentários  ·  Fonte: ipython/ipython

Mesmo que não seja o que é usado por padrão, já experimentei e ouvi falar de muitas outras pessoas que estão enfrentando problemas com a entrada baseada em prompt_toolkit interrompendo os fluxos de trabalho das pessoas, que acho que devemos considerar seriamente trazer esse código de volta.

Acho que foi um erro removê-lo completamente e alterar o padrão ao mesmo tempo.

  • discussão recente na lista de discussão Sage sobre este
  • # 9816 tem vários usuários relatando quebra
  • vários usuários trouxeram o kit de ferramentas de prompt com regressões em comparação com readline em # 9388
  • e da mesma forma # 10075 contém o sentimento de um usuário dizendo o seguinte: "A edição multilinha é um recurso muito bom. Como um usuário de longa data do vim e do bash, a mudança para IPython 5.xe prompt_toolkit foi chocante."
  • # 10085 lista uma limitação e inconsistência do prompt_toolkit que não será tratada no upstream .
  • # 9944 é outro problema que surgiu com a transição prompt-toolkit, que costumava funcionar em código baseado em readline antigo, (embora eu entenda que Thomas propôs recentemente uma correção para isso em # 10185, há uma discussão lá sobre as limitações disso, também).
  • # 10211 é um usuário do emacs afetou uma mudança que, pelo que posso dizer, também é atribuível à transição para o kit de ferramentas prompt.
  • # 10315 é outra quebra inesperada no IPython 5, porque o prompt_toolkit usa um thread separado para conclusões (enquanto as conclusões tinham que ser síncronas em readline, então as conclusões jpype funcionavam bem no IPython <= 4).
  • # 9948 - o usuário não consegue colar várias linhas usando o tmux.
  • # 10071 - prompt ausente aleatoriamente após a atualização para IPython 5 dentro do docker (porque o tamanho do terminal foi relatado como 0x0)
needs-decision

Comentários muito úteis

Para qualquer um que ainda esteja inscrito neste problema: Acabei de lançar rlipython versão 0.1.0, agora você pode pip install rlipython e fazer com que a linha de leitura antiga funcione por padrão no IPython depois de import rlipython; rlipython.install() .

Todos 38 comentários

Estou disposto a fazer o trabalho para conseguir isso de volta a tempo para 6.0, então marcarei # 10329 aqui.

Acho que esta é uma questão particularmente importante porque os usuários de longa data e defensores do IPython estão se sentindo frustrados ou mesmo sem vontade de usar o IPython 5 como está agora.

Estou feliz em adicionar isso de volta como uma opção, embora a maior parte do código tenha sido removida e isso provavelmente representará muitos esforços para reintegrar o readline.

Se pudermos descobrir como tornar isso opcional (para que possa evoluir mais rápido do que o núcleo para consertar o bug em potencial que foi introduzido pelo revival, isso seria ótimo.

Podemos querer atrasar # 10356 se trouxermos RL de volta.

Veja # 9260 também.

E # 9399 é a maior parte da remoção.

Estou fortemente -1 nisso. Conseguimos eliminar muitos códigos e complexidade quando abandonamos o readline (e estamos trabalhando para eliminar ainda mais), ao mesmo tempo em que melhoramos drasticamente a experiência do usuário para a maioria dos usuários. Se trouxermos de volta uma opção readline, teremos toda a complexidade de ambas as interfaces para manter para sempre. Sempre soubemos que uma mudança tão grande interromperia alguns fluxos de trabalho, mas estou confiante de que é uma melhoria líquida e não quero que estejamos no negócio de manter duas interfaces de terminal alternativas.

Eu prefiro que nós:

  1. Continue a trabalhar em qualquer coisa que possamos melhorar no IPython e no prompt_toolkit para remover obstáculos à troca. Em geral, Jonathan tem sido muito responsivo e útil sempre que enviamos um ping para ele sobre problemas relacionados ao PTK, então acho que temos uma boa chance de conseguir que as alterações de que precisamos sejam aceitas. Isso inclui coisas como documentar melhor como definir atalhos personalizados e talvez experimentar a leitura de .inputrc (embora eu prefira que seja uma opção desativada por padrão, por motivos que expliquei em outro lugar). Se dermos às pessoas uma opção fácil de voltar ao readline, essas melhorias não acontecerão.
  2. Se ainda houver pessoas que realmente insistem em usar readline, crie um pacote separado como rlipython que fornece a interface do terminal, mas deixe bem claro que é mantida pela comunidade, não algo que apoiamos oficialmente.

Dado que sempre houve uma série de problemas com pyreadline no Windows (não menos importante, o fato de que afetou globalmente o REPL padrão do Python, bem como o IPython), prefiro que não exigir (py) readline permaneça o padrão, em pelo menos no Windows. Se um usuário preferir instalar o pyreadline manualmente e ativá-lo, tudo bem, mas o IPython deve funcionar sem o pyreadline presente e não incluí-lo como uma dependência de uma instalação normal.

Se ainda houver pessoas que realmente insistem em usar readline, crie um pacote separado como rlipython, que fornece a interface de terminal, mas deixe bem claro que é mantido pela comunidade, não algo que estamos oficialmente apoiando.

Eu acho que é razoável, embora eu acredite que alguma integração (como um sinalizador e / ou uma variável env) com IPython que restaure o comportamento anterior seja razoável. O objetivo seria ter scripts e receitas bem difundidos que dependem do readline do IPython ainda funcionando com um switch simples.

Meu palpite é que uma configuração simples em IPythonApp, que faz a classe TerminalInteractiveShell usar um traitlet, mais um sinalizador --readline que tem um valor predefinido para um pacote externo conhecido seria o suficiente.

O ipython como um pacote separado também permitirá não bloquear o IPython 6 e obter um ciclo de iteração rápido, se necessário.

Se dermos às pessoas uma opção fácil de voltar ao readline, essas melhorias não acontecerão.

Duvido que isso seja totalmente verdade. A multilinha, o destaque e agora a conclusão ainda são uma grande vantagem da interface PTK. E os usuários que estão fixando no 4.x porque não conseguem nem usar o RL / PTK em paralelo não têm incentivo para enviar patch para IPython / PTK para suavizar o comportamento.

Eu não o integraria a um switch, porque isso faz com que pareça uma opção com suporte, e as pessoas irão arquivar bugs sobre isso aqui. rlipython é menos digitado do que ipython --readline qualquer maneira, e se as pessoas quiserem usá-lo como ipython , eles podem criar um atalho para ele.

Apenas uma observação sobre a experiência atual de ctrl-r :

No Bash, quando você pressiona ctrl-r e escape, você sai de lá.

Neste não faz nada quando deveria fechar a área de busca.

Apenas uma observação sobre a experiência atual de ctrl-r:
No Bash, quando você pressiona ctrl-r e escape, você sai de lá.
Neste não faz nada quando deveria fechar a área de busca.

Este é fácil de consertar, mas não totalmente:

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

Isso funcionará, mas I-search-backward: ainda estará visível até que você pressione uma nova tecla. Essa nova chave se comportará como se a pesquisa para trás fosse descartada, mas é extremamente estranho.

Obrigado por abrir isso, @ivanov! Vou repassar os detalhes com um pouco mais de cuidado e também encorajar mais comentários sobre isso na lista. É evidentemente um equilíbrio complicado e contencioso, portanto, um bom sinal de que mais vozes podem, pelo menos, informar nosso processo de decisão.

Apenas uma atualização sobre o possível caminho a seguir para este esforço: em vez de trazer o código removido para o IPython adequado, @Carreau fez um novo projeto apenas com o código baseado em readline antigo em Carreau / rlipython , e fez o # 10373, que permite aos usuários personalize esta peça.

Para sua informação: o problema descrito na lista de e-mails:

Eu pergunto principalmente porque no SMC pelo menos, se você tentar colar em vários
linhas que cola na primeira linha e silenciosamente ignora tudomais . Isso pode ser um problema com o nível de suporte xterm no SMC
(ou seja, term.js). No entanto, é muito frustrante.

Isso indica que este terminal não suporta pasta entre colchetes.
IMHO: Acho que atualmente podemos esperar de qualquer terminal para suportá-lo: https://cirw.in/blog/bracketed-paste (pelo menos prompt_toolkit exigirá colagem entre colchetes, para colar texto de várias linhas).

Pode valer a pena adicionar suporte readline novamente, mas observe que vários dos bugs mencionados já foram corrigidos ou receberão uma correção. Os maiores problemas são provavelmente o terminal Emacs (que não é realmente um terminal compatível com xterm e nunca será suportado) e o suporte .inputrc que virá eventualmente, mas devido a problemas de largura de banda / prioridade da minha parte, levará algum tempo.

Em qualquer caso, continue relatando problemas de experiência do usuário. Isso é importante.

@pfmoore, esse é um bom ponto. Eu duvido que qualquer ambiente Windows esteja sofrendo com a falta de pyreadline. Se trouxermos de volta a IU readline, provavelmente faz sentido fazer isso apenas para 'true' readline, seja no IPython ou no pacote rlipython .

Uma vantagem do pacote rlipython separado é que ele pode ser usado com a versão existente do IPython 5, ao passo que fazê-lo no próprio IPython obviamente só funcionaria para novas versões do IPython.

Eu gostaria de adicionar # 9799 como outra fonte de desconforto com os padrões do prompt_toolkit. Eu ficaria perfeitamente feliz com um pacote externo extra para instalar.

pyreadline é uma dor no Windows, mas o prompt-toolkit também tem problemas. Portanto, entre 2 soluções insatisfatórias, a solução com menos "débito técnico" parece ser a melhor solução: prompt-toolkit.

Acho que o ponto é que prompt_toolkit é melhor para algumas pessoas e readline é melhor para outras. Portanto, a questão é: é necessário eliminar o pessoal da linha de leitura para evitar a manutenção do código extra?

pyreadline é uma dor no Windows, mas o prompt-toolkit também tem problemas. Portanto, entre 2 soluções insatisfatórias, a solução com menos "débito técnico" parece ser a melhor solução: prompt-toolkit.

Acho que o ponto é que prompt_toolkit é melhor para algumas pessoas e readline é melhor para outras. Portanto, a questão é: é necessário eliminar o pessoal da linha de leitura para evitar a manutenção do código extra?

Observe que agora o PR anexado (# 10373) tem 4 linhas e é apenas uma opção de configuração para torná-lo uma opção de configuração. O código readline nem mesmo estaria em IPython e seria uma extensão.

A verdadeira questão é:

  • R: Tudo bem se readline-ipython for um executável separado com uma grafia diferente.
  • B: Ou para script e extensões que enviam para IPython, (emacs por exemplo), deve ser uma opção de configuração IPython.

Em ambos os casos, readline não se tornará uma dependência do IPython novamente.

Ele influencia algumas funcionalidades que são mais simples de manter no IPython, mas a principal controvérsia agora é A ou B.

Do lado do emacs, qualquer um está bem. B parece mais flexível no longo prazo.

Eu acho que, para aqueles de nós que preferem readline, gostaríamos de ler readline para IPython shelling também - então B.

Tenho pensado nisso há um tempo e conversado com algumas pessoas da equipe com quem tive a chance de interagir pessoalmente. Aqui está minha opinião sobre o assunto. Ainda não estou chamando uma decisão final, mas estou tentando nos aproximar de uma resolução. Aliás, quero enfatizar que sou muito grato à equipe do Prompt Toolkit, pois ela nos proporcionou, na grande maioria dos casos, uma experiência de usuário incrível, moderna e de alta qualidade. Sobre o assunto em questão:

  • as preocupações dos usuários que precisam do readline são muito reais e acho que devemos encontrar uma boa solução para eles agora, mesmo que o custo seja carregar algum código extra no / em torno do IPython.

  • Continuaremos trabalhando com a equipe PT para melhorá-lo em termos de paridade de recursos com readline onde isso é um problema (estou ciente de que tem uma vasta coleção de recursos que RL não tem).

  • Mesmo que o PT melhore ainda mais, ainda posso ver situações em que o velho readline será valioso. PT, em virtude de sua sofisticação, é provável que seja mais lento ou mais frágil quando executado dentro do tmux sobre ssh dentro de um shell ipython dentro do Emacs. Esse é um caso de uso válido que deveríamos suportar bem, e que costumava ser.

Diante disso, acho que uma boa solução de compromisso segue as linhas do que @Carreau propôs em seu PR:

  • oferecemos suporte ao readline, mas apenas por meio de um pacote de terceiros que deve ser instalado manualmente pelo usuário.

  • o usuário pode então definir o uso deste pacote em seu arquivo de configuração, chamá-lo na linha de comando ou escrever um alias de shell ou script de wrapper minúsculo. Sim, isso requer um pouco de trabalho extra por parte dos usuários deste caso, mas dá a eles uma solução limpa a um custo mínimo, enquanto a maioria dos usuários que podem usar o PT (e se beneficiar de seus recursos) continuam fazendo isso sem interrupções .

Isso significa dar suporte por um tempo a esse pacote extra, mas não imagino que vá dar tanto trabalho: esse código quase não mudou por um bom tempo, e não estamos falando sobre adicionar muitos recursos novos. Simplesmente mantendo a compatibilidade com o comportamento da linha de base histórica existente.

O único custo que considero um tanto significativo é que (mencionado por @Carreau) pode haver código que gostaríamos de extrair e que isso nos impediria de remover. Eu vejo isso como um preço que devemos pagar em benefício de nossos usuários, pelo menos por enquanto. Se, em algum momento futuro, realmente nos encontrarmos em uma situação em que o PT é um substituto 100% para RL em todos os casos imagináveis, podemos revisitar. Mas, por enquanto, manter um pouco de código um pouco desatualizado para fins especiais para o benefício de algum subconjunto de nossos usuários é a coisa certa a fazer. Ao longo dos anos, tivemos vários tipos de código de caso especial (windows, py2 / 3, etc.) e tenho certeza de que o faremos novamente no futuro. Atender os fluxos de trabalho de nossos usuários deve, eu acho, ter prioridade sobre uma limpeza de código (nesta situação, não fazer uma declaração geral).

Como isso soa?

BTW, acho que essa 'correção' deve ser retransmitida para a série 5.x: se houver alguma coisa, eu suspeito que a população de usuários ainda no python 2.x tem uma boa sobreposição com a de pessoas que trabalham remotamente em servidores mais antigos. Portanto, meu voto seria para tornar o pacote externo compatível com python 2-3 e fazer backport do lado ipython do código para 5.x.

Obrigado Fernando por dedicar seu tempo para responder e, especialmente, por alcançar várias pessoas.
Vou trabalhar no polimento do meu PR, mesclá-lo e retrocedê-lo para 5.0.

Eu fiz rlipython no GitHub para qualquer pessoa interessada em manter a interface readline. Não vou manter e não vou publicá-lo no PyPI, mas você está convidado a fazê-lo, e pode ser uma boa coisa mover isso para https://github.com/ipython-contrib se você precisar de uma organização .

Obrigado !

Na verdade, acho que devemos hospedar isso na organização IPython principal e colocá-lo no pypi. Também podemos enviar uma mensagem um pouco mais acolhedora para a comunidade, nos moldes de:

isso é algo que oferecemos em suporte de compatibilidade histórica e certos casos de uso específicos em que nossa interface principal (prompt-toolkit) não é a ideal. Mas não prevemos nenhum desenvolvimento significativo além da correção de bugs críticos. Só temos os recursos para oferecer isso como uma solução de melhor esforço. Se você estiver interessado em fazer qualquer desenvolvimento significativo nesta ferramenta, informe-nos através de um problema, e podemos explorar a transferência da manutenção do pacote para você. "

Se @ivanov tiver alguns ciclos para colocar nessa direção, seria ótimo, mas, do contrário, estou disposto a fazer isso nas próximas semanas. Acho que é uma parte importante do envolvimento com todos os cantos de nossa comunidade de usuários.

Obrigado @Carreau por levar o trabalho tão longe!

Obrigado a todos, especialmente @Carreau por rlipython . Comecei a trabalhar nisso e colocá-lo em forma. Caso alguém tenha perdido, ele agora está sob ipython / rlipython . Tentarei lançar um lançamento nas próximas duas semanas quando começar a trabalhar com ele, mas por enquanto posso dizer que funciona! Há um problema conhecido agora - os prompts de entrada / saída não estão sendo coloridos, o que estou rastreando no ipython / rlipython # 3, mas fora isso, parece ótimo.

@ivanov , me diga isso se quiser uma

Fechado por # 10373 e portado como # 10463

Olá, com este problema encerrado, existe alguma maneira de desativar prompt_toolkit completamente?

Olá, com este problema encerrado, existe alguma maneira de desativar o prompt_toolkit completamente?

sim, se você definir TerminalIPythonApp.interactive_shell_class como rlipython em seu arquivo de configuração, o prompt_toolkit nem deve ser importado. O readme de rlipython fornece mais informações sobre como fazer isso.

Para qualquer um que ainda esteja inscrito neste problema: Acabei de lançar rlipython versão 0.1.0, agora você pode pip install rlipython e fazer com que a linha de leitura antiga funcione por padrão no IPython depois de import rlipython; rlipython.install() .

Atrasado para a festa, mas deixe-me reiterar que o RT no momento é proibido para projetos que têm módulos não projetados para inicialização multithread, consulte o

Além disso, um comentário sobre um problema geral com o RT atual: ele dispara a importação multithread de módulos Python ao preencher a guia. Duvidamos muito que seja seguro.

Por último, mas não menos importante - considerando que o preenchimento da guia IPython causa segfaults, que tal um meio de teste não interativo disso?

@jonathanslenders você já se deparou com algum problema de conclusão em execução em um thread separado? Existe uma opção para fazê-lo funcionar de forma síncrona?

Olá @takluyver ,

Desculpe pela resposta tardia. Eu me casei no mês passado, então estou offline por um tempo. ;)

Estou trabalhando no prompt_toolkit 2.0, que já oferece suporte para conclusão síncrona (no thread principal) e assíncrona (em outro thread). Estou trabalhando no 2.0 há quase um ano e espero lançá-lo em alguns meses.

Para a conclusão síncrona, você deve ter em mente que se o completador não for super rápido, isso irá introduzir um atraso após cada pressionamento de tecla (se você tiver completado enquanto digita). Eu acredito que Jedi por exemplo não é super rápido.

Eu sei que certas bibliotecas têm alguns problemas com a conclusão assíncrona. Acho que devemos encorajar os autores dessas bibliotecas a certificar-se de que importá-las em primeiro lugar pode ser feito a partir de qualquer thread. No futuro, eu tornaria uma opção para executar a conclusão sincronizada ou assíncrona, mas ainda prefiro ter a conclusão assíncrona por padrão. Isso torna a experiência do usuário muito mais agradável.

No sábado, 21 de outubro de 2017 às 14h47, Jonathan Slenders < notificaçõ[email protected]

escreveu:

Eu sei que certas bibliotecas têm alguns problemas com assíncronas
conclusão. Acho que devemos encorajar os autores dessas bibliotecas a
certifique-se de que importá-los em primeiro lugar pode ser feito a partir de qualquer
fio.

IMHO é uma ilusão que isso é sempre fácil de conseguir.
Existem bibliotecas Python que basicamente envolvem terceiros
código do partido, e as alterações necessárias para inicialização thread-safe têm que ser
feito a montante.
Um exemplo concreto em que estamos batendo a cabeça
Maxima é executado em um sistema ECL (embutido em Python) Lisp.
Este último, como todo Lisps, precisa de um coletor de garbade e está usando BoehmGC . Em algumas plataformas, o último deve ser
inicializado no thread principal --- ou costumava ser o caso, por exemplo, para
FreeBSD, até que eu indiquei, e foi corrigido rapidamente . Como você pode imaginar, em outros
casos, alguém poderia estar totalmente sem sorte com tal correção, pois precisava de um especialista
conhecimento de um sistema bastante complicado.

E há vários problemas a serem resolvidos, um dos quais é que em um
cenário de thread único, uma biblioteca pode fazer seu próprio tratamento de sinais, enquanto
em um cenário multithread, o tratamento do sinal deve ser centralizado. o
outro, ainda mais difícil de resolver, é que esse código de terceiros pode não ser
discussão segura.
(voltando ao exemplo acima, vemos tudo isso ...)

Parece que a melhor opção seria
para a PT fazer todas as importações no segmento principal --- não tenho ideia se
é fácil ou mesmo viável de implementar, no entanto.

Por fim, deixe-me salientar que, na verdade, o PT faz uma importação multithread.
Como a importação é um gargalo de inicialização para sistemas maiores, é muito
tentador permitir a importação multithread.
Eu realmente gostaria de ouvir o que as pessoas do CPython diriam sobre isso; eu
não ficará surpreso se a resposta for que não deve ser feito.

PS. Não quero estragar sua lua de mel, parabéns :-)

Parabéns! É claro que não há necessidade de se desculpar - nós recebemos sua incrível biblioteca de graça, portanto, qualquer suporte deve ser feito como e quando for conveniente para você. Muitas felicidades para você e seu parceiro.

Acho que provavelmente mudaremos para completações síncronas quando estiverem disponíveis. Não usamos o método completo à medida que você digita, porque habilitamos o recurso de pesquisa de histórico, que é mutuamente exclusivo com ele.

Esta página foi útil?
0 / 5 - 0 avaliações