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::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(); } }
static PyObject* communicatorFlushBatchRequests(CommunicatorObject* self, PyObject* args) { PyObject* compressBatchType = lookupType("Ice.CompressBatch"); PyObject* compressBatch; if(!PyArg_ParseTuple(args, STRCAST("O!"), compressBatchType, &compressBatch)) { return 0; } PyObjectHandle v = getAttr(compressBatch, "_value", false); assert(v.get()); Ice::CompressBatch cb = static_cast<Ice::CompressBatch>(PyLong_AsLong(v.get())); assert(self->communicator); try { AllowThreads allowThreads; // Release Python's global interpreter lock to avoid a potential deadlock. (*self->communicator)->flushBatchRequests(cb); } catch(const Ice::Exception& ex) { setPythonException(ex); return 0; } Py_INCREF(Py_None); return Py_None; }
Ice::ValuePtr IcePy::FactoryWrapper::create(const string& id) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. // // Get the type information. // ValueInfoPtr info = getValueInfo(id); if(!info) { return 0; } PyObjectHandle obj = PyObject_CallFunction(_valueFactory, STRCAST("s"), id.c_str()); if(!obj.get()) { assert(PyErr_Occurred()); throw AbortMarshaling(); } if(obj.get() == Py_None) { return 0; } return new ObjectReader(obj.get(), info); }
void IcePy::UpdateCallbackWrapper::updated(const Ice::PropertyDict& dict) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. PyObjectHandle result = PyDict_New(); if(result.get()) { for(Ice::PropertyDict::const_iterator p = dict.begin(); p != dict.end(); ++p) { PyObjectHandle key = createString(p->first); PyObjectHandle val = createString(p->second); if(!val.get() || PyDict_SetItem(result.get(), key.get(), val.get()) < 0) { return; } } } PyObjectHandle obj = PyObject_CallMethod(_callback, STRCAST("updated"), STRCAST("O"), result.get()); if(!obj.get()) { assert(PyErr_Occurred()); throw AbortMarshaling(); } }
void IcePy::handleSystemExit(PyObject* ex) { // // This code is similar to handle_system_exit in pythonrun.c. // PyObjectHandle code; if(PyExceptionInstance_Check(ex)) { code = getAttr(ex, "code", true); } else { code = ex; Py_INCREF(ex); } int status; if(PyLong_Check(code.get())) { status = static_cast<int>(PyLong_AsLong(code.get())); } else { PyObject_Print(code.get(), stderr, Py_PRINT_RAW); PySys_WriteStderr(STRCAST("\n")); status = 1; } code = 0; Py_Exit(status); }
void IcePy::setPythonException(const Ice::Exception& ex) { PyObjectHandle p = convertException(ex); if(p.get()) { setPythonException(p.get()); } }
PyObject* IcePy::callMethod(PyObject* obj, const string& name, PyObject* arg1, PyObject* arg2) { PyObjectHandle method = PyObject_GetAttrString(obj, const_cast<char*>(name.c_str())); if(!method.get()) { return 0; } return callMethod(method.get(), arg1, arg2); }
void IcePy::LoggerWrapper::error(const string& message) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. PyObjectHandle tmp = PyObject_CallMethod(_logger.get(), STRCAST("error"), STRCAST("s"), message.c_str()); if(!tmp.get()) { throwPythonException(); } }
string IcePy::LoggerWrapper::getPrefix() { AdoptThread adoptThread; PyObjectHandle tmp = PyObject_CallMethod(_logger.get(), STRCAST("getPrefix"), 0); if(!tmp.get()) { throwPythonException(); } return getString(tmp.get()); }
Ice::ObjectAdapterPtr IcePy::unwrapObjectAdapter(PyObject* obj) { #ifndef NDEBUG PyObject* wrapperType = lookupType("Ice.ObjectAdapterI"); #endif assert(wrapperType); assert(PyObject_IsInstance(obj, wrapperType)); PyObjectHandle impl = PyObject_GetAttrString(obj, STRCAST("_impl")); assert(impl.get()); return getObjectAdapter(impl.get()); }
Ice::LoggerPtr IcePy::LoggerWrapper::cloneWithPrefix(const string& prefix) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. PyObjectHandle tmp = PyObject_CallMethod(_logger.get(), STRCAST("cloneWithPrefix"), STRCAST("s"), prefix.c_str()); if(!tmp.get()) { throwPythonException(); } return new LoggerWrapper(tmp.get()); }
bool IcePy::getIdentity(PyObject* p, Ice::Identity& ident) { assert(checkIdentity(p)); PyObjectHandle name = getAttr(p, "name", true); PyObjectHandle category = getAttr(p, "category", true); if(name.get()) { if(!checkString(name.get())) { PyErr_Format(PyExc_ValueError, STRCAST("identity name must be a string")); return false; } ident.name = getString(name.get()); } if(category.get()) { if(!checkString(category.get())) { PyErr_Format(PyExc_ValueError, STRCAST("identity category must be a string")); return false; } ident.category = getString(category.get()); } return true; }
static PyObject* communicatorFlushBatchRequestsAsync(CommunicatorObject* self, PyObject* args, PyObject* /*kwds*/) { PyObject* compressBatchType = lookupType("Ice.CompressBatch"); PyObject* compressBatch; if(!PyArg_ParseTuple(args, STRCAST("O!"), compressBatchType, &compressBatch)) { return 0; } PyObjectHandle v = getAttr(compressBatch, "_value", false); assert(v.get()); Ice::CompressBatch cb = static_cast<Ice::CompressBatch>(PyLong_AsLong(v.get())); assert(self->communicator); const string op = "flushBatchRequests"; FlushAsyncCallbackPtr d = new FlushAsyncCallback(op); Ice::Callback_Communicator_flushBatchRequestsPtr callback = Ice::newCallback_Communicator_flushBatchRequests(d, &FlushAsyncCallback::exception, &FlushAsyncCallback::sent); Ice::AsyncResultPtr result; try { result = (*self->communicator)->begin_flushBatchRequests(cb, callback); } catch(const Ice::Exception& ex) { setPythonException(ex); return 0; } PyObjectHandle asyncResultObj = createAsyncResult(result, 0, 0, self->wrapper); if(!asyncResultObj.get()) { return 0; } PyObjectHandle future = createFuture(op, asyncResultObj.get()); if(!future.get()) { return 0; } d->setFuture(future.get()); return future.release(); }
template<typename T> PyObject* createVersion(const T& version, const char* type) { PyObject* versionType = lookupType(type); PyObjectHandle obj = PyObject_CallObject(versionType, 0); if(!obj.get()) { return 0; } if(!setVersion<T>(obj.get(), version, type)) { return 0; } return obj.release(); }
PyObject* IcePy::createIdentity(const Ice::Identity& ident) { PyObject* identityType = lookupType("Ice.Identity"); PyObjectHandle obj = PyObject_CallObject(identityType, 0); if(!obj.get()) { return 0; } if(!setIdentity(obj.get(), ident)) { return 0; } return obj.release(); }
static PyObject* implicitContextGetContext(ImplicitContextObject* self) { Ice::Context ctx = (*self->implicitContext)->getContext(); PyObjectHandle dict = PyDict_New(); if(!dict.get()) { return 0; } if(!contextToDictionary(ctx, dict.get())) { return 0; } return dict.release(); }
static PyObject* communicatorProxyToProperty(CommunicatorObject* self, PyObject* args) { // // We don't want to accept None here, so we can specify ProxyType and force // the caller to supply a proxy object. // PyObject* proxyObj; PyObject* strObj; if(!PyArg_ParseTuple(args, STRCAST("O!O"), &ProxyType, &proxyObj, &strObj)) { return 0; } Ice::ObjectPrx proxy = getProxy(proxyObj); string str; if(!getStringArg(strObj, "property", str)) { return 0; } assert(self->communicator); Ice::PropertyDict dict; try { dict = (*self->communicator)->proxyToProperty(proxy, str); } catch(const Ice::Exception& ex) { setPythonException(ex); return 0; } PyObjectHandle result = PyDict_New(); if(result.get()) { for(Ice::PropertyDict::iterator p = dict.begin(); p != dict.end(); ++p) { PyObjectHandle key = createString(p->first); PyObjectHandle val = createString(p->second); if(!val.get() || PyDict_SetItem(result.get(), key.get(), val.get()) < 0) { return 0; } } } return result.release(); }
Ice::ValuePtr IcePy::DefaultValueFactory::create(const string& id) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. Ice::ValuePtr v; // // Give the application-provided default factory a chance to create the object first. // if(_delegate) { v = _delegate->create(id); if(v) { return v; } } // // Get the type information. // ValueInfoPtr info = getValueInfo(id); if(!info) { return 0; } // // Instantiate the object. // PyTypeObject* type = reinterpret_cast<PyTypeObject*>(info->pythonType.get()); PyObjectHandle args = PyTuple_New(0); PyObjectHandle obj = type->tp_new(type, args.get(), 0); if(!obj.get()) { assert(PyErr_Occurred()); throw AbortMarshaling(); } return new ObjectReader(obj.get(), info); }
void IcePy::Dispatcher::dispatch(const Ice::DispatcherCallPtr& call, const Ice::ConnectionPtr& con) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. DispatcherCallObject* obj = reinterpret_cast<DispatcherCallObject*>(DispatcherCallType.tp_alloc(&DispatcherCallType, 0)); if(!obj) { return; } obj->call = new Ice::DispatcherCallPtr(call); PyObjectHandle c = createConnection(con, _communicator); PyObjectHandle tmp = PyObject_CallFunction(_dispatcher.get(), STRCAST("OO"), obj, c.get()); Py_DECREF(reinterpret_cast<PyObject*>(obj)); if(!tmp.get()) { throwPythonException(); } }
static PyObject* adapterGetPublishedEndpoints(ObjectAdapterObject* self) { assert(self->adapter); Ice::EndpointSeq endpoints; try { endpoints = (*self->adapter)->getPublishedEndpoints(); } catch(const Ice::Exception& ex) { setPythonException(ex); return 0; } int count = static_cast<int>(endpoints.size()); PyObjectHandle result = PyTuple_New(count); int i = 0; for(Ice::EndpointSeq::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p, ++i) { PyObjectHandle endp = createEndpoint(*p); if(!endp.get()) { return 0; } PyTuple_SET_ITEM(result.get(), i, endp.release()); // PyTuple_SET_ITEM steals a reference. } return result.release(); }
template<typename T> bool getVersion(PyObject* p, T& v, const char* type) { assert(checkIsInstance(p, type)); PyObjectHandle major = getAttr(p, "major", false); PyObjectHandle minor = getAttr(p, "minor", false); if(major.get()) { major = PyNumber_Long(major.get()); if(!major.get()) { PyErr_Format(PyExc_ValueError, STRCAST("version major must be a numeric value")); return false; } long m = PyLong_AsLong(major.get()); if(m < 0 || m > 255) { PyErr_Format(PyExc_ValueError, STRCAST("version major must be a value between 0 and 255")); return false; } v.major = static_cast<Ice::Byte>(m); } if(minor.get()) { major = PyNumber_Long(minor.get()); if(!minor.get()) { PyErr_Format(PyExc_ValueError, STRCAST("version minor must be a numeric value")); return false; } long m = PyLong_AsLong(minor.get()); if(m < 0 || m > 255) { PyErr_Format(PyExc_ValueError, STRCAST("version minor must be a value between 0 and 255")); return false; } v.minor = static_cast<Ice::Byte>(m); } return true; }
static PyObject* propertiesGetPropertiesForPrefix(PropertiesObject* self, PyObject* args) { PyObject* prefixObj; if(!PyArg_ParseTuple(args, STRCAST("O"), &prefixObj)) { return 0; } string prefix; if(!getStringArg(prefixObj, "prefix", prefix)) { return 0; } assert(self->properties); Ice::PropertyDict dict; try { dict = (*self->properties)->getPropertiesForPrefix(prefix); } catch(const Ice::Exception& ex) { setPythonException(ex); return 0; } PyObjectHandle result = PyDict_New(); if(result.get()) { for(Ice::PropertyDict::iterator p = dict.begin(); p != dict.end(); ++p) { PyObjectHandle key = createString(p->first); PyObjectHandle val = createString(p->second); if(!val.get() || PyDict_SetItem(result.get(), key.get(), val.get()) < 0) { return 0; } } } return result.release(); }
PyObject* IcePy_identityToString(PyObject* /*self*/, PyObject* args) { PyObject* identityType = lookupType("Ice.Identity"); PyObject* obj; PyObject* mode = 0; if(!PyArg_ParseTuple(args, STRCAST("O!O"), identityType, &obj, &mode)) { return 0; } Ice::Identity id; if(!getIdentity(obj, id)) { return 0; } Ice::ToStringMode toStringMode = Ice::Unicode; if(mode != Py_None && PyObject_HasAttrString(mode, STRCAST("value"))) { PyObjectHandle modeValue = getAttr(mode, "value", true); toStringMode = static_cast<Ice::ToStringMode>(PyLong_AsLong(modeValue.get())); } string str; try { str = identityToString(id, toStringMode); } catch(const Ice::Exception& ex) { setPythonException(ex); return 0; } return createString(str); }
string IcePy::getString(PyObject* p) { assert(p == Py_None || checkString(p)); string str; if(p != Py_None) { #if PY_VERSION_HEX >= 0x03000000 PyObjectHandle bytes = PyUnicode_AsUTF8String(p); if(bytes.get()) { char* s; Py_ssize_t sz; PyBytes_AsStringAndSize(bytes.get(), &s, &sz); str.assign(s, sz); } #else str.assign(PyString_AS_STRING(p), PyString_GET_SIZE(p)); #endif } return str; }
PyObject* IcePy::lookupType(const string& typeName) { string::size_type dot = typeName.rfind('.'); assert(dot != string::npos); string moduleName = typeName.substr(0, dot); string name = typeName.substr(dot + 1); // // First search for the module in sys.modules. // PyObject* sysModules = PyImport_GetModuleDict(); assert(sysModules); PyObject* module = PyDict_GetItemString(sysModules, const_cast<char*>(moduleName.c_str())); PyObject* dict; if(!module) { // // Not found, so we need to import the module. // PyObjectHandle h = PyImport_ImportModule(const_cast<char*>(moduleName.c_str())); if(!h.get()) { return 0; } dict = PyModule_GetDict(h.get()); } else { dict = PyModule_GetDict(module); } assert(dict); return PyDict_GetItemString(dict, const_cast<char*>(name.c_str())); }
PyObject* IcePy::callMethod(PyObject* method, PyObject* arg1, PyObject* arg2) { PyObjectHandle args; if(arg1 && arg2) { args = PyTuple_New(2); if(!args.get()) { return 0; } PyTuple_SET_ITEM(args.get(), 0, incRef(arg1)); PyTuple_SET_ITEM(args.get(), 1, incRef(arg2)); } else if(arg1) { args = PyTuple_New(1); if(!args.get()) { return 0; } PyTuple_SET_ITEM(args.get(), 0, incRef(arg1)); } else if(arg2) { args = PyTuple_New(1); if(!args.get()) { return 0; } PyTuple_SET_ITEM(args.get(), 0, incRef(arg2)); } else { args = PyTuple_New(0); if(!args.get()) { return 0; } } return PyObject_Call(method, args.get(), 0); }
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(); } } }
static PyObject* wssConnectionInfoGetHeaders(ConnectionInfoObject* self) { IceSSL::WSSConnectionInfoPtr info = IceSSL::WSSConnectionInfoPtr::dynamicCast(*self->connectionInfo); assert(info); PyObjectHandle result = PyDict_New(); if(result.get()) { for(Ice::HeaderDict::iterator p = info->headers.begin(); p != info->headers.end(); ++p) { PyObjectHandle key = createString(p->first); PyObjectHandle val = createString(p->second); if(!val.get() || PyDict_SetItem(result.get(), key.get(), val.get()) < 0) { return 0; } } } return result.release(); }
static PyObject* communicatorFindAllAdminFacets(CommunicatorObject* self) { assert(self->communicator); Ice::FacetMap facetMap; try { facetMap = (*self->communicator)->findAllAdminFacets(); } catch(const Ice::Exception& ex) { setPythonException(ex); return 0; } PyObjectHandle result = PyDict_New(); if(!result.get()) { return 0; } PyTypeObject* objectType = reinterpret_cast<PyTypeObject*>(lookupType("Ice.Object")); PyObjectHandle plainObject = objectType->tp_alloc(objectType, 0); for(Ice::FacetMap::const_iterator p = facetMap.begin(); p != facetMap.end(); ++p) { PyObjectHandle obj = plainObject; ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(p->second); if(wrapper) { obj = wrapper->getObject(); } else { Ice::NativePropertiesAdminPtr props = Ice::NativePropertiesAdminPtr::dynamicCast(p->second); if(props) { obj = createNativePropertiesAdmin(props); } } if(PyDict_SetItemString(result.get(), const_cast<char*>(p->first.c_str()), obj.get()) < 0) { return 0; } } return result.release(); }