RuntimeError: генератор вызывает StopIteration каждый раз, когда я пытаюсь запустить приложение

Я пытаюсь запустить этот код:

import web

urls = (
    '/', 'index'
)

if __name__ == "__main__":
    app = web.application(urls, globals())
    app.run()

Но это дает мне эту ошибку каждый раз

C:\Users\aidke\Desktop>python app.py
Traceback (most recent call last):
  File "C:\Users\aidke\AppData\Local\Programs\Python\Python37-32\lib\site-packages\web\utils.py", line 526, in take
    yield next(seq)
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "app.py", line 14, in <module>
    app = web.application(urls, globals())
  File "C:\Users\aidke\AppData\Local\Programs\Python\Python37-32\lib\site-packages\web\application.py", line 62, in __init__
    self.init_mapping(mapping)
  File "C:\Users\aidke\AppData\Local\Programs\Python\Python37-32\lib\site-packages\web\application.py", line 130, in init_mapping
    self.mapping = list(utils.group(mapping, 2))
  File "C:\Users\aidke\AppData\Local\Programs\Python\Python37-32\lib\site-packages\web\utils.py", line 531, in group
    x = list(take(seq, size))
RuntimeError: generator raised StopIteration

Я попробовал чужой код, и произошло то же самое. Кроме того, я попытался переустановить web.py (экспериментально), но это все равно не сработало.


person no4syn    schedule 06.08.2018    source источник
comment
Зацикливание Python 3.7 теперь сложнее и требует более глубокого понимания внутренностей Python (генераторов). Java для каждого теперь проще, чем python.   -  person barrypicker    schedule 05.12.2019


Ответы (6)


Судя по путям к файлам, вы используете Python 3.7. Если это так, вас поймали new-in- 3.7 поведение:

PEP 479 включен для всего кода в Python 3.7, что означает, что исключения StopIteration, вызванные прямо или косвенно в сопрограммах и генераторах, преобразуются в исключения RuntimeError. (Предоставил Юрий Селиванов в bpo-32670.)

До этого изменения StopIteration, вызванное генератором или проходящее через него, просто заканчивало срок службы генератора (исключение было незаметно проглочено). Модуль, который вы используете, должен быть перекодирован для правильной работы с 3.7.

Скорее всего, они должны быть изменены:

yield next(seq)

to:

try:
    yield next(seq)
except StopIteration:
    return
person Tim Peters    schedule 06.08.2018
comment
Так что, если это в стороннем приложении, вам нужно его обновить? Вы SOL, если это стороннее приложение не исправлено для PEP 479? - person Scott Skiles; 21.03.2019
comment
Конечно, обновление приложения ничего не изменит, если они не изменили приложение. Если их нет, вы можете исправить это самостоятельно. Или воздержитесь от перехода на Python 3.7 до тех пор, пока приложения, о которых вы заботитесь, не будут соответствовать PEP 479. Поскольку я видел очень мало отчетов об этом в дикой природе, я считаю, что это редкая проблема. - person Tim Peters; 21.03.2019
comment
Большое спасибо. Использование виртуальной среды, когда Python 3.7 не работает, звучит как отличное решение, когда это необходимо. - person Scott Skiles; 21.03.2019
comment
Извините за вопрос нуба - есть ли какие-либо последствия с этим решением? Почему можно молча проглотить исключение? - person CozyAzure; 09.10.2019
comment
@CozyAzure, прочитайте PEP, это единственное оправдание для этого изменения, которое вы получите. До этого изменения StopIteration было незаметно поглощено генераторами, поскольку указанный исходный генератор PEP (255) должен произойти. Таким образом, предлагаемый код просто восстанавливает поведение, которое генераторы использовали годами. - person Tim Peters; 10.10.2019
comment
Как исправить yield from? - person Colonel Panic; 26.11.2019
comment
@ColonelPanic, вы знаете, как это сделать: что вы пробовали? что случилось? что вы хотите, чтобы произошло вместо этого? Вероятно, вам следует открыть новый самостоятельный вопрос. - person Tim Peters; 26.11.2019
comment
Я обновил mongoengine с 0.14.0 до 0.19.1 и с flask-mongoengine до 0.9.5. - person Ohad Perry; 09.02.2020
comment
Другим хорошим решением, в зависимости от контекста, является передача значения по умолчанию в блок next вместо блока try-except: yield next(seq, None). - person bryant1410; 16.01.2021

Итак, во время моего недавнего самообучения по Python курс требовал от меня установки Web.py, и я получал эту ошибку, и, как говорилось в одном из ответов, его нужно было обновить, чтобы он был совместим с Python 3.7.

Я установил пакет с pip3 install web.py==0.40-dev1, столкнулся с этой ошибкой и начал искать решение в Интернете.

Что я сделал, так это поискал в webpy git и нашел файл utils.py, который был более свежим в https://github.com/webpy/webpy/tree/master/web, скачал его и использовал для замены того, что был в моей Lib/site-packages/web папку (я пользователь Windows), и это просто сработало.

Надеюсь, это поможет кому-то.

person Leo Gomez    schedule 15.07.2019

Мое решение состояло в том, чтобы обновить эти точки

mongoengine с 0.14.0 по 0.19.1 и

flask-mongoengine to 0.9.5

это сработало.

person WebQube    schedule 09.02.2020
comment
Как это сделать для яиц? - person mLstudent33; 24.06.2020

Они исправили эту проблему, просто удалите текущую версию web.py, и я получил ошибку при запуске pip install web.py из windows 10. Поэтому я запускаю команду pip install -e git+https://github.com/webpy/webpy.git#egg=webpy, чтобы получить последнюю версию из ветки master. Это не приведет к ошибке RuntimeError: generator raised StopIteration, как упоминалось в вопросе.

person Kushan Gunasekera    schedule 04.08.2019
comment
Я получил предупреждение, и это не исправило его. - person mLstudent33; 24.06.2020