Ipython: Impossible de créer des blocs de code multiligne dans ipython

Créé le 27 sept. 2018  ·  26Commentaires  ·  Source: ipython/ipython

J'ai juste fait un pip install ipython en enseignant une classe aujourd'hui et j'ai tapé une instruction if, puis appuyez sur Entrée après la première ligne et le code exécuté.

Cela semble être un bug.

J'ai fait un pip install ipython==6.5.0 et appuyer sur Entrée dans un bloc de code m'a correctement montré la prochaine ligne en retrait à taper.

Je suis sur Ubuntu 18.04 exécutant ipython dans tmux, bien que je doute que tmux soit le problème ici.

Hacktoberfest help wanted

Commentaire le plus utile

En fait, j'ai eu une régression avec mon correctif. Réparer maintenant.

Le PR # 11354 est mis à jour maintenant.

Tous les 26 commentaires

vous pouvez utiliser ctrl-o pour forcer une nouvelle ligne.

Je n'aurais jamais deviné celui-là. Je ne sais pas comment rendre cela plus clair, mais je pense que cela mérite une clarification / une prise en main. J'ai essayé tous les raccourcis auxquels je pouvais penser et j'ai fini par forcer une rétrogradation pour résoudre mon problème.

J'utilise IPython pour faciliter la saisie et la modification de blocs multilignes dans le REPL tout en enseignant au public en direct. Je soupçonne que d'autres personnes dans ma situation peuvent avoir des problèmes similaires.

Peut-être un avertissement quelque part qui indique que Ctrl-O peut être utilisé pour créer un bloc de code multiligne? Je ne sais pas s'il existe un endroit approprié pour cela.

C'est un bug avec un refactor récent, j'essayais juste de vous dire que vous pouvez utiliser Ctrl-O en attendant si vous souhaitez utiliser 7.x

Ah super! Je suis content que ce ne soit qu'un bug. Merci @Carreau! 😄

Pourriez-vous me donner quelques exemples (fonctionnels et non fonctionnels) de ce que vous attendez, afin de tester les correctifs?

J'en ai mais j'en collectionne quelques-uns et je ne veux pas vous influencer.

with open('hello.txt', mode='wt') as my_file:
    my_file.write('hi')
    my_file.write('hi again')

Je ne me souviens pas du deuxième exemple, mais un certain nombre de boucles:

numbers = [2, 1, 3, 4, 7, 8, 11]

for n in numbers:
    if n > 0:
        print(n*2)
    else:
        print(n/2)

@Carreau est-ce que quelqu'un travaille sur ce problème? Je serais heureux d'aider

salut @ Deborah-Digges, j'ai jeté un coup d'œil mais pas trop pour l'instant.

J'ai écrit ce petit cas de test pour voir la différence entre l'ancien input_splitter et le nouveau input_transformer:

from IPython.core import inputtransformer2 as ipt2 # new way
from IPython.core import inputsplitter #oldl way

occ =  inputsplitter.InputSplitter().check_complete
cc = ipt2.TransformerManager().check_complete

comp = lambda x : (cc(x), occ(x), x)
print(comp('if'))
print(comp('if\n\n'))
print(comp("""
def foo():
    print('Hello')"""
))
print(comp('if True:'))

Quel résultat en

(('invalid', None), ('invalid', None), 'if')
(('complete', None), ('invalid', None), 'if\n\n')
(('complete', None), ('incomplete', 4), "\ndef foo():\n    print('Hello')")
(('incomplete', 4), ('incomplete', 4), 'if True:')

Vous voyez que le 3ème élément est celui qui nous intéresse. La seconde était par curiosité car l'une des "fonctionnalités" d'IPython est de forcer l'exécution s'il y a plus de 2 nouvelles lignes.

Une partie du code pertinent se trouve dans shortcut.py:L109-L127 .

Je suppose qu'il y a une sorte de confusion entre le rôle de définir si une vérification de code est "complète" ou si nous devons "exécuter ou ajouter une nouvelle ligne".

