CalledProcessError, проходящий блок try с помощью eventlet

1

Я использую eventlet для зеленых потоков (в частности, сервер wsgi). Чтобы легко добавить эту функциональность в существующую базу кода, я использовал функциональные возможности eventkey monkey_patch.

Таким образом, самая верхняя часть моего файла:

import eventlet
eventlet.monkey_patch()

Теперь у меня есть функция немного дальше:

def ping(host: str) -> bool:
    try:
        ret = subprocess.check_output(["ping", "-c", "4", host], stderr=subprocess.DEVNULL).decode("utf-8")
        for line in ret.splitlines()[1:-3]:
            if host in line:
                return True
        return False
    except subprocess.CalledProcessError:
        return False

Если цель недоступна, поведение этой функции немного меня озадачивает. Если monkey_patch не включен, то это возвращает False, как и следовало ожидать. Если, однако, они monkey_patch на месте, он вызывает CalledProcessError.

Я не понимаю, как это возможно - его нужно немедленно поймать. Что здесь происходит?

Редактировать 1: Здесь пример сеанса интерпретатора:

>>> ping("192.168.0.233")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "test.py", line 8, in ping
    ret = subprocess.check_output(["ping", "-c", "4", host], stderr=subprocess.DEVNULL).decode("utf-8")
  File "/usr/lib/python3.6/subprocess.py", line 336, in check_output
    **kwargs).stdout
  File "/usr/lib/python3.6/subprocess.py", line 418, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['ping', '-c', '4', '192.168.0.233']' returned non-zero exit status 1.

Редактировать 2: Как оказалось, если я поймаю исключение, except Exception или даже голого, except, то поймается отлично. Я полагаю, что буду использовать это, пока не найдется более подходящее решение. Однако я все еще ошеломлен этим поведением.

  • 0
    Ваш код стирает информацию об ошибках, которая может быть использована для устранения неполадок. Показать исключение. В логе производственного кода все ненормально.
  • 0
    Я не совсем понимаю. Где я стираю информацию об ошибке? Вы имеете в виду, потому что я ловлю исключение? Но это та часть, которая не работает - я хочу, чтобы исключение было поймано. Тем не менее, я добавил пример сеанса интерпретатора, иллюстрирующий проблему. (Кстати, предоставленный код является почти рабочим примером - вам просто нужно импортировать подпроцесс)
Показать ещё 1 комментарий
Теги:
exception
eventlet

1 ответ

0

Проблема состоит в двух различных объектах класса исключения с тем же именем в stdlib и в зеленых исправленных модулях. В коде они выглядят одинаково, но для try/except они разные.

К сожалению, нет стабильного решения прямо сейчас. Патчи приветствуются!

Обход eventlet.monkey_patch(): вызовите eventlet.monkey_patch() перед любым другим выполнением кода.

Подпишитесь на новости по этому вопросу здесь: https://github.com/eventlet/eventlet/issues/413

Коренной причиной является то, что исправление обезьяны создает новый модуль, "копирует" известные им имена, заменяя ссылки на зеленые модули и помещает этот модуль под именем sys.modules в sys.modules. (В отличие от модификации модуля stdlib на месте, что невозможно, поскольку ограничения C-API Python)

  • 0
    Самые первые две строки моего файла - это import eventlet и eventlet.monkey_path() . Как я мог сделать monkey_patch раньше?
  • 0
    Этот файл выполняется первым или, может быть, какой-то фреймворк загружает его? Не могли бы вы опубликовать минимальный сценарий воспроизведения или отправить мне?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню