gpt4 book ai didi

python - 如何防止 Python 返回到 C++ boost::python::error_already_set?

转载 作者:行者123 更新时间:2023-11-30 05:19:11 26 4
gpt4 key购买 nike

我需要在问题之前提供一些背景信息。请多多包涵。我使用 boost::python 向 Python 公开了一些异常类型,比如 MyExceptionType。我有一个 boomTest,我将其暴露给 Python 以检查它是否有效。 Python 调用 boomTest 并正确处理 MyExceptionType,目前一切顺利。这是事物的 C++ 方面:

static void boomTest() {
throw MyExceptionType("Smoked too many Cohibas!");
}

static PyObject *myExceptionPtr = NULL;
static void translate(MyExceptionType const &exception) {
assert(myExceptionPtr != NULL);
boost::python::object pythonExceptionInstance(exception);
PyErr_SetObject(myExceptionPtr, pythonExceptionInstance.ptr());
}

BOOST_PYTHON_MODULE(test) {
class_<MyExceptionType> myException("MyExceptionType", no_init);
myException.add_property("message", &MyExceptionType::what);
myExceptionPtr = myException.ptr();
register_exception_translator<MyExceptionType>(&translate);
}

这是 Python 方面的事情:

import sys

import example
reload(example)
from example import MyExceptionType, boomTest

def tryBoomTest():
try:
boomTest()

except MyExceptionType as ex:
print 'Success! MyExceptionType gracefully handled:' \
'\n message="%s"' % ex.message
except:
print 'Caught unhandled exception: %s "%s"' % (sys.exc_info()[0], sys.exc_info()[1])

现在事情变得有点棘手了,因为在实际用例中,我有一个从 C++ Boost(非 Python)线程到 Python 的回调,如下所示:

# this is a Python callback invoked from a C++ boost non-Python thread
def handle(future):
try:
# future.get() throws MyExceptionType if there was a cluster exception
"Cluster response received with value: %s" % future.get()

except MyExceptionType as ex:
print 'Success! MyExceptionType gracefully handled:' \
'\n message="%s"' % ex.message

现在是 OP:

future.get() 调用抛出 MyExceptionType 时,为什么我的 C++ 回调触发器会收到 boost::python::error_already_set 异常> 打算让 Python 处理?我怀疑这种行为是由于异常是在 C++(非 Python)线程中引发的......

需要什么来强制 Python 处理开头示例中的异常?

我已经尝试在 C++ 的回调触发器中执行以下操作:

void callbackTrigger() {
try {
pythonHandle_(getFuture());
}
// why do I get this???
catch (boost::python::error_already_set&) {
// this doesn't help, Python doesn't still handle MyExceptionType
boost::python::handle_exception();
}
}

最佳答案

我验证了我关于 Python 不喜欢处理抛出的异常(即使在 Python 代码中)但作为外来 C++ 线程的一部分执行的理论。因此,我构建了这个纯 Python 包装器,以便能够处理主 Python 线程中的回调。

import example
reload(example)
from example import MyExceptionType

condition = threading.Condition()
futures = []

# Actual handle executed by the main Python THREAD
# __after__ submitting all the jobs to the Cluster
# N is the number of jobs that were submitted to the Cluster
def handle(N):
while (N > 0):
condition.acquire()
try:
# wait for max of a second to prevent this thread waiting indefinitely
# when it misses notify while being busy processing responses
condition.wait(1.0)
for future in futures:
try:
print 'callback received! the response is:\n %s' % future.get()

except MyExceptionType as ex:
print 'MyExceptionType gracefully handled:' \
'\n message="%s"' % ex.message
except:
print 'Caught unhandled exception: %s "%s"' % (sys.exc_info()[0], sys.exc_info()[1])
finally:
N -= len(futures)
del(futures[:])
condition.release()

# callback called from a C++ boost THREAD
def callback(future):
condition.acquire()
try:
# do not consume the future here, rather let the main
# Python thread deal with it ...
futures.append(future)
condition.notify()
finally:
condition.release()

它并不理想,但它可以工作并且输出是正确的:

registering callback 1 ...
registering callback 2 ...
registering callback 3 ...
registering callback 4 ...
registering callback 5 ...
MyExceptionType gracefully handled:
message="Smoked too many Cohibas!"
MyExceptionType gracefully handled:
message="Smoked too many Cohibas!"
MyExceptionType gracefully handled:
message="Smoked too many Cohibas!"
MyExceptionType gracefully handled:
message="Smoked too many Cohibas!"
MyExceptionType gracefully handled:
message="Smoked too many Cohibas!"

Process finished with exit code 0

关于python - 如何防止 Python 返回到 C++ boost::python::error_already_set?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41283737/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com