1 /* -*- Mode: C++; eval:(c-set-style "bsd"); tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_folders.h>
22 #include "pyuno_impl.hxx"
24 #include <o3tl/any.hxx>
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>
31 #include <rtl/ref.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>
44 #include <comphelper/sequence.hxx>
45 #include <comphelper/servicehelper.hxx>
46 #include <cppuhelper/exc_hlp.hxx>
50 using com::sun::star::uno::Reference
;
51 using com::sun::star::uno::XInterface
;
52 using com::sun::star::uno::Any
;
53 using com::sun::star::uno::TypeDescription
;
54 using com::sun::star::uno::Sequence
;
55 using com::sun::star::uno::Type
;
56 using com::sun::star::uno::UNO_QUERY
;
57 using com::sun::star::uno::Exception
;
58 using com::sun::star::uno::RuntimeException
;
59 using com::sun::star::uno::XComponentContext
;
60 using com::sun::star::lang::WrappedTargetRuntimeException
;
61 using com::sun::star::lang::XSingleServiceFactory
;
62 using com::sun::star::lang::XUnoTunnel
;
63 using com::sun::star::reflection::theCoreReflection
;
64 using com::sun::star::reflection::InvocationTargetException
;
65 using com::sun::star::script::Converter
;
66 using com::sun::star::script::XTypeConverter
;
67 using com::sun::star::script::XInvocation
;
68 using com::sun::star::beans::XMaterialHolder
;
69 using com::sun::star::beans::theIntrospection
;
74 static PyTypeObject RuntimeImpl_Type
=
76 PyVarObject_HEAD_INIT (&PyType_Type
, 0)
81 #if PY_VERSION_HEX >= 0x03080000
82 0, // Py_ssize_t tp_vectorcall_offset
84 nullptr, // printfunc tp_print
127 #if PY_VERSION_HEX >= 0x03040000
129 #if PY_VERSION_HEX >= 0x03080000
130 , nullptr // vectorcallfunc tp_vectorcall
131 #if PY_VERSION_HEX < 0x03090000
132 #if defined __clang__
133 #pragma clang diagnostic push
134 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
136 , nullptr // tp_print
137 #if defined __clang__
138 #pragma clang diagnostic pop
145 /*----------------------------------------------------------------------
146 Runtime implementation
147 -----------------------------------------------------------------------*/
148 /// @throws css::uno::RuntimeException
149 static void getRuntimeImpl( PyRef
& globalDict
, PyRef
&runtimeImpl
)
151 PyThreadState
* state
= PyThreadState_Get();
154 throw RuntimeException( "python global interpreter must be held (thread must be attached)" );
157 PyObject
* pModule
= PyImport_AddModule("__main__");
161 throw RuntimeException("can't import __main__ module");
164 globalDict
= PyRef( PyModule_GetDict(pModule
));
166 if( ! globalDict
.is() ) // FATAL !
168 throw RuntimeException("can't find __main__ module");
170 runtimeImpl
= PyDict_GetItemString( globalDict
.get() , "pyuno_runtime" );
173 /// @throws RuntimeException
174 static PyRef
importUnoModule( )
176 // import the uno module
177 PyRef
module( PyImport_ImportModule( "uno" ), SAL_NO_ACQUIRE
, NOT_NULL
);
178 if( PyErr_Occurred() )
180 PyRef excType
, excValue
, excTraceback
;
181 PyErr_Fetch( reinterpret_cast<PyObject
**>(&excType
), reinterpret_cast<PyObject
**>(&excValue
), reinterpret_cast<PyObject
**>(&excTraceback
));
182 // As of Python 2.7 this gives a rather non-useful "<traceback object at 0xADDRESS>",
183 // but it is the best we can do in the absence of uno._uno_extract_printable_stacktrace
184 // Who knows, a future Python might print something better.
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() ) );
193 throw RuntimeException( buf
.makeStringAndClear() );
195 PyRef
dict( PyModule_GetDict( module
.get() ) );
199 static void readLoggingConfig( sal_Int32
*pLevel
, FILE **ppFile
)
201 *pLevel
= LogLevel::NONE
;
204 osl_getModuleURLFromFunctionAddress(
205 reinterpret_cast< oslGenericFunction
>(readLoggingConfig
),
207 fileName
= fileName
.copy( fileName
.lastIndexOf( '/' )+1 );
209 fileName
+= "../" LIBO_ETC_FOLDER
"/";
211 fileName
+= SAL_CONFIGFILE("pyuno" );
212 rtl::Bootstrap
bootstrapHandle( fileName
);
215 if( bootstrapHandle
.getFrom( "PYUNO_LOGLEVEL", str
) )
218 *pLevel
= LogLevel::NONE
;
219 else if ( str
== "CALL" )
220 *pLevel
= LogLevel::CALL
;
221 else if ( str
== "ARGS" )
222 *pLevel
= LogLevel::ARGS
;
225 fprintf( stderr
, "unknown loglevel %s\n",
226 OUStringToOString( str
, RTL_TEXTENCODING_UTF8
).getStr() );
229 if( *pLevel
<= LogLevel::NONE
)
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
);
247 OString o
= OUStringToOString( str
, osl_getThreadTextEncoding() );
249 o
+= OString::number( data
.Ident
);
251 *ppFile
= fopen( o
.getStr() , "w" );
254 // do not buffer (useful if e.g. analyzing a crash)
255 setvbuf( *ppFile
, nullptr, _IONBF
, 0 );
259 fprintf( stderr
, "couldn't create file %s\n",
260 OUStringToOString( str
, RTL_TEXTENCODING_UTF8
).getStr() );
266 /*-------------------------------------------------------------------
267 RuntimeImpl implementations
268 *-------------------------------------------------------------------*/
269 PyRef
stRuntimeImpl::create( const Reference
< XComponentContext
> &ctx
)
271 RuntimeImpl
*me
= PyObject_New (RuntimeImpl
, &RuntimeImpl_Type
);
273 throw RuntimeException( "cannot instantiate pyuno::RuntimeImpl" );
275 // must use a different struct here, as the PyObject_New
276 // makes C++ unusable
277 RuntimeCargo
*c
= new RuntimeCargo
;
278 readLoggingConfig( &(c
->logLevel
) , &(c
->logFile
) );
279 log( c
, LogLevel::CALL
, "Instantiating pyuno bridge" );
283 c
->xInvocation
= Reference
< XSingleServiceFactory
> (
284 ctx
->getServiceManager()->createInstanceWithContext(
285 "com.sun.star.script.Invocation",
287 css::uno::UNO_QUERY_THROW
);
289 c
->xTypeConverter
= Converter::create(ctx
);
290 if( ! c
->xTypeConverter
.is() )
291 throw RuntimeException( "pyuno: couldn't instantiate typeconverter service" );
293 c
->xCoreReflection
= theCoreReflection::get(ctx
);
295 c
->xAdapterFactory
= css::script::InvocationAdapterFactory::create(ctx
);
297 c
->xIntrospection
= theIntrospection::get(ctx
);
299 Any a
= ctx
->getValueByName("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
301 if( ! c
->xTdMgr
.is() )
302 throw RuntimeException( "pyuno: couldn't retrieve typedescriptionmanager" );
305 return PyRef( reinterpret_cast< PyObject
* > ( me
), SAL_NO_ACQUIRE
);
308 void stRuntimeImpl::del(PyObject
* self
)
310 RuntimeImpl
*me
= reinterpret_cast< RuntimeImpl
* > ( self
);
311 if( me
->cargo
->logFile
)
312 fclose( me
->cargo
->logFile
);
318 void Runtime::initialize( const Reference
< XComponentContext
> & ctx
)
320 PyRef globalDict
, runtime
;
321 getRuntimeImpl( globalDict
, runtime
);
322 RuntimeImpl
*impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
324 if( runtime
.is() && impl
->cargo
->valid
)
326 throw RuntimeException("pyuno runtime has already been initialized before" );
328 PyRef
keep( RuntimeImpl::create( ctx
) );
329 PyDict_SetItemString( globalDict
.get(), "pyuno_runtime" , keep
.get() );
330 Py_XINCREF( keep
.get() );
334 bool Runtime::isInitialized()
336 PyRef globalDict
, runtime
;
337 getRuntimeImpl( globalDict
, runtime
);
338 RuntimeImpl
*impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
339 return runtime
.is() && impl
->cargo
->valid
;
345 PyRef globalDict
, runtime
;
346 getRuntimeImpl( globalDict
, runtime
);
349 throw RuntimeException(
350 "pyuno runtime is not initialized, "
351 "(the pyuno.bootstrap needs to be called before using any uno classes)" );
353 impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
354 Py_XINCREF( runtime
.get() );
357 Runtime::Runtime( const Runtime
& r
)
360 Py_XINCREF( reinterpret_cast< PyObject
* >(impl
) );
365 Py_XDECREF( reinterpret_cast< PyObject
* >(impl
) );
368 Runtime
& Runtime::operator = ( const Runtime
& r
)
370 PyRef
temp( reinterpret_cast< PyObject
* >(r
.impl
) );
371 Py_XINCREF( temp
.get() );
372 Py_XDECREF( reinterpret_cast< PyObject
* >(impl
) );
377 PyRef
Runtime::any2PyObject (const Any
&a
) const
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
:
393 sal_Unicode c
= *o3tl::forceAccess
<sal_Unicode
>(a
);
394 return PyRef( PyUNO_char_new( c
, *this ), SAL_NO_ACQUIRE
);
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
:
447 return ustring2PyUnicode( tmp_ostr
);
449 case css::uno::TypeClass_TYPE
:
453 OString o
= OUStringToOString( t
.getTypeName(), RTL_TEXTENCODING_ASCII_US
);
456 o
.getStr(), t
.getTypeClass(), *this),
459 case css::uno::TypeClass_ANY
:
461 //I don't think this can happen.
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
);
480 return PyRef( PyUNO_Enum_new(e
.getStr(),v
.getStr(), *this ), SAL_NO_ACQUIRE
);
484 throw RuntimeException( "Any carries enum " + a
.getValueType().getTypeName() +
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 );
491 PyRef value
= PyUNOStruct_new( a
, getImpl()->cargo
->xInvocation
);
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
) )
503 // add the message in a standard python way !
504 PyRef
args( PyTuple_New( 1 ), SAL_NO_ACQUIRE
, NOT_NULL
);
506 PyRef pymsg
= ustring2PyString( e
->Message
);
507 PyTuple_SetItem( args
.get(), 0 , pymsg
.getAcquired() );
508 // the exception base functions want to have an "args" tuple,
509 // which contains the message
510 PyObject_SetAttrString( ret
.get(), "args", args
.get() );
514 case css::uno::TypeClass_SEQUENCE
:
518 Sequence
< sal_Int8
> byteSequence
;
519 if( a
>>= byteSequence
)
521 // byte sequence is treated in a special way because of performance reasons
523 return PyRef( PyUNO_ByteSequence_new( byteSequence
, *this ), SAL_NO_ACQUIRE
);
527 Reference
< XTypeConverter
> tc
= getImpl()->cargo
->xTypeConverter
;
528 tc
->convertTo (a
, cppu::UnoType
<decltype(s
)>::get()) >>= s
;
529 PyRef
tuple( PyTuple_New (s
.getLength()), SAL_NO_ACQUIRE
, NOT_NULL
);
533 for ( i
= 0; i
< s
.getLength (); i
++)
535 PyRef element
= any2PyObject (tc
->convertTo (s
[i
], s
[i
].getValueType() ));
536 OSL_ASSERT( element
.is() );
537 PyTuple_SetItem( tuple
.get(), i
, element
.getAcquired() );
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
:
554 Reference
<XInterface
> tmp_interface
;
556 if (!tmp_interface
.is ())
559 return PyUNO_new( a
, getImpl()->cargo
->xInvocation
);
563 throw RuntimeException( "Unknown UNO type class " + OUString::number(static_cast<int>(a
.getValueTypeClass())) );
568 static Sequence
< Type
> invokeGetTypes( const Runtime
& r
, PyObject
* o
)
570 Sequence
< Type
> ret
;
572 PyRef
method( PyObject_GetAttrString( o
, "getTypes" ), SAL_NO_ACQUIRE
);
573 raiseInvocationTargetExceptionWhenNeeded( r
);
574 if( method
.is() && PyCallable_Check( method
.get() ) )
576 PyRef
types( PyObject_CallObject( method
.get(), nullptr ) , SAL_NO_ACQUIRE
);
577 raiseInvocationTargetExceptionWhenNeeded( r
);
578 if( types
.is() && PyTuple_Check( types
.get() ) )
580 int size
= PyTuple_Size( types
.get() );
582 // add the XUnoTunnel interface for uno object identity concept (hack)
583 ret
.realloc( size
+ 1 );
584 auto pret
= ret
.getArray();
585 for( int i
= 0 ; i
< size
; i
++ )
587 Any a
= r
.pyObject2Any(PyTuple_GetItem(types
.get(),i
));
590 pret
[size
] = cppu::UnoType
<css::lang::XUnoTunnel
>::get();
597 lcl_ExceptionMessage(PyObject
*const o
, OUString
const*const pWrapped
)
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();
612 // For Python 2.7 - see https://bugs.python.org/issue24161
613 // Fills aSeq and returns true if pObj is a valid iterator
614 bool Runtime::pyIterUnpack( PyObject
*const pObj
, Any
&a
) const
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
);
634 items
.push_back( pyObject2Any( rItem
.get() ) );
635 pItem
= PyIter_Next( pObj
);
638 a
<<= comphelper::containerToSequence(items
);
642 Any
Runtime::pyObject2Any(const PyRef
& source
, enum ConversionMode mode
) const
644 if (!impl
|| !impl
->cargo
->valid
)
646 throw RuntimeException("pyuno runtime must be initialized before calling any2PyObject" );
650 PyObject
*o
= source
.get();
655 else if (PyLong_Check (o
))
657 // Convert the Python 3 booleans that are actually of type PyLong.
662 else if(o
== Py_False
)
668 sal_Int64 l
= static_cast<sal_Int64
>(PyLong_AsLong (o
));
669 if( l
< 128 && l
>= -128 )
671 sal_Int8 b
= static_cast<sal_Int8
>(l
);
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
))
698 a
<<= pyString2ustring(o
);
700 else if (PyTuple_Check (o
))
702 Sequence
<Any
> s (PyTuple_Size (o
));
703 auto sRange
= asNonConstRange(s
);
704 for (Py_ssize_t i
= 0; i
< PyTuple_Size (o
); i
++)
706 sRange
[i
] = pyObject2Any (PyTuple_GetItem (o
, i
), mode
);
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
++)
717 sRange
[i
] = pyObject2Any (PyList_GetItem (o
, i
), mode
);
721 else if (!pyIterUnpack (o
, a
))
724 // should be removed, in case ByteSequence gets derived from String
725 if( PyObject_IsInstance( o
, getByteSequenceClass( runtime
).get() ) )
727 PyRef
str(PyObject_GetAttrString( o
, "value" ),SAL_NO_ACQUIRE
);
728 Sequence
< sal_Int8
> seq
;
729 if( PyBytes_Check( str
.get() ) )
731 seq
= Sequence
<sal_Int8
> (
732 reinterpret_cast<sal_Int8
*>(PyBytes_AsString(str
.get())), PyBytes_Size(str
.get()));
737 if( PyObject_IsInstance( o
, getTypeClass( runtime
).get() ) )
739 Type t
= PyType2Type( o
);
742 else if( PyObject_IsInstance( o
, getEnumClass( runtime
).get() ) )
744 a
= PyEnum2Enum( o
);
746 else if( isInstanceOfStructOrException( o
) )
748 PyRef
struc(PyObject_GetAttrString( o
, "value" ),SAL_NO_ACQUIRE
);
749 PyUNO
* obj
= reinterpret_cast<PyUNO
*>(struc
.get());
750 Reference
< XMaterialHolder
> holder( obj
->members
->xInvocation
, UNO_QUERY
);
753 throw RuntimeException(
754 "struct or exception wrapper does not support XMaterialHolder" );
757 a
= holder
->getMaterial();
760 else if( PyObject_IsInstance( o
, getPyUnoClass().get() ) )
762 PyUNO
* o_pi
= reinterpret_cast<PyUNO
*>(o
);
763 a
= o_pi
->members
->wrappedObject
;
765 else if( PyObject_IsInstance( o
, getPyUnoStructClass().get() ) )
767 PyUNO
* o_pi
= reinterpret_cast<PyUNO
*>(o
);
768 Reference
<XMaterialHolder
> my_mh (o_pi
->members
->xInvocation
, css::uno::UNO_QUERY_THROW
);
769 a
= my_mh
->getMaterial();
771 else if( PyObject_IsInstance( o
, getCharClass( runtime
).get() ) )
773 a
<<= PyChar2Unicode( o
);
775 else if( PyObject_IsInstance( o
, getAnyClass( runtime
).get() ) )
777 if( ACCEPT_UNO_ANY
!= mode
)
779 throw RuntimeException(
780 "uno.Any instance not accepted during method call, "
781 "use uno.invoke instead" );
784 a
= pyObject2Any( PyRef( PyObject_GetAttrString( o
, "value" ), SAL_NO_ACQUIRE
) );
786 pyObject2Any( PyRef( PyObject_GetAttrString( o
, "type" ), SAL_NO_ACQUIRE
) ) >>= t
;
790 a
= getImpl()->cargo
->xTypeConverter
->convertTo( a
, t
);
792 catch( const css::uno::Exception
& e
)
794 css::uno::Any anyEx
= cppu::getCaughtException();
795 throw WrappedTargetRuntimeException(
796 e
.Message
, e
.Context
, anyEx
);
802 Reference
< XInterface
> mappedObject
;
803 Reference
< XInvocation
> adapterObject
;
805 // instance already mapped out to the world ?
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() )
814 // object got already bridged !
815 auto pAdapter
= comphelper::getFromUnoTunnel
<Adapter
>(adapterObject
);
817 mappedObject
= impl
->cargo
->xAdapterFactory
->createAdapter(
818 adapterObject
, pAdapter
->getWrappedTypes() );
823 Sequence
<Type
> interfaces
= invokeGetTypes(*this, o
);
824 if (interfaces
.getLength())
826 rtl::Reference
<Adapter
> pAdapter
= new Adapter( o
, interfaces
);
828 getImpl()->cargo
->xAdapterFactory
->createAdapter(
829 pAdapter
, interfaces
);
831 // keep a list of exported objects to ensure object identity !
832 impl
->cargo
->mappedObjects
[ PyRef(o
) ] =
833 css::uno::WeakReference
< XInvocation
> ( pAdapter
);
835 } catch (InvocationTargetException
const& e
) {
836 OUString
const msg(lcl_ExceptionMessage(o
, &e
.Message
));
837 throw WrappedTargetRuntimeException( // re-wrap that
838 msg
, e
.Context
, e
.TargetException
);
841 if( mappedObject
.is() )
847 OUString
const msg(lcl_ExceptionMessage(o
, nullptr));
848 throw RuntimeException(msg
);
855 Any
Runtime::extractUnoException( const PyRef
& excType
, const PyRef
&excValue
, const PyRef
&excTraceback
) const
859 if( excTraceback
.is() )
867 unoModule
= impl
->cargo
->getUnoModule();
869 catch (const Exception
&ei
)
876 PyRef
extractTraceback(
877 PyDict_GetItemString(unoModule
.get(),"_uno_extract_printable_stacktrace" ) );
879 if( PyCallable_Check(extractTraceback
.get()) )
881 PyRef
args( PyTuple_New( 1), SAL_NO_ACQUIRE
, NOT_NULL
);
882 PyTuple_SetItem( args
.get(), 0, excTraceback
.getAcquired() );
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
+ ")";
903 // it may occur, that no traceback is given (e.g. only native code below)
904 str
= "no traceback available";
907 if( isInstanceOfStructOrException( excValue
.get() ) )
909 ret
= pyObject2Any( excValue
);
914 PyRef
typeName( PyObject_Str( excType
.get() ), SAL_NO_ACQUIRE
);
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",
947 OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).getStr() );
955 PyThreadAttach::PyThreadAttach( PyInterpreterState
*interp
)
956 : m_isNewState(false)
958 // note: *may* be called recursively, with PyThreadDetach between - in
959 // that case, don't create *new* PyThreadState but reuse!
960 tstate
= PyGILState_GetThisThreadState(); // from TLS, possibly detached
964 tstate
= PyThreadState_New( interp
);
967 throw RuntimeException( "Couldn't create a pythreadstate" );
968 PyEval_AcquireThread( tstate
);
971 PyThreadAttach::~PyThreadAttach()
974 { // Clear needs GIL!
975 PyThreadState_Clear( tstate
);
976 // note: PyThreadState_Delete(tstate) cannot be called, it will assert
977 // because it requires a PyThreadState to be set, but not the tstate!
978 PyThreadState_DeleteCurrent();
982 PyEval_ReleaseThread( tstate
);
986 PyThreadDetach::PyThreadDetach()
988 tstate
= PyThreadState_Get();
989 PyEval_ReleaseThread( tstate
);
990 // tstate must not be deleted here! lots of pointers to it on the stack
993 /** Acquires the global interpreter lock again
996 PyThreadDetach::~PyThreadDetach()
998 PyEval_AcquireThread( tstate
);
1002 PyRef
const & RuntimeCargo::getUnoModule()
1004 if( ! dictUnoModule
.is() )
1006 dictUnoModule
= importUnoModule();
1008 return dictUnoModule
;
1012 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */