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_features.h>
21 #include <config_folders.h>
23 #include "pyuno_impl.hxx"
25 #include <osl/diagnose.h>
26 #include <osl/thread.h>
27 #include <osl/module.h>
28 #include <osl/process.h>
29 #include <rtl/strbuf.hxx>
30 #include <rtl/ustrbuf.hxx>
31 #include <rtl/bootstrap.hxx>
34 #include <typelib/typedescription.hxx>
36 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
37 #include <com/sun/star/beans/XMaterialHolder.hpp>
38 #include <com/sun/star/beans/theIntrospection.hpp>
39 #include <com/sun/star/script/Converter.hpp>
40 #include <com/sun/star/script/InvocationAdapterFactory.hpp>
41 #include <com/sun/star/reflection/theCoreReflection.hpp>
42 #include <comphelper/sequence.hxx>
45 using com::sun::star::uno::Reference
;
46 using com::sun::star::uno::XInterface
;
47 using com::sun::star::uno::Any
;
48 using com::sun::star::uno::TypeDescription
;
49 using com::sun::star::uno::Sequence
;
50 using com::sun::star::uno::Type
;
51 using com::sun::star::uno::UNO_QUERY
;
52 using com::sun::star::uno::Exception
;
53 using com::sun::star::uno::RuntimeException
;
54 using com::sun::star::uno::XComponentContext
;
55 using com::sun::star::lang::WrappedTargetRuntimeException
;
56 using com::sun::star::lang::XSingleServiceFactory
;
57 using com::sun::star::lang::XUnoTunnel
;
58 using com::sun::star::reflection::theCoreReflection
;
59 using com::sun::star::reflection::InvocationTargetException
;
60 using com::sun::star::script::Converter
;
61 using com::sun::star::script::XTypeConverter
;
62 using com::sun::star::script::XInvocation
;
63 using com::sun::star::beans::XMaterialHolder
;
64 using com::sun::star::beans::theIntrospection
;
71 static PyTypeObject RuntimeImpl_Type
=
73 PyVarObject_HEAD_INIT (&PyType_Type
, 0)
119 #if PY_VERSION_HEX >= 0x02060000
122 #if PY_VERSION_HEX >= 0x03040000
127 /*----------------------------------------------------------------------
128 Runtime implementation
129 -----------------------------------------------------------------------*/
130 static void getRuntimeImpl( PyRef
& globalDict
, PyRef
&runtimeImpl
)
131 throw ( css::uno::RuntimeException
)
133 PyThreadState
* state
= PyThreadState_Get();
136 throw RuntimeException( "python global interpreter must be held (thread must be attached)" );
139 PyObject
* pModule
= PyImport_AddModule("__main__");
143 throw RuntimeException("can't import __main__ module");
146 globalDict
= PyRef( PyModule_GetDict(pModule
));
148 if( ! globalDict
.is() ) // FATAL !
150 throw RuntimeException("can't find __main__ module");
152 runtimeImpl
= PyDict_GetItemString( globalDict
.get() , "pyuno_runtime" );
155 static PyRef
importUnoModule( ) throw ( RuntimeException
)
157 // import the uno module
158 PyRef
module( PyImport_ImportModule( "uno" ), SAL_NO_ACQUIRE
, NOT_NULL
);
159 if( PyErr_Occurred() )
161 PyRef excType
, excValue
, excTraceback
;
162 PyErr_Fetch( reinterpret_cast<PyObject
**>(&excType
), reinterpret_cast<PyObject
**>(&excValue
), reinterpret_cast<PyObject
**>(&excTraceback
));
163 // As of Python 2.7 this gives a rather non-useful "<traceback object at 0xADDRESS>",
164 // but it is the best we can do in the absence of uno._uno_extract_printable_stacktrace
165 // Who knows, a future Python might print something better.
166 PyRef
str( PyObject_Str( excTraceback
.get() ), SAL_NO_ACQUIRE
);
169 buf
.append( "python object raised an unknown exception (" );
170 PyRef
valueRep( PyObject_Repr( excValue
.get() ), SAL_NO_ACQUIRE
);
171 buf
.appendAscii( PyStr_AsString( valueRep
.get())).append( ", traceback follows\n" );
172 buf
.appendAscii( PyStr_AsString( str
.get() ) );
174 throw RuntimeException( buf
.makeStringAndClear() );
176 PyRef
dict( PyModule_GetDict( module
.get() ) );
180 static void readLoggingConfig( sal_Int32
*pLevel
, FILE **ppFile
)
182 *pLevel
= LogLevel::NONE
;
185 osl_getModuleURLFromFunctionAddress(
186 reinterpret_cast< oslGenericFunction
>(readLoggingConfig
),
188 fileName
= fileName
.copy( fileName
.lastIndexOf( '/' )+1 );
190 fileName
+= "../" LIBO_ETC_FOLDER
"/";
192 fileName
+= SAL_CONFIGFILE("pyuno" );
193 rtl::Bootstrap
bootstrapHandle( fileName
);
196 if( bootstrapHandle
.getFrom( "PYUNO_LOGLEVEL", str
) )
199 *pLevel
= LogLevel::NONE
;
200 else if ( str
== "CALL" )
201 *pLevel
= LogLevel::CALL
;
202 else if ( str
== "ARGS" )
203 *pLevel
= LogLevel::ARGS
;
206 fprintf( stderr
, "unknown loglevel %s\n",
207 OUStringToOString( str
, RTL_TEXTENCODING_UTF8
).getStr() );
210 if( *pLevel
> LogLevel::NONE
)
213 if( bootstrapHandle
.getFrom( "PYUNO_LOGTARGET", str
) )
215 if ( str
== "stdout" )
217 else if ( str
== "stderr" )
222 data
.Size
= sizeof( data
);
224 nullptr , osl_Process_IDENTIFIER
, &data
);
225 osl_getSystemPathFromFileURL( str
.pData
, &str
.pData
);
226 OString o
= OUStringToOString( str
, osl_getThreadTextEncoding() );
228 o
+= OString::number( data
.Ident
);
230 *ppFile
= fopen( o
.getStr() , "w" );
233 // do not buffer (useful if e.g. analyzing a crash)
234 setvbuf( *ppFile
, nullptr, _IONBF
, 0 );
238 fprintf( stderr
, "couldn't create file %s\n",
239 OUStringToOString( str
, RTL_TEXTENCODING_UTF8
).getStr() );
247 /*-------------------------------------------------------------------
248 RuntimeImpl implementations
249 *-------------------------------------------------------------------*/
250 PyRef
stRuntimeImpl::create( const Reference
< XComponentContext
> &ctx
)
251 throw( css::uno::RuntimeException
, std::exception
)
253 RuntimeImpl
*me
= PyObject_New (RuntimeImpl
, &RuntimeImpl_Type
);
255 throw RuntimeException( "cannot instantiate pyuno::RuntimeImpl" );
257 // must use a different struct here, as the PyObject_New
258 // makes C++ unusable
259 RuntimeCargo
*c
= new RuntimeCargo();
260 readLoggingConfig( &(c
->logLevel
) , &(c
->logFile
) );
261 log( c
, LogLevel::CALL
, "Instantiating pyuno bridge" );
265 c
->xInvocation
= Reference
< XSingleServiceFactory
> (
266 ctx
->getServiceManager()->createInstanceWithContext(
267 "com.sun.star.script.Invocation",
270 if( ! c
->xInvocation
.is() )
271 throw RuntimeException( "pyuno: couldn't instantiate invocation service" );
273 c
->xTypeConverter
= Converter::create(ctx
);
274 if( ! c
->xTypeConverter
.is() )
275 throw RuntimeException( "pyuno: couldn't instantiate typeconverter service" );
277 c
->xCoreReflection
= theCoreReflection::get(ctx
);
279 c
->xAdapterFactory
= css::script::InvocationAdapterFactory::create(ctx
);
281 c
->xIntrospection
= theIntrospection::get(ctx
);
283 Any a
= ctx
->getValueByName("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
285 if( ! c
->xTdMgr
.is() )
286 throw RuntimeException( "pyuno: couldn't retrieve typedescriptionmanager" );
289 return PyRef( reinterpret_cast< PyObject
* > ( me
), SAL_NO_ACQUIRE
);
292 void stRuntimeImpl::del(PyObject
* self
)
294 RuntimeImpl
*me
= reinterpret_cast< RuntimeImpl
* > ( self
);
295 if( me
->cargo
->logFile
)
296 fclose( me
->cargo
->logFile
);
302 void Runtime::initialize( const Reference
< XComponentContext
> & ctx
)
303 throw ( RuntimeException
, std::exception
)
305 PyRef globalDict
, runtime
;
306 getRuntimeImpl( globalDict
, runtime
);
307 RuntimeImpl
*impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
309 if( runtime
.is() && impl
->cargo
->valid
)
311 throw RuntimeException("pyuno runtime has already been initialized before" );
313 PyRef
keep( RuntimeImpl::create( ctx
) );
314 PyDict_SetItemString( globalDict
.get(), "pyuno_runtime" , keep
.get() );
315 Py_XINCREF( keep
.get() );
319 bool Runtime::isInitialized() throw ( RuntimeException
)
321 PyRef globalDict
, runtime
;
322 getRuntimeImpl( globalDict
, runtime
);
323 RuntimeImpl
*impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
324 return runtime
.is() && impl
->cargo
->valid
;
327 Runtime::Runtime() throw( RuntimeException
)
330 PyRef globalDict
, runtime
;
331 getRuntimeImpl( globalDict
, runtime
);
334 throw RuntimeException(
335 "pyuno runtime is not initialized, "
336 "(the pyuno.bootstrap needs to be called before using any uno classes)" );
338 impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
339 Py_XINCREF( runtime
.get() );
342 Runtime::Runtime( const Runtime
& r
)
345 Py_XINCREF( reinterpret_cast< PyObject
* >(impl
) );
350 Py_XDECREF( reinterpret_cast< PyObject
* >(impl
) );
353 Runtime
& Runtime::operator = ( const Runtime
& r
)
355 PyRef
temp( reinterpret_cast< PyObject
* >(r
.impl
) );
356 Py_XINCREF( temp
.get() );
357 Py_XDECREF( reinterpret_cast< PyObject
* >(impl
) );
362 PyRef
Runtime::any2PyObject (const Any
&a
) const
363 throw ( css::script::CannotConvertException
,
364 css::lang::IllegalArgumentException
,
367 if( ! impl
->cargo
->valid
)
369 throw RuntimeException("pyuno runtime must be initialized before calling any2PyObject" );
372 switch (a
.getValueTypeClass ())
374 case typelib_TypeClass_VOID
:
377 return PyRef(Py_None
);
379 case typelib_TypeClass_CHAR
:
381 sal_Unicode c
= *static_cast<sal_Unicode
const *>(a
.getValue());
382 return PyRef( PyUNO_char_new( c
, *this ), SAL_NO_ACQUIRE
);
384 case typelib_TypeClass_BOOLEAN
:
392 case typelib_TypeClass_BYTE
:
393 case typelib_TypeClass_SHORT
:
394 case typelib_TypeClass_UNSIGNED_SHORT
:
395 case typelib_TypeClass_LONG
:
399 return PyRef( PyLong_FromLong (l
), SAL_NO_ACQUIRE
);
401 case typelib_TypeClass_UNSIGNED_LONG
:
405 return PyRef( PyLong_FromUnsignedLong (l
), SAL_NO_ACQUIRE
);
407 case typelib_TypeClass_HYPER
:
411 return PyRef( PyLong_FromLongLong (l
), SAL_NO_ACQUIRE
);
413 case typelib_TypeClass_UNSIGNED_HYPER
:
417 return PyRef( PyLong_FromUnsignedLongLong (l
), SAL_NO_ACQUIRE
);
419 case typelib_TypeClass_FLOAT
:
423 return PyRef(PyFloat_FromDouble (f
), SAL_NO_ACQUIRE
);
425 case typelib_TypeClass_DOUBLE
:
429 return PyRef( PyFloat_FromDouble (d
), SAL_NO_ACQUIRE
);
431 case typelib_TypeClass_STRING
:
435 return ustring2PyUnicode( tmp_ostr
);
437 case typelib_TypeClass_TYPE
:
441 OString o
= OUStringToOString( t
.getTypeName(), RTL_TEXTENCODING_ASCII_US
);
444 o
.getStr(), (css::uno::TypeClass
)t
.getTypeClass(), *this),
447 case typelib_TypeClass_ANY
:
449 //I don't think this can happen.
453 case typelib_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
);
473 buf
.append( "Any carries enum " );
474 buf
.append( a
.getValueType().getTypeName());
475 buf
.append( " with invalid value " ).append( l
);
476 throw RuntimeException( buf
.makeStringAndClear() );
478 case typelib_TypeClass_EXCEPTION
:
479 case typelib_TypeClass_STRUCT
:
481 PyRef excClass
= getClass( a
.getValueType().getTypeName(), *this );
482 PyRef value
= PyUNOStruct_new( a
, getImpl()->cargo
->xInvocation
);
483 PyRef
argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE
, NOT_NULL
);
484 PyTuple_SetItem( argsTuple
.get() , 0 , value
.getAcquired() );
485 PyRef
ret( PyObject_CallObject( excClass
.get() , argsTuple
.get() ), SAL_NO_ACQUIRE
);
489 buf
.append( "Couldn't instantiate python representation of structured UNO type " );
490 buf
.append( a
.getValueType().getTypeName() );
491 throw RuntimeException( buf
.makeStringAndClear() );
494 if( css::uno::TypeClass_EXCEPTION
== a
.getValueTypeClass() )
496 // add the message in a standard python way !
497 PyRef
args( PyTuple_New( 1 ), SAL_NO_ACQUIRE
, NOT_NULL
);
499 // assuming that the Message is always the first member, wuuuu
500 void const *pData
= a
.getValue();
501 OUString message
= *static_cast<OUString
const *>(pData
);
502 PyRef pymsg
= ustring2PyString( message
);
503 PyTuple_SetItem( args
.get(), 0 , pymsg
.getAcquired() );
504 // the exception base functions want to have an "args" tuple,
505 // which contains the message
506 PyObject_SetAttrString( ret
.get(), "args", args
.get() );
510 case typelib_TypeClass_SEQUENCE
:
514 Sequence
< sal_Int8
> byteSequence
;
515 if( a
>>= byteSequence
)
517 // byte sequence is treated in a special way because of peformance reasons
519 return PyRef( PyUNO_ByteSequence_new( byteSequence
, *this ), SAL_NO_ACQUIRE
);
523 Reference
< XTypeConverter
> tc
= getImpl()->cargo
->xTypeConverter
;
524 Reference
< XSingleServiceFactory
> ssf
= getImpl()->cargo
->xInvocation
;
525 tc
->convertTo (a
, cppu::UnoType
<decltype(s
)>::get()) >>= s
;
526 PyRef
tuple( PyTuple_New (s
.getLength()), SAL_NO_ACQUIRE
, NOT_NULL
);
530 for ( i
= 0; i
< s
.getLength (); i
++)
533 element
= any2PyObject (tc
->convertTo (s
[i
], s
[i
].getValueType() ));
534 OSL_ASSERT( element
.is() );
535 PyTuple_SetItem( tuple
.get(), i
, element
.getAcquired() );
538 catch( css::uno::Exception
& )
540 for( ; i
< s
.getLength() ; i
++ )
542 Py_INCREF( Py_None
);
543 PyTuple_SetItem( tuple
.get(), i
, Py_None
);
550 case typelib_TypeClass_INTERFACE
:
552 Reference
<XInterface
> tmp_interface
;
554 if (!tmp_interface
.is ())
557 return PyUNO_new( a
, getImpl()->cargo
->xInvocation
);
562 buf
.append( "Unknown UNO type class " );
563 buf
.append( (sal_Int32
) a
.getValueTypeClass() );
564 throw RuntimeException(buf
.makeStringAndClear( ) );
569 static Sequence
< Type
> invokeGetTypes( const Runtime
& r
, PyObject
* o
)
571 Sequence
< Type
> ret
;
573 PyRef
method( PyObject_GetAttrString( o
, "getTypes" ), SAL_NO_ACQUIRE
);
574 raiseInvocationTargetExceptionWhenNeeded( r
);
575 if( method
.is() && PyCallable_Check( method
.get() ) )
577 PyRef
types( PyObject_CallObject( method
.get(), nullptr ) , SAL_NO_ACQUIRE
);
578 raiseInvocationTargetExceptionWhenNeeded( r
);
579 if( types
.is() && PyTuple_Check( types
.get() ) )
581 int size
= PyTuple_Size( types
.get() );
583 // add the XUnoTunnel interface for uno object identity concept (hack)
584 ret
.realloc( size
+ 1 );
585 for( int i
= 0 ; i
< size
; i
++ )
587 Any a
= r
.pyObject2Any(PyTuple_GetItem(types
.get(),i
));
590 ret
[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( PyStr_AsString(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::list
<Any
> items
;
633 PyRef
rItem( pItem
, SAL_NO_ACQUIRE
);
634 items
.push_back( pyObject2Any( rItem
.get() ) );
636 while( (pItem
= PyIter_Next( pObj
)) );
637 a
<<= comphelper::containerToSequence
<Any
>(items
);
641 Any
Runtime::pyObject2Any ( const PyRef
& source
, enum ConversionMode mode
) const
642 throw ( css::uno::RuntimeException
)
644 if( ! impl
->cargo
->valid
)
646 throw RuntimeException("pyuno runtime must be initialized before calling any2PyObject" );
650 PyObject
*o
= source
.get();
655 // In Python 3, there is no PyInt type.
656 #if PY_MAJOR_VERSION < 3
657 else if (PyInt_Check (o
))
663 else if ( o
== Py_False
)
669 sal_Int32 l
= (sal_Int32
) PyLong_AsLong( o
);
670 if( l
< 128 && l
>= -128 )
672 sal_Int8 b
= (sal_Int8
) l
;
675 else if( l
<= 0x7fff && l
>= -0x8000 )
677 sal_Int16 s
= (sal_Int16
) l
;
686 #endif /* PY_MAJOR_VERSION < 3 */
687 else if (PyLong_Check (o
))
689 #if PY_MAJOR_VERSION >= 3
690 // Convert the Python 3 booleans that are actually of type PyLong.
695 else if(o
== Py_False
)
701 #endif /* PY_MAJOR_VERSION >= 3 */
702 sal_Int64 l
= (sal_Int64
)PyLong_AsLong (o
);
703 if( l
< 128 && l
>= -128 )
705 sal_Int8 b
= (sal_Int8
) l
;
708 else if( l
<= 0x7fff && l
>= -0x8000 )
710 sal_Int16 s
= (sal_Int16
) l
;
713 else if( l
<= SAL_CONST_INT64(0x7fffffff) &&
714 l
>= -SAL_CONST_INT64(0x80000000) )
716 sal_Int32 l32
= (sal_Int32
) l
;
723 #if PY_MAJOR_VERSION >= 3
727 else if (PyFloat_Check (o
))
729 double d
= PyFloat_AsDouble (o
);
732 else if (PyStrBytes_Check(o
) || PyUnicode_Check(o
))
734 a
<<= pyString2ustring(o
);
736 else if (PyTuple_Check (o
))
738 Sequence
<Any
> s (PyTuple_Size (o
));
739 for (Py_ssize_t i
= 0; i
< PyTuple_Size (o
); i
++)
741 s
[i
] = pyObject2Any (PyTuple_GetItem (o
, i
), mode
);
745 else if (PyList_Check (o
))
747 Py_ssize_t l
= PyList_Size (o
);
749 for (Py_ssize_t i
= 0; i
< l
; i
++)
751 s
[i
] = pyObject2Any (PyList_GetItem (o
, i
), mode
);
755 else if (!pyIterUnpack (o
, a
))
758 // should be removed, in case ByteSequence gets derived from String
759 if( PyObject_IsInstance( o
, getByteSequenceClass( runtime
).get() ) )
761 PyRef
str(PyObject_GetAttrString( o
, "value" ),SAL_NO_ACQUIRE
);
762 Sequence
< sal_Int8
> seq
;
763 if( PyStrBytes_Check( str
.get() ) )
765 seq
= Sequence
<sal_Int8
> (
766 reinterpret_cast<sal_Int8
*>(PyStrBytes_AsString(str
.get())), PyStrBytes_Size(str
.get()));
771 if( PyObject_IsInstance( o
, getTypeClass( runtime
).get() ) )
773 Type t
= PyType2Type( o
);
776 else if( PyObject_IsInstance( o
, getEnumClass( runtime
).get() ) )
778 a
= PyEnum2Enum( o
);
780 else if( isInstanceOfStructOrException( o
) )
782 PyRef
struc(PyObject_GetAttrString( o
, "value" ),SAL_NO_ACQUIRE
);
783 PyUNO
* obj
= reinterpret_cast<PyUNO
*>(struc
.get());
784 Reference
< XMaterialHolder
> holder( obj
->members
->xInvocation
, UNO_QUERY
);
786 a
= holder
->getMaterial();
789 throw RuntimeException(
790 "struct or exception wrapper does not support XMaterialHolder" );
793 else if( PyObject_IsInstance( o
, getPyUnoClass().get() ) )
795 PyUNO
* o_pi
= reinterpret_cast<PyUNO
*>(o
);
796 a
= o_pi
->members
->wrappedObject
;
798 else if( PyObject_IsInstance( o
, getPyUnoStructClass().get() ) )
800 PyUNO
* o_pi
= reinterpret_cast<PyUNO
*>(o
);
801 Reference
<XMaterialHolder
> my_mh (o_pi
->members
->xInvocation
, UNO_QUERY
);
805 throw RuntimeException(
806 "struct wrapper does not support XMaterialHolder" );
809 a
= my_mh
->getMaterial();
811 else if( PyObject_IsInstance( o
, getCharClass( runtime
).get() ) )
813 sal_Unicode c
= PyChar2Unicode( o
);
814 a
.setValue( &c
, cppu::UnoType
<cppu::UnoCharType
>::get());
816 else if( PyObject_IsInstance( o
, getAnyClass( runtime
).get() ) )
818 if( ACCEPT_UNO_ANY
== mode
)
820 a
= pyObject2Any( PyRef( PyObject_GetAttrString( o
, "value" ), SAL_NO_ACQUIRE
) );
822 pyObject2Any( PyRef( PyObject_GetAttrString( o
, "type" ), SAL_NO_ACQUIRE
) ) >>= t
;
826 a
= getImpl()->cargo
->xTypeConverter
->convertTo( a
, t
);
828 catch( const css::uno::Exception
& e
)
830 throw WrappedTargetRuntimeException(
831 e
.Message
, e
.Context
, makeAny(e
));
836 throw RuntimeException(
837 "uno.Any instance not accepted during method call, "
838 "use uno.invoke instead" );
843 Reference
< XInterface
> mappedObject
;
844 Reference
< XInvocation
> adapterObject
;
846 // instance already mapped out to the world ?
847 PyRef2Adapter::iterator ii
= impl
->cargo
->mappedObjects
.find( PyRef( o
) );
848 if( ii
!= impl
->cargo
->mappedObjects
.end() )
850 adapterObject
= ii
->second
;
853 if( adapterObject
.is() )
855 // object got already bridged !
856 Reference
< css::lang::XUnoTunnel
> tunnel( adapterObject
, UNO_QUERY
);
858 Adapter
*pAdapter
= reinterpret_cast<Adapter
*>(
859 tunnel
->getSomething(
860 ::pyuno::Adapter::getUnoTunnelImplementationId() ) );
862 mappedObject
= impl
->cargo
->xAdapterFactory
->createAdapter(
863 adapterObject
, pAdapter
->getWrappedTypes() );
868 Sequence
<Type
> interfaces
= invokeGetTypes(*this, o
);
869 if (interfaces
.getLength())
871 Adapter
*pAdapter
= new Adapter( o
, interfaces
);
873 getImpl()->cargo
->xAdapterFactory
->createAdapter(
874 pAdapter
, interfaces
);
876 // keep a list of exported objects to ensure object identity !
877 impl
->cargo
->mappedObjects
[ PyRef(o
) ] =
878 css::uno::WeakReference
< XInvocation
> ( pAdapter
);
880 } catch (InvocationTargetException
const& e
) {
881 OUString
const msg(lcl_ExceptionMessage(o
, &e
.Message
));
882 throw WrappedTargetRuntimeException( // re-wrap that
883 msg
, e
.Context
, e
.TargetException
);
886 if( mappedObject
.is() )
888 a
= css::uno::makeAny( mappedObject
);
892 OUString
const msg(lcl_ExceptionMessage(o
, nullptr));
893 throw RuntimeException(msg
);
900 Any
Runtime::extractUnoException( const PyRef
& excType
, const PyRef
&excValue
, const PyRef
&excTraceback
) const
904 if( excTraceback
.is() )
912 unoModule
= impl
->cargo
->getUnoModule();
914 catch (const Exception
&ei
)
921 PyRef
extractTraceback(
922 PyDict_GetItemString(unoModule
.get(),"_uno_extract_printable_stacktrace" ) );
924 if( PyCallable_Check(extractTraceback
.get()) )
926 PyRef
args( PyTuple_New( 1), SAL_NO_ACQUIRE
, NOT_NULL
);
927 PyTuple_SetItem( args
.get(), 0, excTraceback
.getAcquired() );
928 PyRef
pyStr( PyObject_CallObject( extractTraceback
.get(),args
.get() ), SAL_NO_ACQUIRE
);
929 str
= OUString::createFromAscii( PyStr_AsString(pyStr
.get()) );
933 str
= "Couldn't find uno._uno_extract_printable_stacktrace";
938 str
= "Could not load uno.py, no stacktrace available";
939 if ( !e
.Message
.isEmpty() )
941 str
+= " (Error loading uno.py: " + e
.Message
+ ")";
948 // it may occur, that no traceback is given (e.g. only native code below)
949 str
= "no traceback available";
952 if( isInstanceOfStructOrException( excValue
.get() ) )
954 ret
= pyObject2Any( excValue
);
959 PyRef
typeName( PyObject_Str( excType
.get() ), SAL_NO_ACQUIRE
);
962 buf
.appendAscii( PyStr_AsString( typeName
.get() ) );
966 buf
.append( "no typename available" );
969 PyRef
valueRep( PyObject_Str( excValue
.get() ), SAL_NO_ACQUIRE
);
972 buf
.appendAscii( PyStr_AsString( valueRep
.get()));
976 buf
.append( "Couldn't convert exception value to a string" );
978 buf
.append( ", traceback follows\n" );
986 buf
.append( ", no traceback available\n" );
989 e
.Message
= buf
.makeStringAndClear();
990 #if OSL_DEBUG_LEVEL > 0
991 fprintf( stderr
, "Python exception: %s\n",
992 OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).getStr() );
994 ret
= css::uno::makeAny( e
);
1000 PyThreadAttach::PyThreadAttach( PyInterpreterState
*interp
)
1001 throw ( css::uno::RuntimeException
)
1003 tstate
= PyThreadState_New( interp
);
1005 throw RuntimeException( "Couldn't create a pythreadstate" );
1006 PyEval_AcquireThread( tstate
);
1009 PyThreadAttach::~PyThreadAttach()
1011 PyThreadState_Clear( tstate
);
1012 PyEval_ReleaseThread( tstate
);
1013 PyThreadState_Delete( tstate
);
1016 PyThreadDetach::PyThreadDetach() throw ( css::uno::RuntimeException
)
1018 tstate
= PyThreadState_Get();
1019 PyEval_ReleaseThread( tstate
);
1022 /** Acquires the global interpreter lock again
1025 PyThreadDetach::~PyThreadDetach()
1027 PyEval_AcquireThread( tstate
);
1031 PyRef
RuntimeCargo::getUnoModule()
1033 if( ! dictUnoModule
.is() )
1035 dictUnoModule
= importUnoModule();
1037 return dictUnoModule
;
1041 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */