void IcePy::ServantLocatorWrapper::finished(const Ice::Current& current, const Ice::ObjectPtr&, const Ice::LocalObjectPtr& cookie) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. CookiePtr c = CookiePtr::dynamicCast(cookie); assert(c); ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(c->servant); PyObjectHandle servantObj = wrapper->getObject(); PyObjectHandle res = PyObject_CallMethod(_locator, STRCAST("finished"), STRCAST("OOO"), c->current, servantObj.get(), c->cookie); if(PyErr_Occurred()) { PyException ex; // Retrieve the exception before another Python API call clears it. // // A locator that calls sys.exit() will raise the SystemExit exception. // This is normally caught by the interpreter, causing it to exit. // However, we have no way to pass this exception to the interpreter, // so we act on it directly. // ex.checkSystemExit(); PyObject* userExceptionType = lookupType("Ice.UserException"); if(PyObject_IsInstance(ex.ex.get(), userExceptionType)) { throw ExceptionWriter(ex.ex); } ex.raise(); } }
void translate_exc_py_to_cpp() { if (unlikely(describe_py_exception == nullptr)) { throw Error(MSG(err) << "describe_py_exception is uninitialized; " "can't check for and translate Python exception to C++ exception."); } if (likely(not check_for_py_exception())) { // no exception has occurred. return; } PyException pyex; describe_py_exception(&pyex); // recurse to throw a possible cause. try { translate_exc_py_to_cpp(); } catch (...) { pyex.store_cause(); } // throw exception without cause. throw pyex; }
void invoke(const Ice::ConnectionPtr& con) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. #ifndef NDEBUG ConnectionObject* c = reinterpret_cast<ConnectionObject*>(_con); assert(con == *(c->connection)); #endif PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), _con); assert(_cb); PyObjectHandle tmp = PyObject_Call(_cb, args.get(), 0); if(PyErr_Occurred()) { PyException ex; // Retrieve it before another Python API call clears it. // // A callback that calls sys.exit() will raise the SystemExit exception. // This is normally caught by the interpreter, causing it to exit. // However, we have no way to pass this exception to the interpreter, // so we act on it directly. // ex.checkSystemExit(); ex.raise(); } }
void IcePy::ServantLocatorWrapper::deactivate(const string& category) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. PyObjectHandle res = PyObject_CallMethod(_locator, STRCAST("deactivate"), STRCAST("s"), category.c_str()); if(PyErr_Occurred()) { PyException ex; // Retrieve the exception before another Python API call clears it. // // A locator that calls sys.exit() will raise the SystemExit exception. // This is normally caught by the interpreter, causing it to exit. // However, we have no way to pass this exception to the interpreter, // so we act on it directly. // ex.checkSystemExit(); ex.raise(); } }
void invoke(const string& methodName, const Ice::ConnectionPtr& con) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. #ifndef NDEBUG ConnectionObject* c = reinterpret_cast<ConnectionObject*>(_con); assert(con == *(c->connection)); #endif if(!PyObject_HasAttrString(_cb, STRCAST(methodName.c_str()))) { ostringstream ostr; ostr << "connection callback object does not define " << methodName << "()"; string str = ostr.str(); PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); } else { PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), _con); PyObjectHandle method = PyObject_GetAttrString(_cb, STRCAST(methodName.c_str())); assert(method.get()); PyObjectHandle tmp = PyObject_Call(method.get(), args.get(), 0); if(PyErr_Occurred()) { PyException ex; // Retrieve it before another Python API call clears it. // // A callback that calls sys.exit() will raise the SystemExit exception. // This is normally caught by the interpreter, causing it to exit. // However, we have no way to pass this exception to the interpreter, // so we act on it directly. // ex.checkSystemExit(); ex.raise(); } } }
Ice::ObjectPtr IcePy::ServantLocatorWrapper::locate(const Ice::Current& current, Ice::LocalObjectPtr& cookie) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. CookiePtr c = new Cookie; c->current = createCurrent(current); if(!c->current) { throwPythonException(); } // // Invoke locate on the Python object. We expect the object to // return either the servant by itself, or the servant in a tuple // with an optional cookie object. // PyObjectHandle res = PyObject_CallMethod(_locator, STRCAST("locate"), STRCAST("O"), c->current); if(PyErr_Occurred()) { PyException ex; // Retrieve the exception before another Python API call clears it. // // A locator that calls sys.exit() will raise the SystemExit exception. // This is normally caught by the interpreter, causing it to exit. // However, we have no way to pass this exception to the interpreter, // so we act on it directly. // ex.checkSystemExit(); PyObject* userExceptionType = lookupType("Ice.UserException"); if(PyObject_IsInstance(ex.ex.get(), userExceptionType)) { throw ExceptionWriter(ex.ex); } ex.raise(); } if(res.get() == Py_None) { return 0; } PyObject* servantObj = 0; PyObject* cookieObj = Py_None; if(PyTuple_Check(res.get())) { if(PyTuple_GET_SIZE(res.get()) > 2) { PyErr_Warn(PyExc_RuntimeWarning, STRCAST("invalid return value for ServantLocator::locate")); return 0; } servantObj = PyTuple_GET_ITEM(res.get(), 0); if(PyTuple_GET_SIZE(res.get()) > 1) { cookieObj = PyTuple_GET_ITEM(res.get(), 1); } } else { servantObj = res.get(); } // // Verify that the servant is an Ice object. // if(!PyObject_IsInstance(servantObj, _objectType)) { PyErr_Warn(PyExc_RuntimeWarning, STRCAST("return value of ServantLocator::locate is not an Ice object")); return 0; } // // Save state in our cookie and return a wrapper for the servant. // c->servant = createServantWrapper(servantObj); c->cookie = cookieObj; Py_INCREF(c->cookie); cookie = c; return c->servant; }
void IcePy::throwPythonException() { PyException ex; ex.raise(); }