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>
32 #include <typelib/typedescription.hxx>
34 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
35 #include <com/sun/star/beans/XMaterialHolder.hpp>
36 #include <com/sun/star/beans/theIntrospection.hpp>
37 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
38 #include <com/sun/star/script/Converter.hpp>
39 #include <com/sun/star/script/InvocationAdapterFactory.hpp>
40 #include <com/sun/star/reflection/theCoreReflection.hpp>
41 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
42 #include <comphelper/sequence.hxx>
43 #include <comphelper/servicehelper.hxx>
44 #include <cppuhelper/exc_hlp.hxx>
48 using com::sun::star::uno::Reference
;
49 using com::sun::star::uno::XInterface
;
50 using com::sun::star::uno::Any
;
51 using com::sun::star::uno::TypeDescription
;
52 using com::sun::star::uno::Sequence
;
53 using com::sun::star::uno::Type
;
54 using com::sun::star::uno::UNO_QUERY
;
55 using com::sun::star::uno::Exception
;
56 using com::sun::star::uno::RuntimeException
;
57 using com::sun::star::uno::XComponentContext
;
58 using com::sun::star::lang::WrappedTargetRuntimeException
;
59 using com::sun::star::lang::XSingleServiceFactory
;
60 using com::sun::star::lang::XUnoTunnel
;
61 using com::sun::star::reflection::theCoreReflection
;
62 using com::sun::star::reflection::InvocationTargetException
;
63 using com::sun::star::script::Converter
;
64 using com::sun::star::script::XTypeConverter
;
65 using com::sun::star::script::XInvocation
;
66 using com::sun::star::beans::XMaterialHolder
;
67 using com::sun::star::beans::theIntrospection
;
72 static PyTypeObject RuntimeImpl_Type
=
74 PyVarObject_HEAD_INIT (&PyType_Type
, 0)
79 #if PY_VERSION_HEX >= 0x03080000
80 0, // Py_ssize_t tp_vectorcall_offset
82 nullptr, // printfunc tp_print
125 #if PY_VERSION_HEX >= 0x03040000
127 #if PY_VERSION_HEX >= 0x03080000
128 , nullptr // vectorcallfunc tp_vectorcall
133 /*----------------------------------------------------------------------
134 Runtime implementation
135 -----------------------------------------------------------------------*/
136 /// @throws css::uno::RuntimeException
137 static void getRuntimeImpl( PyRef
& globalDict
, PyRef
&runtimeImpl
)
139 PyThreadState
* state
= PyThreadState_Get();
142 throw RuntimeException( "python global interpreter must be held (thread must be attached)" );
145 PyObject
* pModule
= PyImport_AddModule("__main__");
149 throw RuntimeException("can't import __main__ module");
152 globalDict
= PyRef( PyModule_GetDict(pModule
));
154 if( ! globalDict
.is() ) // FATAL !
156 throw RuntimeException("can't find __main__ module");
158 runtimeImpl
= PyDict_GetItemString( globalDict
.get() , "pyuno_runtime" );
161 /// @throws RuntimeException
162 static PyRef
importUnoModule( )
164 // import the uno module
165 PyRef
module( PyImport_ImportModule( "uno" ), SAL_NO_ACQUIRE
, NOT_NULL
);
166 if( PyErr_Occurred() )
168 PyRef excType
, excValue
, excTraceback
;
169 PyErr_Fetch( reinterpret_cast<PyObject
**>(&excType
), reinterpret_cast<PyObject
**>(&excValue
), reinterpret_cast<PyObject
**>(&excTraceback
));
170 // As of Python 2.7 this gives a rather non-useful "<traceback object at 0xADDRESS>",
171 // but it is the best we can do in the absence of uno._uno_extract_printable_stacktrace
172 // Who knows, a future Python might print something better.
173 PyRef
str( PyObject_Str( excTraceback
.get() ), SAL_NO_ACQUIRE
);
176 buf
.append( "python object raised an unknown exception (" );
177 PyRef
valueRep( PyObject_Repr( excValue
.get() ), SAL_NO_ACQUIRE
);
178 buf
.appendAscii( PyStr_AsString( valueRep
.get())).append( ", traceback follows\n" );
179 buf
.appendAscii( PyStr_AsString( str
.get() ) );
181 throw RuntimeException( buf
.makeStringAndClear() );
183 PyRef
dict( PyModule_GetDict( module
.get() ) );
187 static void readLoggingConfig( sal_Int32
*pLevel
, FILE **ppFile
)
189 *pLevel
= LogLevel::NONE
;
192 osl_getModuleURLFromFunctionAddress(
193 reinterpret_cast< oslGenericFunction
>(readLoggingConfig
),
195 fileName
= fileName
.copy( fileName
.lastIndexOf( '/' )+1 );
197 fileName
+= "../" LIBO_ETC_FOLDER
"/";
199 fileName
+= SAL_CONFIGFILE("pyuno" );
200 rtl::Bootstrap
bootstrapHandle( fileName
);
203 if( bootstrapHandle
.getFrom( "PYUNO_LOGLEVEL", str
) )
206 *pLevel
= LogLevel::NONE
;
207 else if ( str
== "CALL" )
208 *pLevel
= LogLevel::CALL
;
209 else if ( str
== "ARGS" )
210 *pLevel
= LogLevel::ARGS
;
213 fprintf( stderr
, "unknown loglevel %s\n",
214 OUStringToOString( str
, RTL_TEXTENCODING_UTF8
).getStr() );
217 if( *pLevel
> LogLevel::NONE
)
220 if( bootstrapHandle
.getFrom( "PYUNO_LOGTARGET", str
) )
222 if ( str
== "stdout" )
224 else if ( str
== "stderr" )
229 data
.Size
= sizeof( data
);
231 nullptr , osl_Process_IDENTIFIER
, &data
);
232 osl_getSystemPathFromFileURL( str
.pData
, &str
.pData
);
233 OString o
= OUStringToOString( str
, osl_getThreadTextEncoding() );
235 o
+= OString::number( data
.Ident
);
237 *ppFile
= fopen( o
.getStr() , "w" );
240 // do not buffer (useful if e.g. analyzing a crash)
241 setvbuf( *ppFile
, nullptr, _IONBF
, 0 );
245 fprintf( stderr
, "couldn't create file %s\n",
246 OUStringToOString( str
, RTL_TEXTENCODING_UTF8
).getStr() );
254 /*-------------------------------------------------------------------
255 RuntimeImpl implementations
256 *-------------------------------------------------------------------*/
257 PyRef
stRuntimeImpl::create( const Reference
< XComponentContext
> &ctx
)
259 RuntimeImpl
*me
= PyObject_New (RuntimeImpl
, &RuntimeImpl_Type
);
261 throw RuntimeException( "cannot instantiate pyuno::RuntimeImpl" );
263 // must use a different struct here, as the PyObject_New
264 // makes C++ unusable
265 RuntimeCargo
*c
= new RuntimeCargo
;
266 readLoggingConfig( &(c
->logLevel
) , &(c
->logFile
) );
267 log( c
, LogLevel::CALL
, "Instantiating pyuno bridge" );
271 c
->xInvocation
= Reference
< XSingleServiceFactory
> (
272 ctx
->getServiceManager()->createInstanceWithContext(
273 "com.sun.star.script.Invocation",
275 css::uno::UNO_QUERY_THROW
);
277 c
->xTypeConverter
= Converter::create(ctx
);
278 if( ! c
->xTypeConverter
.is() )
279 throw RuntimeException( "pyuno: couldn't instantiate typeconverter service" );
281 c
->xCoreReflection
= theCoreReflection::get(ctx
);
283 c
->xAdapterFactory
= css::script::InvocationAdapterFactory::create(ctx
);
285 c
->xIntrospection
= theIntrospection::get(ctx
);
287 Any a
= ctx
->getValueByName("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
289 if( ! c
->xTdMgr
.is() )
290 throw RuntimeException( "pyuno: couldn't retrieve typedescriptionmanager" );
293 return PyRef( reinterpret_cast< PyObject
* > ( me
), SAL_NO_ACQUIRE
);
296 void stRuntimeImpl::del(PyObject
* self
)
298 RuntimeImpl
*me
= reinterpret_cast< RuntimeImpl
* > ( self
);
299 if( me
->cargo
->logFile
)
300 fclose( me
->cargo
->logFile
);
306 void Runtime::initialize( const Reference
< XComponentContext
> & ctx
)
308 PyRef globalDict
, runtime
;
309 getRuntimeImpl( globalDict
, runtime
);
310 RuntimeImpl
*impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
312 if( runtime
.is() && impl
->cargo
->valid
)
314 throw RuntimeException("pyuno runtime has already been initialized before" );
316 PyRef
keep( RuntimeImpl::create( ctx
) );
317 PyDict_SetItemString( globalDict
.get(), "pyuno_runtime" , keep
.get() );
318 Py_XINCREF( keep
.get() );
322 bool Runtime::isInitialized()
324 PyRef globalDict
, runtime
;
325 getRuntimeImpl( globalDict
, runtime
);
326 RuntimeImpl
*impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
327 return runtime
.is() && impl
->cargo
->valid
;
333 PyRef globalDict
, runtime
;
334 getRuntimeImpl( globalDict
, runtime
);
337 throw RuntimeException(
338 "pyuno runtime is not initialized, "
339 "(the pyuno.bootstrap needs to be called before using any uno classes)" );
341 impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
342 Py_XINCREF( runtime
.get() );
345 Runtime::Runtime( const Runtime
& r
)
348 Py_XINCREF( reinterpret_cast< PyObject
* >(impl
) );
353 Py_XDECREF( reinterpret_cast< PyObject
* >(impl
) );
356 Runtime
& Runtime::operator = ( const Runtime
& r
)
358 PyRef
temp( reinterpret_cast< PyObject
* >(r
.impl
) );
359 Py_XINCREF( temp
.get() );
360 Py_XDECREF( reinterpret_cast< PyObject
* >(impl
) );
365 PyRef
Runtime::any2PyObject (const Any
&a
) const
367 if( ! impl
->cargo
->valid
)
369 throw RuntimeException("pyuno runtime must be initialized before calling any2PyObject" );
372 switch (a
.getValueTypeClass ())
374 case css::uno::TypeClass_VOID
:
377 return PyRef(Py_None
);
379 case css::uno::TypeClass_CHAR
:
381 sal_Unicode c
= *o3tl::forceAccess
<sal_Unicode
>(a
);
382 return PyRef( PyUNO_char_new( c
, *this ), SAL_NO_ACQUIRE
);
384 case css::uno::TypeClass_BOOLEAN
:
392 case css::uno::TypeClass_BYTE
:
393 case css::uno::TypeClass_SHORT
:
394 case css::uno::TypeClass_UNSIGNED_SHORT
:
395 case css::uno::TypeClass_LONG
:
399 return PyRef( PyLong_FromLong (l
), SAL_NO_ACQUIRE
);
401 case css::uno::TypeClass_UNSIGNED_LONG
:
405 return PyRef( PyLong_FromUnsignedLong (l
), SAL_NO_ACQUIRE
);
407 case css::uno::TypeClass_HYPER
:
411 return PyRef( PyLong_FromLongLong (l
), SAL_NO_ACQUIRE
);
413 case css::uno::TypeClass_UNSIGNED_HYPER
:
417 return PyRef( PyLong_FromUnsignedLongLong (l
), SAL_NO_ACQUIRE
);
419 case css::uno::TypeClass_FLOAT
:
423 return PyRef(PyFloat_FromDouble (f
), SAL_NO_ACQUIRE
);
425 case css::uno::TypeClass_DOUBLE
:
429 return PyRef( PyFloat_FromDouble (d
), SAL_NO_ACQUIRE
);
431 case css::uno::TypeClass_STRING
:
435 return ustring2PyUnicode( tmp_ostr
);
437 case css::uno::TypeClass_TYPE
:
441 OString o
= OUStringToOString( t
.getTypeName(), RTL_TEXTENCODING_ASCII_US
);
444 o
.getStr(), t
.getTypeClass(), *this),
447 case css::uno::TypeClass_ANY
:
449 //I don't think this can happen.
453 case css::uno::TypeClass_ENUM
:
455 sal_Int32 l
= *static_cast<sal_Int32
const *>(a
.getValue());
456 TypeDescription
desc( a
.getValueType() );
460 typelib_EnumTypeDescription
*pEnumDesc
=
461 reinterpret_cast<typelib_EnumTypeDescription
*>(desc
.get());
462 for( int i
= 0 ; i
< pEnumDesc
->nEnumValues
; i
++ )
464 if( pEnumDesc
->pEnumValues
[i
] == l
)
466 OString v
= OUStringToOString( pEnumDesc
->ppEnumNames
[i
], RTL_TEXTENCODING_ASCII_US
);
467 OString e
= OUStringToOString( pEnumDesc
->aBase
.pTypeName
, RTL_TEXTENCODING_ASCII_US
);
468 return PyRef( PyUNO_Enum_new(e
.getStr(),v
.getStr(), *this ), SAL_NO_ACQUIRE
);
472 throw RuntimeException( "Any carries enum " + a
.getValueType().getTypeName() +
473 " with invalid value " + OUString::number(l
) );
475 case css::uno::TypeClass_EXCEPTION
:
476 case css::uno::TypeClass_STRUCT
:
478 PyRef excClass
= getClass( a
.getValueType().getTypeName(), *this );
479 PyRef value
= PyUNOStruct_new( a
, getImpl()->cargo
->xInvocation
);
480 PyRef
argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE
, NOT_NULL
);
481 PyTuple_SetItem( argsTuple
.get() , 0 , value
.getAcquired() );
482 PyRef
ret( PyObject_CallObject( excClass
.get() , argsTuple
.get() ), SAL_NO_ACQUIRE
);
485 throw RuntimeException( "Couldn't instantiate python representation of structured UNO type " +
486 a
.getValueType().getTypeName() );
489 if( auto e
= o3tl::tryAccess
<css::uno::Exception
>(a
) )
491 // add the message in a standard python way !
492 PyRef
args( PyTuple_New( 1 ), SAL_NO_ACQUIRE
, NOT_NULL
);
494 PyRef pymsg
= ustring2PyString( e
->Message
);
495 PyTuple_SetItem( args
.get(), 0 , pymsg
.getAcquired() );
496 // the exception base functions want to have an "args" tuple,
497 // which contains the message
498 PyObject_SetAttrString( ret
.get(), "args", args
.get() );
502 case css::uno::TypeClass_SEQUENCE
:
506 Sequence
< sal_Int8
> byteSequence
;
507 if( a
>>= byteSequence
)
509 // byte sequence is treated in a special way because of performance reasons
511 return PyRef( PyUNO_ByteSequence_new( byteSequence
, *this ), SAL_NO_ACQUIRE
);
515 Reference
< XTypeConverter
> tc
= getImpl()->cargo
->xTypeConverter
;
516 tc
->convertTo (a
, cppu::UnoType
<decltype(s
)>::get()) >>= s
;
517 PyRef
tuple( PyTuple_New (s
.getLength()), SAL_NO_ACQUIRE
, NOT_NULL
);
521 for ( i
= 0; i
< s
.getLength (); i
++)
523 PyRef element
= any2PyObject (tc
->convertTo (s
[i
], s
[i
].getValueType() ));
524 OSL_ASSERT( element
.is() );
525 PyTuple_SetItem( tuple
.get(), i
, element
.getAcquired() );
528 catch( css::uno::Exception
& )
530 for( ; i
< s
.getLength() ; i
++ )
532 Py_INCREF( Py_None
);
533 PyTuple_SetItem( tuple
.get(), i
, Py_None
);
540 case css::uno::TypeClass_INTERFACE
:
542 Reference
<XInterface
> tmp_interface
;
544 if (!tmp_interface
.is ())
547 return PyUNO_new( a
, getImpl()->cargo
->xInvocation
);
551 throw RuntimeException( "Unknown UNO type class " + OUString::number(static_cast<int>(a
.getValueTypeClass())) );
556 static Sequence
< Type
> invokeGetTypes( const Runtime
& r
, PyObject
* o
)
558 Sequence
< Type
> ret
;
560 PyRef
method( PyObject_GetAttrString( o
, "getTypes" ), SAL_NO_ACQUIRE
);
561 raiseInvocationTargetExceptionWhenNeeded( r
);
562 if( method
.is() && PyCallable_Check( method
.get() ) )
564 PyRef
types( PyObject_CallObject( method
.get(), nullptr ) , SAL_NO_ACQUIRE
);
565 raiseInvocationTargetExceptionWhenNeeded( r
);
566 if( types
.is() && PyTuple_Check( types
.get() ) )
568 int size
= PyTuple_Size( types
.get() );
570 // add the XUnoTunnel interface for uno object identity concept (hack)
571 ret
.realloc( size
+ 1 );
572 for( int i
= 0 ; i
< size
; i
++ )
574 Any a
= r
.pyObject2Any(PyTuple_GetItem(types
.get(),i
));
577 ret
[size
] = cppu::UnoType
<css::lang::XUnoTunnel
>::get();
584 lcl_ExceptionMessage(PyObject
*const o
, OUString
const*const pWrapped
)
587 buf
.append("Couldn't convert ");
588 PyRef
reprString( PyObject_Str(o
), SAL_NO_ACQUIRE
);
589 buf
.appendAscii( PyStr_AsString(reprString
.get()) );
590 buf
.append(" to a UNO type");
593 buf
.append("; caught exception: ");
594 buf
.append(*pWrapped
);
596 return buf
.makeStringAndClear();
599 // For Python 2.7 - see https://bugs.python.org/issue24161
600 // Fills aSeq and returns true if pObj is a valid iterator
601 bool Runtime::pyIterUnpack( PyObject
*const pObj
, Any
&a
) const
603 if( !PyIter_Check( pObj
))
606 PyObject
*pItem
= PyIter_Next( pObj
);
609 if( PyErr_Occurred() )
617 ::std::vector
<Any
> items
;
620 PyRef
rItem( pItem
, SAL_NO_ACQUIRE
);
621 items
.push_back( pyObject2Any( rItem
.get() ) );
622 pItem
= PyIter_Next( pObj
);
625 a
<<= comphelper::containerToSequence(items
);
629 Any
Runtime::pyObject2Any ( const PyRef
& source
, enum ConversionMode mode
) const
631 if( ! impl
->cargo
->valid
)
633 throw RuntimeException("pyuno runtime must be initialized before calling any2PyObject" );
637 PyObject
*o
= source
.get();
642 // In Python 3, there is no PyInt type.
643 #if PY_MAJOR_VERSION < 3
644 else if (PyInt_Check (o
))
650 else if ( o
== Py_False
)
656 sal_Int32 l
= (sal_Int32
) PyLong_AsLong( o
);
657 if( l
< 128 && l
>= -128 )
659 sal_Int8 b
= (sal_Int8
) l
;
662 else if( l
<= 0x7fff && l
>= -0x8000 )
664 sal_Int16 s
= (sal_Int16
) l
;
673 #endif /* PY_MAJOR_VERSION < 3 */
674 else if (PyLong_Check (o
))
676 #if PY_MAJOR_VERSION >= 3
677 // Convert the Python 3 booleans that are actually of type PyLong.
682 else if(o
== Py_False
)
688 #endif /* PY_MAJOR_VERSION >= 3 */
689 sal_Int64 l
= static_cast<sal_Int64
>(PyLong_AsLong (o
));
690 if( l
< 128 && l
>= -128 )
692 sal_Int8 b
= static_cast<sal_Int8
>(l
);
695 else if( l
<= 0x7fff && l
>= -0x8000 )
697 sal_Int16 s
= static_cast<sal_Int16
>(l
);
700 else if( l
<= SAL_CONST_INT64(0x7fffffff) &&
701 l
>= -SAL_CONST_INT64(0x80000000) )
703 sal_Int32 l32
= static_cast<sal_Int32
>(l
);
710 #if PY_MAJOR_VERSION >= 3
714 else if (PyFloat_Check (o
))
716 double d
= PyFloat_AsDouble (o
);
719 else if (PyStrBytes_Check(o
) || PyUnicode_Check(o
))
721 a
<<= pyString2ustring(o
);
723 else if (PyTuple_Check (o
))
725 Sequence
<Any
> s (PyTuple_Size (o
));
726 for (Py_ssize_t i
= 0; i
< PyTuple_Size (o
); i
++)
728 s
[i
] = pyObject2Any (PyTuple_GetItem (o
, i
), mode
);
732 else if (PyList_Check (o
))
734 Py_ssize_t l
= PyList_Size (o
);
736 for (Py_ssize_t i
= 0; i
< l
; i
++)
738 s
[i
] = pyObject2Any (PyList_GetItem (o
, i
), mode
);
742 else if (!pyIterUnpack (o
, a
))
745 // should be removed, in case ByteSequence gets derived from String
746 if( PyObject_IsInstance( o
, getByteSequenceClass( runtime
).get() ) )
748 PyRef
str(PyObject_GetAttrString( o
, "value" ),SAL_NO_ACQUIRE
);
749 Sequence
< sal_Int8
> seq
;
750 if( PyStrBytes_Check( str
.get() ) )
752 seq
= Sequence
<sal_Int8
> (
753 reinterpret_cast<sal_Int8
*>(PyStrBytes_AsString(str
.get())), PyStrBytes_Size(str
.get()));
758 if( PyObject_IsInstance( o
, getTypeClass( runtime
).get() ) )
760 Type t
= PyType2Type( o
);
763 else if( PyObject_IsInstance( o
, getEnumClass( runtime
).get() ) )
765 a
= PyEnum2Enum( o
);
767 else if( isInstanceOfStructOrException( o
) )
769 PyRef
struc(PyObject_GetAttrString( o
, "value" ),SAL_NO_ACQUIRE
);
770 PyUNO
* obj
= reinterpret_cast<PyUNO
*>(struc
.get());
771 Reference
< XMaterialHolder
> holder( obj
->members
->xInvocation
, UNO_QUERY
);
774 throw RuntimeException(
775 "struct or exception wrapper does not support XMaterialHolder" );
778 a
= holder
->getMaterial();
781 else if( PyObject_IsInstance( o
, getPyUnoClass().get() ) )
783 PyUNO
* o_pi
= reinterpret_cast<PyUNO
*>(o
);
784 a
= o_pi
->members
->wrappedObject
;
786 else if( PyObject_IsInstance( o
, getPyUnoStructClass().get() ) )
788 PyUNO
* o_pi
= reinterpret_cast<PyUNO
*>(o
);
789 Reference
<XMaterialHolder
> my_mh (o_pi
->members
->xInvocation
, css::uno::UNO_QUERY_THROW
);
790 a
= my_mh
->getMaterial();
792 else if( PyObject_IsInstance( o
, getCharClass( runtime
).get() ) )
794 a
<<= PyChar2Unicode( o
);
796 else if( PyObject_IsInstance( o
, getAnyClass( runtime
).get() ) )
798 if( ACCEPT_UNO_ANY
!= mode
)
800 throw RuntimeException(
801 "uno.Any instance not accepted during method call, "
802 "use uno.invoke instead" );
805 a
= pyObject2Any( PyRef( PyObject_GetAttrString( o
, "value" ), SAL_NO_ACQUIRE
) );
807 pyObject2Any( PyRef( PyObject_GetAttrString( o
, "type" ), SAL_NO_ACQUIRE
) ) >>= t
;
811 a
= getImpl()->cargo
->xTypeConverter
->convertTo( a
, t
);
813 catch( const css::uno::Exception
& e
)
815 css::uno::Any anyEx
= cppu::getCaughtException();
816 throw WrappedTargetRuntimeException(
817 e
.Message
, e
.Context
, anyEx
);
823 Reference
< XInterface
> mappedObject
;
824 Reference
< XInvocation
> adapterObject
;
826 // instance already mapped out to the world ?
827 PyRef2Adapter::iterator ii
= impl
->cargo
->mappedObjects
.find( PyRef( o
) );
828 if( ii
!= impl
->cargo
->mappedObjects
.end() )
830 adapterObject
= ii
->second
;
833 if( adapterObject
.is() )
835 // object got already bridged !
836 auto pAdapter
= comphelper::getUnoTunnelImplementation
<Adapter
>(adapterObject
);
838 mappedObject
= impl
->cargo
->xAdapterFactory
->createAdapter(
839 adapterObject
, pAdapter
->getWrappedTypes() );
844 Sequence
<Type
> interfaces
= invokeGetTypes(*this, o
);
845 if (interfaces
.getLength())
847 Adapter
*pAdapter
= new Adapter( o
, interfaces
);
849 getImpl()->cargo
->xAdapterFactory
->createAdapter(
850 pAdapter
, interfaces
);
852 // keep a list of exported objects to ensure object identity !
853 impl
->cargo
->mappedObjects
[ PyRef(o
) ] =
854 css::uno::WeakReference
< XInvocation
> ( pAdapter
);
856 } catch (InvocationTargetException
const& e
) {
857 OUString
const msg(lcl_ExceptionMessage(o
, &e
.Message
));
858 throw WrappedTargetRuntimeException( // re-wrap that
859 msg
, e
.Context
, e
.TargetException
);
862 if( mappedObject
.is() )
868 OUString
const msg(lcl_ExceptionMessage(o
, nullptr));
869 throw RuntimeException(msg
);
876 Any
Runtime::extractUnoException( const PyRef
& excType
, const PyRef
&excValue
, const PyRef
&excTraceback
) const
880 if( excTraceback
.is() )
888 unoModule
= impl
->cargo
->getUnoModule();
890 catch (const Exception
&ei
)
897 PyRef
extractTraceback(
898 PyDict_GetItemString(unoModule
.get(),"_uno_extract_printable_stacktrace" ) );
900 if( PyCallable_Check(extractTraceback
.get()) )
902 PyRef
args( PyTuple_New( 1), SAL_NO_ACQUIRE
, NOT_NULL
);
903 PyTuple_SetItem( args
.get(), 0, excTraceback
.getAcquired() );
904 PyRef
pyStr( PyObject_CallObject( extractTraceback
.get(),args
.get() ), SAL_NO_ACQUIRE
);
905 str
= OUString::createFromAscii( PyStr_AsString(pyStr
.get()) );
909 str
= "Couldn't find uno._uno_extract_printable_stacktrace";
914 str
= "Could not load uno.py, no stacktrace available";
915 if ( !e
.Message
.isEmpty() )
917 str
+= " (Error loading uno.py: " + e
.Message
+ ")";
924 // it may occur, that no traceback is given (e.g. only native code below)
925 str
= "no traceback available";
928 if( isInstanceOfStructOrException( excValue
.get() ) )
930 ret
= pyObject2Any( excValue
);
935 PyRef
typeName( PyObject_Str( excType
.get() ), SAL_NO_ACQUIRE
);
938 buf
.appendAscii( PyStr_AsString( typeName
.get() ) );
942 buf
.append( "no typename available" );
945 PyRef
valueRep( PyObject_Str( excValue
.get() ), SAL_NO_ACQUIRE
);
948 buf
.appendAscii( PyStr_AsString( valueRep
.get()));
952 buf
.append( "Couldn't convert exception value to a string" );
954 buf
.append( ", traceback follows\n" );
962 buf
.append( ", no traceback available\n" );
965 e
.Message
= buf
.makeStringAndClear();
966 #if OSL_DEBUG_LEVEL > 0
967 fprintf( stderr
, "Python exception: %s\n",
968 OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).getStr() );
976 PyThreadAttach::PyThreadAttach( PyInterpreterState
*interp
)
978 tstate
= PyThreadState_New( interp
);
980 throw RuntimeException( "Couldn't create a pythreadstate" );
981 PyEval_AcquireThread( tstate
);
984 PyThreadAttach::~PyThreadAttach()
986 PyThreadState_Clear( tstate
);
987 PyEval_ReleaseThread( tstate
);
988 PyThreadState_Delete( tstate
);
991 PyThreadDetach::PyThreadDetach()
993 tstate
= PyThreadState_Get();
994 PyEval_ReleaseThread( tstate
);
997 /** Acquires the global interpreter lock again
1000 PyThreadDetach::~PyThreadDetach()
1002 PyEval_AcquireThread( tstate
);
1006 PyRef
const & RuntimeCargo::getUnoModule()
1008 if( ! dictUnoModule
.is() )
1010 dictUnoModule
= importUnoModule();
1012 return dictUnoModule
;
1016 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */