20#include <config_folders.h> 
   25#include <osl/diagnose.h> 
   26#include <osl/thread.h> 
   27#include <osl/module.h> 
   28#include <osl/process.h> 
   29#include <rtl/ustrbuf.hxx> 
   30#include <rtl/bootstrap.hxx> 
   33#include <typelib/typedescription.hxx> 
   35#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> 
   36#include <com/sun/star/beans/XMaterialHolder.hpp> 
   37#include <com/sun/star/beans/theIntrospection.hpp> 
   38#include <com/sun/star/container/XHierarchicalNameAccess.hpp> 
   39#include <com/sun/star/script/Converter.hpp> 
   40#include <com/sun/star/script/InvocationAdapterFactory.hpp> 
   41#include <com/sun/star/script/XInvocation2.hpp> 
   42#include <com/sun/star/reflection/theCoreReflection.hpp> 
   43#include <com/sun/star/lang/XSingleServiceFactory.hpp> 
   51using com::sun::star::uno::XInterface;
 
   52using com::sun::star::uno::Any;
 
   53using com::sun::star::uno::TypeDescription;
 
   55using com::sun::star::uno::Type;
 
   56using com::sun::star::uno::UNO_QUERY;
 
   57using com::sun::star::uno::Exception;
 
   58using com::sun::star::uno::RuntimeException;
 
   59using com::sun::star::uno::XComponentContext;
 
   60using com::sun::star::lang::WrappedTargetRuntimeException;
 
   61using com::sun::star::lang::XSingleServiceFactory;
 
   62using com::sun::star::lang::XUnoTunnel;
 
   63using com::sun::star::reflection::theCoreReflection;
 
   64using com::sun::star::reflection::InvocationTargetException;
 
   65using com::sun::star::script::Converter;
 
   66using com::sun::star::script::XTypeConverter;
 
   67using com::sun::star::script::XInvocation;
 
   68using com::sun::star::beans::XMaterialHolder;
 
   69using com::sun::star::beans::theIntrospection;
 
   76    PyVarObject_HEAD_INIT (&PyType_Type, 0)
 
   81#
if PY_VERSION_HEX >= 0x03080000
 
  127#
if PY_VERSION_HEX >= 0x03040000
 
  129#
if PY_VERSION_HEX >= 0x03080000
 
  131#
if PY_VERSION_HEX < 0x03090000
 
  133#pragma clang diagnostic push
 
  134#pragma clang diagnostic ignored 
"-Wdeprecated-declarations" 
  138#pragma clang diagnostic pop
 
  151    PyThreadState * state = PyThreadState_Get();
 
  154        throw RuntimeException( 
"python global interpreter must be held (thread must be attached)" );
 
  157    PyObject* pModule = PyImport_AddModule(
"__main__");
 
  164    globalDict = 
PyRef( PyModule_GetDict(pModule));
 
  166    if( ! globalDict.
is() ) 
 
  170    runtimeImpl = PyDict_GetItemString( globalDict.
get() , 
"pyuno_runtime" );
 
  178    if( PyErr_Occurred() )
 
  180        PyRef excType, excValue, excTraceback;
 
  181        PyErr_Fetch( 
reinterpret_cast<PyObject **
>(&excType), 
reinterpret_cast<PyObject**
>(&excValue), 
reinterpret_cast<PyObject**
>(&excTraceback));
 
  185        PyRef str( PyObject_Str( excTraceback.
get() ), SAL_NO_ACQUIRE );
 
  188        buf.append( 
"python object raised an unknown exception (" );
 
  189        PyRef valueRep( PyObject_Repr( excValue.
get() ), SAL_NO_ACQUIRE );
 
  190        buf.appendAscii( PyUnicode_AsUTF8( valueRep.
get())).append( 
", traceback follows\n" );
 
  191        buf.appendAscii( PyUnicode_AsUTF8( str.
get() ) );
 
  204    osl_getModuleURLFromFunctionAddress(
 
  207    fileName = fileName.copy( fileName.lastIndexOf( 
'/' )+1 );
 
  209    fileName += 
"../" LIBO_ETC_FOLDER 
"/";
 
  212    rtl::Bootstrap bootstrapHandle( fileName );
 
  215    if( bootstrapHandle.getFrom( 
"PYUNO_LOGLEVEL", str ) )
 
  219        else if ( str == 
"CALL" )
 
  221        else if ( str == 
"ARGS" )
 
  225            fprintf( stderr, 
"unknown loglevel %s\n",
 
  233    if( !bootstrapHandle.getFrom( 
"PYUNO_LOGTARGET", str ) )
 
  236    if ( str == 
"stdout" )
 
  238    else if ( str == 
"stderr" )
 
  243        data.Size = 
sizeof( data );
 
  245            nullptr , osl_Process_IDENTIFIER , &data );
 
  246        osl_getSystemPathFromFileURL( str.pData, &str.pData);
 
  249        o += OString::number( data.Ident );
 
  251        *ppFile = fopen( o.getStr() , 
"w" );
 
  255            setvbuf( *ppFile, 
nullptr, _IONBF, 0 );
 
  259            fprintf( stderr, 
"couldn't create file %s\n",
 
  284        ctx->getServiceManager()->createInstanceWithContext(
 
  285            "com.sun.star.script.Invocation",
 
  287        css::uno::UNO_QUERY_THROW );
 
  291        throw RuntimeException( 
"pyuno: couldn't instantiate typeconverter service" );
 
  299    Any a = 
ctx->getValueByName(
"/singletons/com.sun.star.reflection.theTypeDescriptionManager");
 
  302        throw RuntimeException( 
"pyuno: couldn't retrieve typedescriptionmanager" );
 
  305    return PyRef( 
reinterpret_cast< PyObject * 
> ( me ), SAL_NO_ACQUIRE );
 
  320    PyRef globalDict, runtime;
 
  324    if( runtime.
is() && 
impl->cargo->valid )
 
  326        throw RuntimeException(
"pyuno runtime has already been initialized before" );
 
  329    PyDict_SetItemString( globalDict.
get(), 
"pyuno_runtime" , keep.
get() );
 
  330    Py_XINCREF( keep.
get() );
 
  336    PyRef globalDict, runtime;
 
  339    return runtime.
is() && 
impl->cargo->valid;
 
  345    PyRef globalDict, runtime;
 
  350            "pyuno runtime is not initialized, " 
  351            "(the pyuno.bootstrap needs to be called before using any uno classes)" );
 
  354    Py_XINCREF( runtime.
get() );
 
  360    Py_XINCREF( 
reinterpret_cast< PyObject * 
>(
impl) );
 
  365    Py_XDECREF( 
reinterpret_cast< PyObject * 
>(
impl) );
 
  370    PyRef temp( 
reinterpret_cast< PyObject * 
>(r.
impl) );
 
  371    Py_XINCREF( temp.
get() );
 
  372    Py_XDECREF( 
reinterpret_cast< PyObject * 
>(
impl) );
 
  379    if( ! 
impl->cargo->valid )
 
  381        throw RuntimeException(
"pyuno runtime must be initialized before calling any2PyObject" );
 
  384    switch (
a.getValueTypeClass ())
 
  386    case css::uno::TypeClass_VOID:
 
  389        return PyRef(Py_None);
 
  391    case css::uno::TypeClass_CHAR:
 
  396    case css::uno::TypeClass_BOOLEAN:
 
  404    case css::uno::TypeClass_BYTE:
 
  405    case css::uno::TypeClass_SHORT:
 
  406    case css::uno::TypeClass_UNSIGNED_SHORT:
 
  407    case css::uno::TypeClass_LONG:
 
  411        return PyRef( PyLong_FromLong (l), SAL_NO_ACQUIRE );
 
  413    case css::uno::TypeClass_UNSIGNED_LONG:
 
  417        return PyRef( PyLong_FromUnsignedLong (l), SAL_NO_ACQUIRE );
 
  419    case css::uno::TypeClass_HYPER:
 
  423        return PyRef( PyLong_FromLongLong (l), SAL_NO_ACQUIRE);
 
  425    case css::uno::TypeClass_UNSIGNED_HYPER:
 
  429        return PyRef( PyLong_FromUnsignedLongLong (l), SAL_NO_ACQUIRE);
 
  431    case css::uno::TypeClass_FLOAT:
 
  435        return PyRef(PyFloat_FromDouble (f), SAL_NO_ACQUIRE);
 
  437    case css::uno::TypeClass_DOUBLE:
 
  441        return PyRef( PyFloat_FromDouble (
d), SAL_NO_ACQUIRE);
 
  443    case css::uno::TypeClass_STRING:
 
  449    case css::uno::TypeClass_TYPE:
 
  456                o.getStr(),  
t.getTypeClass(), *
this),
 
  459    case css::uno::TypeClass_ANY:
 
  465    case css::uno::TypeClass_ENUM:
 
  467        sal_Int32 l = *