Je suppose que l'heuristique qui vérifie si l'entrée est multiligne et si le dernier caractère est déjà une nouvelle ligne ou non devrait être suffisante.

L'une des questions restantes est de savoir où mettre ce correctif?

  • dans shortcut.py ? si c'est le cas, il ne réparera que le terminal IPython
  • dans input_transformer2? Je pense que cela pourrait être la bonne solution, mais cela affectera probablement également QtConsole.

Faites-moi savoir si cela suffit pour au moins vous aider à démarrer

Merci !

Salut @Carreau ! Merci beaucoup pour l'explication détaillée et les cas de test.

J'ai pu le reproduire localement avec la version dev d'ipython et je vais maintenant commencer à chercher dans le code pour shortcut.py et inputtransformer .

Pourriez-vous me donner quelques exemples (fonctionnels et non fonctionnels) de ce que vous attendez, afin de tester les correctifs?

Vous n'avez pas besoin de quelques exemples. Le bug se produit de manière très reproductible.
La multiligne ne fonctionne

iPython

Majuscules, s'il vous plaît, nous ne voulons pas de problèmes avec Apple.

Vous n'avez pas besoin de quelques exemples

Eh bien, non, je n'ai pas besoin, mais je veux plusieurs exemples. Je peux reproduire et avoir une idée de la façon de le réparer, mais le fait d'avoir plusieurs cas m'aide à être sûr que je ne touche pas un cas de pointe. J'ai une opinion biaisée sur la façon d'utiliser IPython, donc des exemples d'autres sont utiles.

iPython
Majuscules, s'il vous plaît, nous ne voulons pas de problèmes avec Apple.

Au moins j'ai découvert pourquoi il y avait le haut I dans le nom, merci et désolé :)

Pour vous excuser, voici une pull request # 11354 qui résout ce problème (majeur). À mon humble avis, il s'agit d'un bogue bloquant pour IPython, vous devriez envisager de faire une version bientôt (voir combien de problèmes sont créés sur github par les utilisateurs à ce sujet).

Au moins j'ai découvert pourquoi il y avait le haut I dans le nom, merci et désolé :)

Ce n'est pas la (seule) raison, car IPython 0.1 était sorti avant le premier iProduct, mais généralement les gens se souviennent

Pour vous excuser, voici une pull request # 11354 qui résout ce problème (majeur).

merci je jetterai un coup d'oeil quand le temps le permettra

vous devriez envisager de faire une sortie bientôt

Oui, une fois qu'un volontaire aura le temps, nous le ferons. Il y a d'autres problèmes critiques comme la sortie d'une version de jupyter_console, et je ne pense pas que quiconque ici puisse prendre quelques heures sur $ DAYJOB pour le faire. Il faudra donc peut-être attendre ce week-end.

En fait, j'ai eu une régression avec mon correctif. Réparer maintenant.

En fait, j'ai eu une régression avec mon correctif. Réparer maintenant.

Le PR # 11354 est mis à jour maintenant.

Merci pour le correctif, une idée de la date de sortie de cet article? J'utilise les raccourcis clavier vim pour CTRL-O ne fonctionne pas pour moi (ESC + o fait ...)

Merci pour le correctif, une idée de la date de sortie de cet article?

Ce sera l'un des bénévoles du projet qui bénéficiera de quelques heures gratuites pour trier les quelques problèmes restants pour la version 7.1 et fera une version. J'espère avoir peut-être quelques heures ce week-end, mais ce n'est peut-être pas suffisant.

Toute aide sur le tri / la révision / le marquage des PR / problèmes existants serait utile.

Toujours reproductible avec les blocs async with , a essayé à la fois la branche maître actuelle et la v7.1.1 de PyPI.

In [16]: async with aiofiles.open('/tmp/foobar', 'r') as f:
    ...:     content = await f.read()

In [17]: content
Out[17]: 'hello'

Hum, c'est probablement une interaction étrange avec autoawait.

Oh, je ne pensais pas que cela serait lié à ce problème. Quoi qu'il en soit, la raison pour laquelle cela échoue est que lorsque nous avons

