Ipython: No se pueden crear bloques de código de varias líneas en ipython

Creado en 27 sept. 2018  ·  26Comentarios  ·  Fuente: ipython/ipython

Acabo de hacer un pip install ipython mientras impartía una clase hoy y escribí una declaración if y luego presioné enter después de la primera línea y el código se ejecutó.

Esto parece un error.

Hice un pip install ipython==6.5.0 y presionar Enter en un bloque de código me mostró correctamente la siguiente línea con sangría para escribir.

Estoy en Ubuntu 18.04 ejecutando ipython dentro de tmux, aunque dudo que tmux sea el problema aquí.

Hacktoberfest help wanted

Comentario más útil

De hecho, tengo una regresión con mi solución. Arreglandolo ahora.

El PR # 11354 está actualizado ahora.

Todos 26 comentarios

puede usar ctrl-o para forzar una nueva línea.

Nunca lo hubiera adivinado. No estoy seguro de cómo dejar esto más claro, pero creo que merece una aclaración / agarre de la mano. Probé todos los atajos que pude pensar y terminé forzando una rebaja para solucionar mi problema.

Utilizo IPython para facilitar la escritura y la edición de bloques de varias líneas en REPL mientras enseño a audiencias en vivo. Sospecho que otras personas en mi situación pueden tener problemas similares.

¿Quizás una advertencia en alguna parte que indique que Ctrl-O se puede usar para hacer un bloque de código de varias líneas? No estoy seguro de si hay un lugar apropiado para eso.

Es un error con una refactorización reciente, solo estaba intentando decirte que puedes usar Ctrl-O mientras tanto si deseas usar 7.x

¡Ah, genial! Me alegro de que haya sido solo un error. ¡Gracias @Carreau! 😄

¿Le importaría darme algunos ejemplos (que funcionan y no funcionan) de lo que espera, para poder probar las correcciones?

Tengo algunos, pero solo colecciono algunos y no quiero influenciarlos.

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

No recuerdo el segundo ejemplo, pero varios bucles:

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

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

@Carreau, ¿alguien está trabajando en este tema? Estaré feliz de ayudar

hola @ Deborah-Digges, he echado un vistazo rápido, pero no demasiado hasta ahora.

Escribí este pequeño caso de prueba para ver la diferencia entre el antiguo input_splitter y el nuevo 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:'))

Que resulta 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:')

Ves que el 3º punto es el que nos interesa. El segundo fue por curiosidad, ya que una de las "características" de IPython es forzar la ejecución si hay más de 2 líneas nuevas.

Parte del código relevante está en shortcut.py:L109-L127 .

Supongo que existe una especie de combinación entre el papel de definir si una verificación de código está "completa" o si deberíamos "ejecutar o agregar una nueva línea".

Estoy _conjeturo_ que la heurística que verifica si la entrada es multilínea y si el último carácter ya es una nueva línea o no debería ser suficiente.

Una de las preguntas restantes es ¿dónde colocar esa solución?

  • en shortcut.py ? si es así, solo arreglará el terminal IPython
  • en input_transformer2? Creo que podría ser la solución correcta, pero probablemente también afectará a QtConsole.

Hágame saber si eso es suficiente para al menos comenzar.

Gracias !

Hola @Carreau ! Muchas gracias por la explicación detallada y los casos de prueba.

Pude reproducirlo localmente con la versión dev de ipython y ahora comenzaré a buscar en el código shortcut.py y inputtransformer .

¿Le importaría darme algunos ejemplos (que funcionan y no funcionan) de lo que espera, para poder probar las correcciones?

No necesitas algunos ejemplos. El error se produce de forma muy reproducible.
Multiline funciona solo si la línea termina con dos puntos. Si no hay dos puntos al final de la línea, iPython ejecuta el código. Esto parece un poco más trivial con esta información, pero nunca examiné el código fuente de iPython, por lo que tal vez sea demasiado optimista aquí;)

iPython

Mayúsculas, por favor, no queremos problemas con Apple.

No necesitas algunos ejemplos

Bueno, no, no _necesito_, pero quiero múltiples ejemplos. Puedo reproducir y tener una idea de cómo solucionarlo, pero tener varios casos me ayuda a estar seguro de que no voy a tocar un caso de borde. Tengo una visión sesgada sobre cómo usar IPython, por lo que los ejemplos de otros son útiles.

iPython
Mayúsculas, por favor, no queremos problemas con Apple.

Al menos descubrí por qué estaba la I superior en el nombre, gracias y lo siento :)

Como disculpa, aquí hay una solicitud de extracción n. ° 11354 que soluciona este problema (importante). En mi humilde opinión, este es un error de bloqueo para IPython, debería considerar hacer un lanzamiento pronto (vea cuántos problemas se crean en github por los usuarios al respecto).