static_cast<sal_Int32 
const *
>(
a.getValue());
 
  468        TypeDescription desc( 
a.getValueType() );
 
  472            typelib_EnumTypeDescription *pEnumDesc =
 
  473                reinterpret_cast<typelib_EnumTypeDescription *
>(desc.get());
 
  474            for( 
int i = 0 ; 
i < pEnumDesc->nEnumValues ; 
i ++ )
 
  476                if( pEnumDesc->pEnumValues[
i] == l )
 
  478                    OString 
v = 
OUStringToOString( OUString::unacquired(&pEnumDesc->ppEnumNames[
i]), RTL_TEXTENCODING_ASCII_US);
 
  479                    OString e = 
OUStringToOString( OUString::unacquired(&pEnumDesc->aBase.pTypeName), RTL_TEXTENCODING_ASCII_US);
 
  485                " with invalid value " + OUString::number(l) );
 
  487    case css::uno::TypeClass_EXCEPTION:
 
  488    case css::uno::TypeClass_STRUCT:
 
  490        PyRef excClass = 
getClass( 
a.getValueType().getTypeName(), *
this );
 
  492        PyRef argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE, 
NOT_NULL );
 
  493        PyTuple_SetItem( argsTuple.
get() , 0 , 
value.getAcquired() );
 
  494        PyRef ret( PyObject_CallObject( excClass.
get() , argsTuple.
get() ), SAL_NO_ACQUIRE );
 
  497            throw RuntimeException( 
"Couldn't instantiate python representation of structured UNO type " +
 
  498                        a.getValueType().getTypeName() );
 
  501        if( 
auto e = o3tl::tryAccess<css::uno::Exception>(
a) )
 
  510            PyObject_SetAttrString( ret.
get(), 
"args", 
args.get() );
 
  514    case css::uno::TypeClass_SEQUENCE:
 
  519        if( 
a >>= byteSequence )
 
  529            PyRef tuple( PyTuple_New (s.getLength()), SAL_NO_ACQUIRE, 
NOT_NULL);
 
  533                for ( 
i = 0; 
i < s.getLength (); 
i++)
 
  536                    OSL_ASSERT( element.
is() );
 
  540            catch( css::uno::Exception & )
 
  542                for( ; 
i < s.getLength() ; 
i ++ )
 
  544                    Py_INCREF( Py_None );
 
  545                    PyTuple_SetItem( tuple.
get(), 
i,  Py_None );
 
  552    case css::uno::TypeClass_INTERFACE:
 
  556        if (!tmp_interface.is ())
 
  563        throw RuntimeException( 
"Unknown UNO type class " + OUString::number(
static_cast<int>(
a.getValueTypeClass())) );
 
  572    PyRef method( PyObject_GetAttrString( o , 
"getTypes" ), SAL_NO_ACQUIRE );
 
  574    if( method.
is() && PyCallable_Check( method.
get() ) )
 
  576        PyRef types( PyObject_CallObject( method.
get(), 
nullptr ) , SAL_NO_ACQUIRE );
 
  578        if( types.
is() && PyTuple_Check( types.
get() ) )
 
  580            int size = PyTuple_Size( types.
get() );
 
  583            ret.realloc( 
size + 1 );
 
  584            auto pret = ret.getArray();
 
  585            for( 
int i = 0 ; 
i < 
size ; 
i ++ )
 
  600    buf.append(
"Couldn't convert ");
 
  601    PyRef reprString( PyObject_Str(o), SAL_NO_ACQUIRE );
 
  602    buf.appendAscii( PyUnicode_AsUTF8(reprString.
get()) );
 
  603    buf.append(
" to a UNO type");
 
  606        buf.append(
"; caught exception: ");
 
  607        buf.append(*pWrapped);
 
  609    return buf.makeStringAndClear();
 
  616    if( !PyIter_Check( pObj ))
 
  619    PyObject *pItem = PyIter_Next( pObj );
 
  622        if( PyErr_Occurred() )
 
  630    ::std::vector<Any> items;
 
  633        PyRef rItem( pItem, SAL_NO_ACQUIRE );
 
  635        pItem = PyIter_Next( pObj );
 
  646        throw RuntimeException(
"pyuno runtime must be initialized before calling any2PyObject" );
 
  650    PyObject *o = source.
get();
 
  655    else if (PyLong_Check (o))
 
  662        else if(o == Py_False)
 
  668        sal_Int64 l = 
static_cast<sal_Int64
>(PyLong_AsLong (o));
 
  669        if( l < 128 && l >= -128 )
 
  674        else if( l <= 0x7fff && l >= -0x8000 )
 
  676            sal_Int16 s = 
static_cast<sal_Int16
>(l);
 
  679        else if( l <= SAL_CONST_INT64(0x7fffffff) &&
 
  680                 l >= -SAL_CONST_INT64(0x80000000) )
 
  682            sal_Int32 l32 = 
static_cast<sal_Int32
>(l);
 
  691    else if (PyFloat_Check (o))
 
  693        double d = PyFloat_AsDouble (o);
 
  696    else if (PyBytes_Check(o) || PyUnicode_Check(o))
 
  700    else if (PyTuple_Check (o))
 
  703        auto sRange = asNonConstRange(s);
 
  704        for (Py_ssize_t 
i = 0; 
i < PyTuple_Size (o); 
i++)
 
  710    else if (PyList_Check (o))
 
  712        Py_ssize_t l = PyList_Size (o);
 
  714        auto sRange = asNonConstRange(s);
 
  715        for (Py_ssize_t 
i = 0; 
i < l; 
i++)
 
  727            PyRef str(PyObject_GetAttrString( o , 
"value" ),SAL_NO_ACQUIRE);
 
  729            if( PyBytes_Check( str.
get() ) )
 
  732                    reinterpret_cast<sal_Int8*
>(PyBytes_AsString(str.
get())), PyBytes_Size(str.
get()));
 
  748            PyRef struc(PyObject_GetAttrString( o , 
"value" ),SAL_NO_ACQUIRE);
 
  754                    "struct or exception wrapper does not support XMaterialHolder" );
 
  757            a = holder->getMaterial();
 
  769            a = my_mh->getMaterial();
 
  780                    "uno.Any instance not accepted during method call, " 
  781                    "use uno.invoke instead" );
 
  792            catch( 
const css::uno::Exception & e )
 
  795                throw WrappedTargetRuntimeException(
 
  796                        e.Message, e.Context, anyEx);
 
  806            PyRef2Adapter::iterator ii = 
impl->cargo->mappedObjects.find( 
PyRef( o ) );
 
  807            if( ii != 
impl->cargo->mappedObjects.end() )
 
  809                adapterObject = ii->second;
 
  812            if( adapterObject.is() )
 
  815                auto pAdapter = comphelper::getFromUnoTunnel<Adapter>(adapterObject);
 
  817                mappedObject = 