async with aiohttp.ClientSession() as session:
    pass|   # < cursor is there

il exécute check_complete sur chaque fin de ligne, qui, à son tour, exécute compile_command , et ce dernier lève un SyntaxError car 'async with' est utilisé en dehors de la fonction async .
Dans mon fork, j'ai juste coupé ce SyntaxError mais ce n'est certainement pas le moyen le plus brillant de résoudre ce problème, lol.

Solutions / idées possibles:

  • devrait vérifier si le autoawait est activé. si c'est le cas, pourrait ignorer ce cas spécifique SyntaxError . Je ne pense pas que ce soit une bonne solution, mais peut-être que je complique trop les choses.

  • si l'attente automatique est activée, alimentez le compile_command() avec le code enveloppé avec le _asyncify() . Je suppose que de cette façon, cela ne lèvera pas SyntaxError , mais je ne suis pas sûr si le problème de nouvelle ligne sera résolu car _asyncify() lui-même ajoute quelques niveaux d'indentation et cela peut facilement devenir désordonné.

  • peut-être que _AsyncSyntaxErrorVisitor peut aider quelqu'un? Mais je suppose que c'est pour l'inverse

Je suis désolé pour le manque de dévouement, je soumettrais thw PR, mais je déteste écrire des tests et autres et aussi pas sûr de la meilleure façon de résoudre ce problème. Mais j'espère que c'est toujours utile pour quelqu'un.

Nous pourrions également essayer quelque chose comme ça .

C'est votre point n ° 2, et c'est vraiment moche. La nouvelle ligne fonctionne. Ce qui serait bien, c'est d'obtenir un support approprié dans CPython.

Ce problème n'est-il toujours pas résolu? Je pense que j'ai peut-être attrapé ce bug ...

Cela se produit aujourd'hui pour la première fois (lors d'une démo avec un client alors que j'essayais de montrer ce qu'est un générateur en Python !!!).

Est-ce que je fais quelque chose de mal ou que suis-je censé faire pour écrire des blocs de code multiligne (autre que la solution de contournement CTRL-o)?

Résultat attendu comme démontré dans le standard Python REPL:

(tsa) BillsMacBookPro:develop billtubbs$ python
Python 3.5.5 | packaged by conda-forge | (default, Jul 23 2018, 23:45:11) 
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> for i in range(5):
...     x = i*2
...     print(x)
... 
0
2
4
6
8
>>> exit()

Résultat aujourd'hui lorsque je tape la même chose dans un REPL iPython:

(tsa) BillsMacBookPro:develop billtubbs$ ipython
Python 3.5.5 | packaged by conda-forge | (default, Jul 23 2018, 23:45:11) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.0.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: for i in range(5): 
   ...:     x = i*2                                                                   

In [2]:      

Le REPL iPython indente automatiquement la deuxième ligne comme prévu. Mais lorsque je tape enter à la fin de la deuxième ligne, il exécute les deux lignes au lieu de fournir une troisième ligne facultative.

Comme décrit ci-dessus, je peux obtenir le résultat souhaité en appuyant sur CTRL-o au lieu d'appuyer sur Entrée sur la deuxième ligne:

In [2]: for i in range(5): 
   ...:     x = i*2 
   ...:     print(x)                                                                  
0
2
4
6
8

IPython 7.0.1 - ...

Veuillez mettre à jour votre IPython, ce problème est résolu, il y a juste encore un cas limite avec du code asynchrone.

Oh pardon. Je pensais l'avoir fait. Après conda update ipython j'obtiens # All requested packages already installed.

Désolé, je suis un peu confus. Quelle est la dernière version et comment la mettre à niveau?

Cela dépendra de la façon dont vous l'avez installé, je vous suggère d'essayer avec pip install pour voir si cela fonctionne. Mais vous travaillez peut-être aussi dans un environnement.

Quand des choses comme ça se produisent, j'essaye de désinstaller agressivement jusqu'à ce que je ne puisse pas lancer IPython puis réinstaller.

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