Предотвратить / поймать SWIG-завернутый модуль от выхода из сеанса Python? - PullRequest
0 голосов
/ 17 февраля 2020

При использовании функции в импортированном модуле (C ++, завернутый в swig), который, по-видимому, вызывает Треугольник , иногда происходит сбой.

Проблема заключается в том, что нет исключения Python повышенный - после строки сообщения об ошибке он выходит на терминал, и код, следующий за этим вызовом функции, не имеет возможности для запуска. то есть что-то вроде:

import useful_module
# Do stuff here
useful_module.funtion_that_includes_call_to_triangle()  # This crashes under certain conditions
### cleanup code here not run... outputs error below ###

# Internal error in segmentintersection():
#   Topological inconsistency after splitting a segment.
#   Please report this bug to jrs@cs.berkeley.edu
#   Include the message above, your input data set, and the exact
#     command line you used to run Triangle.

Я пытался окружить оскорбительную строку try/except, но когда она выходит без сообщения об ошибке, она не перехватывается.

Это будет также вернитесь обратно к терминалу, если вышеперечисленные действия были предприняты в сеансе ipython.

Есть ли способ отловить выход из сеанса python, чтобы мой код продолжался?

1 Ответ

0 голосов
/ 26 февраля 2020

На данный момент мое решение состоит в том, чтобы обернуть вызов внутри рабочей функции и запустить рабочую функцию как новый процесс, используя multiprocessing.Process. Данные могут быть переданы и возвращены в моем случае с использованием очередей. Передача исключений, вызванных кодом, была непростой задачей - я завернул весь кодовый блок с try/except и put результатом в очереди возврата. Если есть лучший способ, пожалуйста, оставьте комментарий или ответ.

Я включил некоторую реализацию, на случай, если это будет полезно.

Что-то вроде:

import multiprocessing as mp
import queue
import useful_module

# A serialisable worker function
def worker(q, other_args):
    try:
        # Do stuff here with usual try/except/raise
        results = useful_module.funtion_that_includes_call_to_triangle()
        q.put(results)
    except Exception as e:
        q.put(e)

q = mp.Queue()
p = mp.Process(target=worker, args=(q, other_args))
p.start()
p.join()

# Get results from worker
try:
    results = q.get(block=False)
except queue.Empty:
    print('No result. Triangle probably failed!')
    # Do failure handling here
else:
    # Check if an exception was raised by worker code
    if isinstance(results, Exception):
        raise results

# Continue as normal

В случае запуска cra sh он уничтожает только что созданный рабочий процесс, а родительский процесс python выживает.

...