impl->cargo->xAdapterFactory->createAdapter(
 
  818                    adapterObject, pAdapter->getWrappedTypes() );
 
  824                    if (interfaces.getLength())
 
  829                                pAdapter, interfaces );
 
  833                            css::uno::WeakReference< XInvocation > ( pAdapter );
 
  835                } 
catch (InvocationTargetException 
const& e) {
 
  837                    throw WrappedTargetRuntimeException( 
 
  838                            msg, e.Context, e.TargetException);
 
  841            if( mappedObject.is() )
 
  859    if( excTraceback.
is() )
 
  867                unoModule = 
impl->cargo->getUnoModule();
 
  876            PyRef extractTraceback(
 
  877                PyDict_GetItemString(unoModule.
get(),
"_uno_extract_printable_stacktrace" ) );
 
  879            if( PyCallable_Check(extractTraceback.
get()) )
 
  883                PyRef pyStr( PyObject_CallObject( extractTraceback.
get(),
args.get() ), SAL_NO_ACQUIRE);
 
  884                str = OUString::fromUtf8(PyUnicode_AsUTF8(pyStr.
get()));
 
  888                str = 
"Couldn't find uno._uno_extract_printable_stacktrace";
 
  893            str = 
"Could not load uno.py, no stacktrace available";
 
  894            if ( !e.Message.isEmpty() )
 
  896                str += 
" (Error loading uno.py: " + e.Message + 
")";
 
  904        str = 
"no traceback available";
 
  917            buf.appendAscii( PyUnicode_AsUTF8( 
typeName.get() ) );
 
  921            buf.append( 
"no typename available" );
 
  924        PyRef valueRep( PyObject_Str( excValue.
get() ), SAL_NO_ACQUIRE );
 
  927            buf.appendAscii( PyUnicode_AsUTF8( valueRep.
get()));
 
  931            buf.append( 
"Couldn't convert exception value to a string" );
 
  933        buf.append( 
", traceback follows\n" );
 
  941            buf.append( 
", no traceback available\n" );
 
  944        e.Message = buf.makeStringAndClear();
 
  945#if OSL_DEBUG_LEVEL > 0 
  946        fprintf( stderr, 
"Python exception: %s\n",
 
  956    : m_isNewState(false)
 
  960    tstate = PyGILState_GetThisThreadState(); 
 
  964        tstate = PyThreadState_New( interp );
 
  968    PyEval_AcquireThread( 
tstate);
 
  975        PyThreadState_Clear( 
tstate );
 
  978        PyThreadState_DeleteCurrent();
 
  982        PyEval_ReleaseThread( 
tstate );
 
  988    tstate = PyThreadState_Get();
 
  989    PyEval_ReleaseThread( 
tstate );
 
  998    PyEval_AcquireThread( 
tstate );
 
css::uno::Type const & get()
 
Helper class for keeping references to python objects.
 
bool is() const
returns 1 when the reference points to a python object python object, otherwise 0.
 
PyObject * get() const noexcept
 
PyObject * getAcquired() const
 
~PyThreadAttach()
Releases the global interpreter lock and destroys the thread state.
 
PyThreadAttach(const PyThreadAttach &)=delete
 
~PyThreadDetach()
Acquires the global interpreter lock again.
 
PyThreadDetach()
Releases the global interpreter lock.
 
The pyuno::Runtime class keeps the internal state of the python UNO bridge for the currently in use p...
 
static bool isInitialized()
Checks, whether the uno runtime is already initialized in the current python interpreter.
 
css::uno::Any extractUnoException(const PyRef &excType, const PyRef &excValue, const PyRef &excTraceback) const
extracts a proper uno exception from a given python exception
 
css::uno::Any pyObject2Any(const PyRef &source, enum ConversionMode mode=REJECT_UNO_ANY) const
converts a Python object to a UNO any
 
PyRef any2PyObject(const css::uno::Any &source) const
converts something contained in a UNO Any to a Python object
 
Runtime & operator=(const Runtime &)
 
RuntimeImpl * getImpl() const
Returns the internal handle.
 
Runtime()
preconditions: python has been initialized before, the global interpreter lock is held and pyuno has ...
 
static void initialize(const css::uno::Reference< css::uno::XComponentContext > &ctx)
Initializes the python-UNO bridge.
 
bool pyIterUnpack(PyObject *const, css::uno::Any &) const
Safely unpacks a Python iterator into a sequence, then stores it in an Any.
 
#define SAL_CONFIGFILE(name)
 
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
 
Any SAL_CALL getCaughtException()
 
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
 
struct stRuntimeImpl RuntimeImpl
 
void log(RuntimeCargo *cargo, sal_Int32 level, std::u16string_view logString)
 
void raiseInvocationTargetExceptionWhenNeeded(const Runtime &runtime)
 
PyObject * PyUNO_Type_new(const char *typeName, css::uno::TypeClass t, const Runtime &r)
 
bool isInstanceOfStructOrException(PyObject *obj)
 
PyRef PyUNO_new(const Any &targetInterface, const Reference< XSingleServiceFactory > &ssf)
 
static OUString lcl_ExceptionMessage(PyObject *const o, OUString const *const pWrapped)
 
PyRef getCharClass(const Runtime &)
 
PyRef getPyUnoStructClass()
 
PyObject * PyUNO_ByteSequence_new(const css::uno::Sequence< sal_Int8 > &, const Runtime &r)
 
PyObject * PyUNO_char_new(sal_Unicode c, const Runtime &r)
 
static PyTypeObject RuntimeImpl_Type
 
PyRef ustring2PyString(std::u16string_view source)
 
sal_Unicode PyChar2Unicode(PyObject *o)
 
PyObject * PyUNO_Enum_new(const char *enumBase, const char *enumValue, const Runtime &r)
 
PyRef getTypeClass(const Runtime &)
 
PyRef getEnumClass(const Runtime &)
 
static void getRuntimeImpl(PyRef &globalDict, PyRef &runtimeImpl)
 
css::uno::Type PyType2Type(PyObject *o)
 
PyRef getByteSequenceClass(const Runtime &)
 
OUString pyString2ustring(PyObject *str)
 
static void readLoggingConfig(sal_Int32 *pLevel, FILE **ppFile)
 
@ NOT_NULL
definition of a no acquire enum for ctors
 
PyRef ustring2PyUnicode(const OUString &source)
 
PyRef getClass(const OUString &name, const Runtime &runtime)
 
css::uno::Any PyEnum2Enum(PyObject *obj)
 
static Sequence< Type > invokeGetTypes(const Runtime &r, PyObject *o)
 
PyRef getAnyClass(const Runtime &)
 
PyRef PyUNOStruct_new(const css::uno::Any &targetInterface, const css::uno::Reference< css::lang::XSingleServiceFactory > &ssf)
 
static PyRef importUnoModule()
 
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
 
css::uno::Any wrappedObject
 
css::uno::Reference< css::script::XInvocation2 > xInvocation
 
PyObject_HEAD PyUNOInternals * members
 
css::uno::Reference< css::script::XTypeConverter > xTypeConverter
 
css::uno::Reference< css::reflection::XIdlReflection > xCoreReflection
 
css::uno::Reference< css::lang::XSingleServiceFactory > xInvocation
 
css::uno::Reference< css::container::XHierarchicalNameAccess > xTdMgr
 
PyRef const & getUnoModule()
 
css::uno::Reference< css::beans::XIntrospection > xIntrospection
 
css::uno::Reference< css::script::XInvocationAdapterFactory2 > xAdapterFactory
 
css::uno::Reference< css::uno::XComponentContext > xContext
 
static PyRef create(const css::uno::Reference< css::uno::XComponentContext > &xContext)
 
PyObject_HEAD struct RuntimeCargo * cargo
 
static void del(PyObject *self)