Ipython: Невозможно создать многострочные блоки кода в ipython

Созданный на 27 сент. 2018  ·  26Комментарии  ·  Источник: ipython/ipython

Я только что сделал pip install ipython во время сегодняшнего преподавания в классе, набрал оператор if, а затем нажал Enter после первой строки и выполнения кода.

Это похоже на ошибку.

Я сделал pip install ipython==6.5.0 и нажатие Enter в блоке кода правильно показало мне следующую строку с отступом для ввода.

Я использую Ubuntu 18.04, использую ipython внутри tmux, хотя я сомневаюсь, что проблема в tmux.

Hacktoberfest help wanted

Самый полезный комментарий

На самом деле у меня с исправлением регресс. Исправляем это сейчас.

PR № 11354 обновлен.

Все 26 Комментарий

вы можете использовать ctrl-o чтобы заставить новую строку.

Я бы никогда не догадался об этом. Я не уверен, как прояснить это, но я думаю, что это требует некоторого разъяснения / поддержки. Я пробовал все ярлыки, которые мог придумать, и в итоге вынужден был перейти на более раннюю версию, чтобы исправить свою проблему.

Я использую IPython, чтобы упростить набор и редактирование многострочных блоков в REPL при обучении живой аудитории. Я подозреваю, что у других людей в моей ситуации могут быть похожие проблемы.

Может быть, где-то есть предупреждение, указывающее, что Ctrl-O можно использовать для создания многострочного блока кода? Я не уверен, есть ли для этого подходящее место.

Это ошибка недавнего рефакторинга, я просто пытался сказать вам, что вы можете пока использовать Ctrl-O, если хотите использовать 7.x

Ах, отлично! Я рад, что это просто ошибка. Спасибо @Carreau! 😄

Не могли бы вы дать мне несколько примеров (работающих, а не работающих) того, чего вы ожидаете, чтобы проверить исправления?

У меня есть несколько, но я их собираю, и я не хочу на вас влиять.

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

Второй пример не помню, но несколько циклов:

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

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

@Carreau кто-то работает над этой проблемой? Я был бы рад помочь

привет @ Дебора-Диггес, я быстро посмотрела, но пока не особо.

Я написал этот небольшой тестовый пример, чтобы увидеть разницу между старым input_splitter и новым 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:'))

В результате

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

Вы видите, что нас интересует третий пункт. Второй - из любопытства, так как одна из «особенностей» IPython - принудительное выполнение, если имеется более двух символов новой строки.

Часть соответствующего кода находится в shortcut.py:L109-L127 .

Я предполагаю, что есть какое-то смешение между ролью определения того, является ли проверка кода «полной», или мы должны «выполнить или добавить новую строку».

Я _gessing_, что эвристики, которая проверяет, является ли ввод многострочным и является ли последний символ уже новой строкой или нет, должно быть достаточно.

Один из оставшихся вопросов: где поставить это исправление?

  • в shortcut.py ? если это так, он исправит только терминал IPython
  • в input_transformer2? Я думаю, что это может быть правильным решением, но, вероятно, также повлияет на QtConsole.

Дайте мне знать, достаточно ли этого для начала.

Благодаря !

Привет @Carreau ! Большое спасибо за подробное объяснение и тестовые примеры.

Мне удалось воспроизвести его локально с помощью версии ipython для разработчиков, и теперь я начну изучать код для shortcut.py и inputtransformer .

Не могли бы вы дать мне несколько примеров (работающих, а не работающих) того, чего вы ожидаете, чтобы проверить исправления?

Вам не нужно приводить несколько примеров. Ошибка возникает очень воспроизводимо.
Многострочный режим работает только в том случае, если строка заканчивается двоеточием. Если в конце строки нет двоеточия, iPython выполняет код. С этой информацией это выглядит несколько тривиально, но я никогда не заглядывал в исходный код iPython, так что, возможно, я здесь слишком оптимистичен;)

iPython

Верхний регистр, прошу, не хотим проблем с яблоком.

Вам не нужно несколько примеров

Нет, мне не нужно, но мне нужно несколько примеров. Я могу воспроизвести и иметь представление о том, как это исправить, но наличие нескольких случаев помогает мне быть уверенным, что я не попаду в крайний случай. У меня есть предвзятое мнение о том, как использовать IPython, поэтому примеры из других могут быть полезны.

iPython
Верхний регистр, прошу, не хотим проблем с яблоком.

По крайней мере, я узнал, почему в названии стоит верхняя буква I, спасибо и извините :)