Al menos descubrí por qué estaba la I superior en el nombre, gracias y lo siento :)

Esa no es la (única) razón, ya que IPython 0.1 se lanzó antes del primer iProduct, pero generalmente la gente recuerda

Como disculpa, aquí hay una solicitud de extracción n. ° 11354 que soluciona este problema (importante).

gracias voy a echar un vistazo cuando el tiempo lo permita

deberías considerar hacer un lanzamiento pronto

Sí, una vez que un voluntario tenga tiempo, lo haremos. Hay otro problema crítico, como obtener una versión de jupyter_console, y no creo que nadie aquí pueda tomar un par de horas en $ DAYJOB para hacerlo. Así que puede que tenga que esperar este fin de semana.

De hecho, tengo una regresión con mi solución. Arreglandolo ahora.

De hecho, tengo una regresión con mi solución. Arreglandolo ahora.

El PR # 11354 está actualizado ahora.

Gracias por la solución, ¿alguna idea de cuándo se lanzará esto? Estoy usando combinaciones de teclas vim para CTRL-O no funciona para mí (ESC + o sí ...)

Gracias por la solución, ¿alguna idea de cuándo se lanzará esto?

Uno de los voluntarios del proyecto obtendrá un par de horas gratis para clasificar los pocos problemas restantes para 7.1 y hará un lanzamiento. Espero tener tal vez un par de horas este fin de semana, pero puede que no sea suficiente.

Cualquier ayuda para clasificar / revisar / etiquetar los RP / Problemas existentes sería útil.

Aún reproducible con los bloques async with , probé tanto la rama maestra actual como 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, esa es probablemente una interacción extraña con autoawait.

Oh, no pensé que estaría relacionado con este tema. De todos modos, la razón por la que falla es que cuando tenemos

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

ejecuta check_complete en cada final de línea, que, a su vez, ejecuta compile_command , y el último genera un SyntaxError porque 'async with' se usa fuera de la función async .
En mi tenedor acabo de silenciar ese SyntaxError pero ciertamente no es la forma más brillante de solucionarlo, jajaja.

Posibles soluciones / ideas:

  • debería comprobar si el autoawait está encendido. si es así, podría ignorar ese caso específico SyntaxError . No creo que sea una buena solución, pero quizás también estoy complicando demasiado las cosas.

  • si el autoawait está activado, alimenta el compile_command() con el código envuelto con el _asyncify() . Supongo que de esta manera no recaudará SyntaxError , pero no estoy seguro de si el problema de la nueva línea se resolverá porque _asyncify() sí mismo agrega algunos niveles de sangría y puede ensuciarse fácilmente.

  • tal vez _AsyncSyntaxErrorVisitor pueda ayudar a alguno? Pero supongo que es al revés

Lamento la falta de dedicación, enviaría las relaciones públicas, pero odio escribir pruebas y todo eso y tampoco estoy seguro de la mejor manera de solucionarlo. Pero espero que todavía sea útil para alguien.

Podríamos intentar algo como esto también.

Ese es tu punto nº 2, y es feo de verdad. La nueva línea funciona. Lo que sería bueno es obtener el soporte adecuado en CPython.

¿Sigue este problema sin resolver? Creo que pude haber atrapado este error ...

Esto surgió hoy por primera vez (¡durante una demostración con un cliente cuando estaba tratando de demostrar qué es un generador en Python!).

¿Estoy haciendo algo mal o qué se supone que debo hacer para escribir bloques de código de varias líneas (además de la solución alternativa CTRL-o)?

Resultado esperado como se demuestra en el REPL estándar de Python:

(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()

Resultado hoy cuando escribo lo mismo en un REPL de 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]:      

IPython REPL sangra automáticamente la segunda línea como se esperaba. Pero cuando escribo enter al final de la segunda línea, ejecuta las dos líneas en lugar de proporcionar una tercera línea opcional.

Como se describió anteriormente, puedo obtener el resultado deseado presionando CTRL-o en lugar de presionar enter en la segunda línea:

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

IPython 7.0.1 - ...

Actualice su IPython, este problema está resuelto, solo hay un caso de borde con código asincrónico.

Oh, lo siento. Pensé que lo había hecho. Después de conda update ipython obtengo # All requested packages already installed.

Lo siento, estoy un poco confundido. ¿Cuál es la última versión y cómo la actualizo?

Depende de cómo lo hayas instalado, te sugiero que pruebes con pip install para ver si funciona. Pero también puede estar trabajando en un entorno.

Cuando suceden cosas como esa, trato de desinstalar agresivamente hasta que no puedo iniciar IPython y luego reinstalar.

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