В качестве извинения вот пул-реквест № 11354, исправляющий эту (серьезную) проблему. ИМХО, это ошибка блокировки для IPython, вам следует подумать о том, чтобы в ближайшее время выпустить релиз (посмотрите, сколько проблем создается на github пользователями в связи с этим).

По крайней мере, я узнал, почему в названии стоит верхняя буква I, спасибо и извините :)

Это не единственная причина, поскольку IPython 0.1 был выпущен раньше первого iProduct, но обычно люди помнят

В качестве извинения вот пул-реквест № 11354, исправляющий эту (серьезную) проблему.

спасибо, я посмотрю, когда позволит время

вам следует подумать о том, чтобы вскоре выпустить релиз

Да, как только у волонтера будет время, мы это сделаем. Есть и другая критическая проблема, такая как выпуск jupyter_console, и я не думаю, что кто-то из присутствующих может потратить на это пару часов на $ DAYJOB. Так что, возможно, придется подождать этих выходных.

На самом деле у меня с исправлением регресс. Исправляем это сейчас.

На самом деле у меня с исправлением регресс. Исправляем это сейчас.

PR № 11354 обновлен.

Спасибо за исправление, есть идеи, когда это будет выпущено? Я использую сочетания клавиш vim для CTRL-O, у меня не работает (ESC + o ...)

Спасибо за исправление, есть идеи, когда это будет выпущено?

Это будет один из добровольцев проекта, который получит пару бесплатных часов, чтобы отсортировать несколько оставшихся проблем для 7.1 и выпустить релиз. Я надеюсь, что у меня будет пара часов в эти выходные, но этого может быть недостаточно.

Любая помощь по сортировке / просмотру / маркировке существующих PR / проблем будет полезна.

Все еще воспроизводимый с блоками async with , пробовал как текущую главную ветку, так и v7.1.1 из PyPI.

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

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

Хм, это, вероятно, странное взаимодействие с автожиданием.

О, я не думал, что это связано с этой проблемой. В любом случае причина его неудачи в том, что когда у нас

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

он запускает check_complete в конце каждой строки, который, в свою очередь, выполняет compile_command , а последний вызывает SyntaxError потому что 'async with' используется вне функции async .
В своей вилке я просто отключил SyntaxError но это определенно не самый лучший способ исправить это, лол.

Возможные решения / идеи:

  • следует проверить, включен ли autoawait . если это так, можно игнорировать этот конкретный случай SyntaxError . Не думаю, что это хорошее решение, но, может быть, я еще и слишком усложняю.

  • если автоматическое ожидание включено, скормите compile_command() кодом, заключенным в _asyncify() . Я предполагаю, что таким образом он не вызовет SyntaxError , но я не уверен, будет ли решена проблема новой строки, потому что _asyncify() сам добавляет несколько уровней отступов, и это легко может испортиться.

  • может _AsyncSyntaxErrorVisitor кому может помочь? Но я думаю, это наоборот

Прошу прощения за недостаточную самоотдачу, я бы отправил PR, но я ненавижу писать тесты и тому подобное, а также не уверен, как это исправить. Но надеюсь, это еще кому-то пригодится.

Мы могли бы попробовать что - то вроде этого , а также.

Это ваша точка зрения №2, и она действительно уродлива. Новая строка работает. Было бы хорошо получить надлежащую поддержку в CPython.

Эта проблема все еще не решена? Думаю, я мог поймать эту ошибку ...

Сегодня это впервые (во время демонстрации с клиентом, когда я пытался продемонстрировать, что такое генератор на Python !!!).

Я что-то делаю не так или что мне делать, чтобы писать многострочные блоки кода (кроме обходного пути CTRL-o)?

Ожидаемый результат, продемонстрированный в стандартном 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()

Результат сегодня, когда я ввожу то же самое в 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]:      

IPython REPL автоматически делает отступ во второй строке, как и ожидалось. Но когда я набираю Enter в конце второй строки, он выполняет две строки вместо предоставления дополнительной третьей строки.

Как описано выше, я могу получить желаемый результат, нажав CTRL-o вместо нажатия Enter во второй строке:

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

IPython 7.0.1 - ...

Пожалуйста, обновите свой IPython, эта проблема решена, есть еще крайний случай с асинхронным кодом.

Ой, извини. Я думал, что да. После conda update ipython я получаю # All requested packages already installed.

Извините, я немного запутался. Какая последняя версия и как мне перейти на нее?

Это будет зависеть от того, как вы его установили, я бы предложил попробовать с pip install чтобы увидеть, работает ли это. Но вы также можете работать в окружающей среде.

Когда случаются подобные вещи, я пытаюсь агрессивно деинсталлировать, пока не смогу запустить IPython, а затем переустановить.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги