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"
25 #include <string_view>
26 #include <unordered_map>
28 #include <osl/module.hxx>
29 #include <osl/thread.h>
30 #include <osl/diagnose.h>
31 #include <osl/file.hxx>
32 #include <sal/log.hxx>
34 #include <typelib/typedescription.hxx>
36 #include <rtl/ustring.hxx>
37 #include <rtl/strbuf.hxx>
38 #include <rtl/ustrbuf.hxx>
40 #include <rtl/bootstrap.hxx>
42 #include <uno/current_context.hxx>
43 #include <cppuhelper/bootstrap.hxx>
45 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
46 #include <com/sun/star/reflection/XConstantTypeDescription.hpp>
47 #include <com/sun/star/reflection/XIdlClass.hpp>
48 #include <com/sun/star/registry/InvalidRegistryException.hpp>
49 #include <com/sun/star/script/CannotConvertException.hpp>
50 #include <com/sun/star/uno/XComponentContext.hpp>
51 #include <com/sun/star/script/XInvocation2.hpp>
52 #include <com/sun/star/reflection/XIdlReflection.hpp>
53 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
58 using com::sun::star::uno::Sequence
;
59 using com::sun::star::uno::Reference
;
60 using com::sun::star::uno::Any
;
61 using com::sun::star::uno::RuntimeException
;
62 using com::sun::star::uno::TypeDescription
;
63 using com::sun::star::uno::XComponentContext
;
64 using com::sun::star::container::NoSuchElementException
;
65 using com::sun::star::reflection::XIdlClass
;
66 using com::sun::star::script::XInvocation2
;
68 using namespace pyuno
;
73 @ index of the next to be used member in the initializer list !
75 // LEM TODO: export member names as keyword arguments in initialiser?
76 // Python supports very flexible variadic functions. By marking
77 // variables with one asterisk (e.g. *var) the given variable is
78 // defined to be a tuple of all the extra arguments. By marking
79 // variables with two asterisks (e.g. **var) the given variable is a
80 // dictionary of all extra keyword arguments; the keys are strings,
81 // which are the names that were used to identify the arguments. If
82 // they exist, these arguments must be the last one in the list.
86 // Keyword arguments used
88 // Which structure members are initialised
89 std::unordered_map
<OUString
, bool> initialised
;
90 // How many positional arguments are consumed
91 // This is always the so-many first ones
92 sal_Int32 nPosConsumed
;
100 throw RuntimeException(u
"pyuno._createUnoStructHelper failed to create new dictionary"_ustr
);
106 void setUsed(PyObject
*key
)
108 PyDict_SetItem(used
, key
, Py_True
);
110 void setInitialised(const OUString
& key
, sal_Int32 pos
= -1)
112 if (initialised
[key
])
114 OUStringBuffer
buf( "pyuno._createUnoStructHelper: member '" + key
+ "'");
117 buf
.append( " at position " + OUString::number(pos
));
119 buf
.append( " initialised multiple times.");
120 throw RuntimeException(buf
.makeStringAndClear());
122 initialised
[key
] = true;
126 bool isInitialised(const OUString
& key
)
128 return initialised
[key
];
130 PyObject
*getUsed() const
134 sal_Int32
getCntConsumed() const
140 /// @throws RuntimeException
142 const Reference
< XInvocation2
> &inv
,
143 typelib_CompoundTypeDescription
*pCompType
,
144 PyObject
*initializer
,
145 PyObject
*kwinitializer
,
146 fillStructState
&state
,
147 const Runtime
&runtime
)
149 if( pCompType
->pBaseTypeDescription
)
150 fillStruct( inv
, pCompType
->pBaseTypeDescription
, initializer
, kwinitializer
, state
, runtime
);
152 const sal_Int32 nMembers
= pCompType
->nMembers
;
154 for( int i
= 0 ; i
< nMembers
; i
++ )
156 const OUString
OUMemberName (pCompType
->ppMemberNames
[i
]);
157 PyObject
*pyMemberName
=
158 PyUnicode_FromString(OUStringToOString(OUMemberName
,
159 RTL_TEXTENCODING_UTF8
).getStr());
160 if ( PyObject
*element
= PyDict_GetItem(kwinitializer
, pyMemberName
) )
162 state
.setInitialised(OUMemberName
);
163 state
.setUsed(pyMemberName
);
164 Any a
= runtime
.pyObject2Any( element
, ACCEPT_UNO_ANY
);
165 inv
->setValue( OUMemberName
, a
);
170 const int remainingPosInitialisers
= PyTuple_Size(initializer
) - state
.getCntConsumed();
171 for( int i
= 0 ; i
< remainingPosInitialisers
&& i
< nMembers
; i
++ )
173 const int tupleIndex
= state
.getCntConsumed();
174 const OUString
aMemberName (pCompType
->ppMemberNames
[i
]);
175 state
.setInitialised(aMemberName
, tupleIndex
);
176 PyObject
*element
= PyTuple_GetItem( initializer
, tupleIndex
);
177 Any a
= runtime
.pyObject2Any( element
, ACCEPT_UNO_ANY
);
178 inv
->setValue( aMemberName
, a
);
181 if ( PyTuple_Size( initializer
) <= 0 )
184 // Allow partial initialisation when only keyword arguments are given
185 for ( int i
= 0; i
< nMembers
; ++i
)
187 const OUString
memberName (pCompType
->ppMemberNames
[i
]);
188 if ( ! state
.isInitialised( memberName
) )
190 OUString buf
= "pyuno._createUnoStructHelper: member '" +
192 "' of struct type '" +
193 OUString::unacquired(&pCompType
->aBase
.pTypeName
) +
194 "' not given a value.";
195 throw RuntimeException(buf
);
200 const OUString
& getLibDir();
201 OUString
getLibDirImpl()
205 // workarounds the $(ORIGIN) until it is available
206 if (Module::getUrlFromAddress(reinterpret_cast<oslGenericFunction
>(getLibDir
), libDir
))
208 libDir
= libDir
.copy(0, libDir
.lastIndexOf('/'));
209 OUString
name(u
"PYUNOLIBDIR"_ustr
);
210 rtl_bootstrap_set(name
.pData
, libDir
.pData
);
215 const OUString
& getLibDir()
217 static OUString sLibDir
= getLibDirImpl();
221 void raisePySystemException( const char * exceptionType
, std::u16string_view message
)
223 OString buf
= OString::Concat("Error during bootstrapping uno (") +
226 OUStringToOString( message
, osl_getThreadTextEncoding() );
227 PyErr_SetString( PyExc_SystemError
, buf
.getStr() );
232 static PyObject
* getComponentContext(
233 SAL_UNUSED_PARAMETER PyObject
*, SAL_UNUSED_PARAMETER PyObject
*)
238 Reference
<XComponentContext
> ctx
;
240 // getLibDir() must be called in order to set bootstrap variables correctly !
241 const OUString
& path( getLibDir());
242 if( Runtime::isInitialized() )
245 ctx
= runtime
.getImpl()->cargo
->xContext
;
252 PyExc_RuntimeError
, "osl_getUrlFromAddress fails, that's why I cannot find ini "
253 "file for bootstrapping python uno bridge\n" );
257 OUString iniFile
= path
+
259 "/../" LIBO_ETC_FOLDER
261 "/" SAL_CONFIGFILE( "pyuno" );
262 osl::DirectoryItem item
;
263 if( osl::DirectoryItem::get( iniFile
, item
) == osl::FileBase::E_None
)
265 // in case pyuno.ini exists, use this file for bootstrapping
266 PyThreadDetach antiguard
;
267 ctx
= cppu::defaultBootstrap_InitialComponentContext (iniFile
);
271 // defaulting to the standard bootstrapping
272 PyThreadDetach antiguard
;
273 ctx
= cppu::defaultBootstrap_InitialComponentContext ();
278 if( ! Runtime::isInitialized() )
280 Runtime::initialize( ctx
);
283 ret
= runtime
.any2PyObject( Any( ctx
) );
285 catch (const css::registry::InvalidRegistryException
&e
)
287 // can't use raisePyExceptionWithAny() here, because the function
288 // does any conversions, which will not work with a
289 // wrongly bootstrapped pyuno!
290 raisePySystemException( "InvalidRegistryException", e
.Message
);
292 catch(const css::lang::IllegalArgumentException
& e
)
294 raisePySystemException( "IllegalArgumentException", e
.Message
);
296 catch(const css::script::CannotConvertException
& e
)
298 raisePySystemException( "CannotConvertException", e
.Message
);
300 catch (const css::uno::RuntimeException
& e
)
302 raisePySystemException( "RuntimeException", e
.Message
);
304 catch (const css::uno::Exception
& e
)
306 raisePySystemException( "uno::Exception", e
.Message
);
308 return ret
.getAcquired();
311 // While pyuno.private_initTestEnvironment is called from individual Python tests (e.g., from
312 // UnoInProcess in unotest/source/python/org/libreoffice/unotest.py, which makes sure to call it
313 // only once), pyuno.private_deinitTestEnvironment is called centrally from
314 // unotest/source/python/org/libreoffice/unittest.py at the end of every PythonTest (to DeInitVCL
315 // exactly once near the end of the process, if InitVCL has ever been called via
316 // pyuno.private_initTestEnvironment):
318 osl::Module
* testModule
= nullptr;
320 static PyObject
* initTestEnvironment(
321 SAL_UNUSED_PARAMETER PyObject
*, SAL_UNUSED_PARAMETER PyObject
*)
323 // this tries to bootstrap enough of the soffice from python to run
324 // unit tests, which is only possible indirectly because pyuno is URE
325 // so load "test" library and invoke a function there to do the work
326 assert(testModule
== nullptr);
329 PyObject
*const ctx(getComponentContext(nullptr, nullptr));
330 if (!ctx
) { abort(); }
331 Runtime
const runtime
;
332 Any
const a(runtime
.pyObject2Any(ctx
));
333 Reference
<XComponentContext
> xContext
;
335 if (!xContext
.is()) { abort(); }
336 using css::lang::XMultiServiceFactory
;
337 Reference
<XMultiServiceFactory
> const xMSF(
338 xContext
->getServiceManager(),
339 css::uno::UNO_QUERY_THROW
);
340 char *const testlib
= getenv("TEST_LIB");
341 if (!testlib
) { abort(); }
343 OString
const libname
= OString(testlib
, strlen(testlib
))
344 .replaceAll(OString('/'), OString('\\'));
346 OString
const libname(testlib
, strlen(testlib
));
349 osl::Module
&mod
= runtime
.getImpl()->cargo
->testModule
;
350 mod
.load(OStringToOUString(libname
, osl_getThreadTextEncoding()),
351 SAL_LOADMODULE_LAZY
| SAL_LOADMODULE_GLOBAL
);
352 if (!mod
.is()) { abort(); }
353 oslGenericFunction
const pFunc(
354 mod
.getFunctionSymbol("test_init"));
355 if (!pFunc
) { abort(); }
356 reinterpret_cast<void (SAL_CALL
*)(XMultiServiceFactory
*)>(pFunc
)(xMSF
.get());
359 catch (const css::uno::Exception
&)
366 static PyObject
* deinitTestEnvironment(
367 SAL_UNUSED_PARAMETER PyObject
*, SAL_UNUSED_PARAMETER PyObject
*)
369 if (testModule
!= nullptr)
373 oslGenericFunction
const pFunc(
374 testModule
->getFunctionSymbol("test_deinit"));
375 if (!pFunc
) { abort(); }
376 reinterpret_cast<void (SAL_CALL
*)()>(pFunc
)();
378 catch (const css::uno::Exception
&)
386 static PyObject
* initTestEnvironmentGPG(
387 SAL_UNUSED_PARAMETER PyObject
*, PyObject
* args
)
389 // this tries to set up certificate stores for unit tests
390 // which is only possible indirectly because pyuno is URE
391 // so load "unotest" library and invoke a function there to do the work
392 Runtime
const runtime
;
393 osl::Module
& rModule(runtime
.getImpl()->cargo
->unoTestModule
);
394 assert(!rModule
.is());
397 char *const testlib
= getenv("UNOTEST_LIB");
398 if (!testlib
) { abort(); }
400 OString
const libname
= OString(testlib
, strlen(testlib
))
401 .replaceAll(OString('/'), OString('\\'));
403 OString
const libname(testlib
, strlen(testlib
));
406 rModule
.load(OStringToOUString(libname
, osl_getThreadTextEncoding()),
407 SAL_LOADMODULE_LAZY
| SAL_LOADMODULE_GLOBAL
);
408 if (!rModule
.is()) { abort(); }
409 oslGenericFunction
const pFunc(rModule
.getFunctionSymbol("test_init_gpg"));
410 if (!pFunc
) { abort(); }
412 if (!PyArg_ParseTuple(args
, "s", &pTestDirURL
)) { abort(); }
413 OUString
const testDirURL(OUString::createFromAscii(pTestDirURL
));
414 reinterpret_cast<void (SAL_CALL
*)(OUString
const&)>(pFunc
)(testDirURL
);
416 catch (const css::uno::Exception
&)
423 static PyObject
* deinitTestEnvironmentGPG(
424 SAL_UNUSED_PARAMETER PyObject
*, SAL_UNUSED_PARAMETER PyObject
*)
426 Runtime
const runtime
;
427 osl::Module
& rModule(runtime
.getImpl()->cargo
->unoTestModule
);
432 oslGenericFunction
const pFunc(
433 rModule
.getFunctionSymbol("test_deinit_gpg"));
434 if (!pFunc
) { abort(); }
435 reinterpret_cast<void (SAL_CALL
*)()>(pFunc
)();
437 catch (const css::uno::Exception
&)
445 PyObject
* extractOneStringArg( PyObject
*args
, char const *funcName
)
447 if( !PyTuple_Check( args
) || PyTuple_Size( args
) != 1 )
449 OString buf
= funcName
+ OString::Concat(": expecting one string argument");
450 PyErr_SetString( PyExc_RuntimeError
, buf
.getStr() );
453 PyObject
*obj
= PyTuple_GetItem( args
, 0 );
454 if (!PyUnicode_Check(obj
))
456 OString buf
= funcName
+ OString::Concat(": expecting one string argument");
457 PyErr_SetString( PyExc_TypeError
, buf
.getStr());
463 static PyObject
*createUnoStructHelper(
464 SAL_UNUSED_PARAMETER PyObject
*, PyObject
* args
, PyObject
* keywordArgs
)
471 if( PyTuple_Size( args
) == 2 )
473 PyObject
*structName
= PyTuple_GetItem(args
, 0);
474 PyObject
*initializer
= PyTuple_GetItem(args
, 1);
476 if (PyUnicode_Check(structName
))
478 if( PyTuple_Check( initializer
) && PyDict_Check ( keywordArgs
) )
480 OUString
typeName( OUString::createFromAscii(PyUnicode_AsUTF8(structName
)));
481 RuntimeCargo
*c
= runtime
.getImpl()->cargo
;
482 Reference
<XIdlClass
> idl_class
= c
->xCoreReflection
->forName (typeName
);
485 idl_class
->createObject (IdlStruct
);
486 PyRef
returnCandidate( PyUNOStruct_new( IdlStruct
, c
->xInvocation
) );
487 PyUNO
*me
= reinterpret_cast<PyUNO
*>( returnCandidate
.get() );
488 TypeDescription
desc( typeName
);
489 OSL_ASSERT( desc
.is() ); // could already instantiate an XInvocation2 !
491 typelib_CompoundTypeDescription
*pCompType
=
492 reinterpret_cast<typelib_CompoundTypeDescription
*>(desc
.get());
493 fillStructState state
;
494 if ( PyTuple_Size( initializer
) > 0 || PyDict_Size( keywordArgs
) > 0 )
495 fillStruct( me
->members
->xInvocation
, pCompType
, initializer
, keywordArgs
, state
, runtime
);
496 if( state
.getCntConsumed() != PyTuple_Size(initializer
) )
498 throw RuntimeException( "pyuno._createUnoStructHelper: too many "
499 "elements in the initializer list, expected " +
500 OUString::number(state
.getCntConsumed()) + ", got " +
501 OUString::number( PyTuple_Size(initializer
) ) );
503 ret
= PyRef( PyTuple_Pack(2, returnCandidate
.get(), state
.getUsed()), SAL_NO_ACQUIRE
);
507 OString buf
= OString::Concat("UNO struct ")
508 + PyUnicode_AsUTF8(structName
)
510 PyErr_SetString (PyExc_RuntimeError
, buf
.getStr());
517 "pyuno._createUnoStructHelper: 2nd argument (initializer sequence) is no tuple" );
522 PyErr_SetString (PyExc_AttributeError
, "createUnoStruct: first argument wasn't a string");
527 PyErr_SetString (PyExc_AttributeError
, "pyuno._createUnoStructHelper: expects exactly two non-keyword arguments:\n\tStructure Name\n\tinitialiser tuple; may be the empty tuple");
530 catch( const css::uno::RuntimeException
& e
)
532 raisePyExceptionWithAny( Any( e
) );
534 catch( const css::script::CannotConvertException
& e
)
536 raisePyExceptionWithAny( Any( e
) );
538 catch( const css::uno::Exception
& e
)
540 raisePyExceptionWithAny( Any( e
) );
542 return ret
.getAcquired();
545 static PyObject
*getTypeByName(
546 SAL_UNUSED_PARAMETER PyObject
*, PyObject
*args
)
548 PyObject
* ret
= nullptr;
554 if (PyArg_ParseTuple (args
, "s", &name
))
556 OUString
typeName ( OUString::createFromAscii( name
) );
557 TypeDescription
typeDesc( typeName
);
561 ret
= PyUNO_Type_new(
562 name
, static_cast<css::uno::TypeClass
>(typeDesc
.get()->eTypeClass
), runtime
);
566 OString buf
= OString::Concat("Type ") + name
+ " is unknown";
567 PyErr_SetString( PyExc_RuntimeError
, buf
.getStr() );
571 catch ( const RuntimeException
& e
)
573 raisePyExceptionWithAny( Any( e
) );
578 static PyObject
*getConstantByName(
579 SAL_UNUSED_PARAMETER PyObject
*, PyObject
*args
)
581 PyObject
*ret
= nullptr;
586 if (PyArg_ParseTuple (args
, "s", &name
))
588 OUString
typeName ( OUString::createFromAscii( name
) );
590 css::uno::Reference
< css::reflection::XConstantTypeDescription
> td
;
591 if (!(runtime
.getImpl()->cargo
->xTdMgr
->getByHierarchicalName(
595 throw RuntimeException( "pyuno.getConstantByName: " + typeName
+ "is not a constant" );
597 PyRef constant
= runtime
.any2PyObject( td
->getConstantValue() );
598 ret
= constant
.getAcquired();
601 catch( const NoSuchElementException
& e
)
603 // to the python programmer, this is a runtime exception,
604 // do not support tweakings with the type system
605 RuntimeException
runExc( e
.Message
);
606 raisePyExceptionWithAny( Any( runExc
) );
608 catch(const css::script::CannotConvertException
& e
)
610 raisePyExceptionWithAny( Any( e
) );
612 catch(const css::lang::IllegalArgumentException
& e
)
614 raisePyExceptionWithAny( Any( e
) );
616 catch( const RuntimeException
& e
)
618 raisePyExceptionWithAny( Any(e
) );
623 static PyObject
*checkType( SAL_UNUSED_PARAMETER PyObject
*, PyObject
*args
)
625 if( !PyTuple_Check( args
) || PyTuple_Size( args
) != 1 )
627 OString buf
= "pyuno.checkType : expecting one uno.Type argument"_ostr
;
628 PyErr_SetString( PyExc_RuntimeError
, buf
.getStr() );
631 PyObject
*obj
= PyTuple_GetItem( args
, 0 );
637 catch(const RuntimeException
& e
)
639 raisePyExceptionWithAny( Any( e
) );
642 Py_INCREF( Py_None
);
646 static PyObject
*checkEnum( SAL_UNUSED_PARAMETER PyObject
*, PyObject
*args
)
648 if( !PyTuple_Check( args
) || PyTuple_Size( args
) != 1 )
650 OString buf
= "pyuno.checkType : expecting one uno.Type argument"_ostr
;
651 PyErr_SetString( PyExc_RuntimeError
, buf
.getStr() );
654 PyObject
*obj
= PyTuple_GetItem( args
, 0 );
660 catch(const RuntimeException
& e
)
662 raisePyExceptionWithAny( Any( e
) );
665 Py_INCREF( Py_None
);
669 static PyObject
*getClass( SAL_UNUSED_PARAMETER PyObject
*, PyObject
*args
)
671 PyObject
*obj
= extractOneStringArg( args
, "pyuno.getClass");
678 PyRef ret
= getClass(pyString2ustring(obj
), runtime
);
679 Py_XINCREF( ret
.get() );
682 catch(const RuntimeException
& e
)
684 raisePyExceptionWithAny( Any(e
) );
689 static PyObject
*isInterface( SAL_UNUSED_PARAMETER PyObject
*, PyObject
*args
)
692 if( PyTuple_Check( args
) && PyTuple_Size( args
) == 1 )
694 PyObject
*obj
= PyTuple_GetItem( args
, 0 );
696 return PyLong_FromLong( isInterfaceClass( r
, obj
) );
698 return PyLong_FromLong( 0 );
701 static PyObject
* generateUuid(
702 SAL_UNUSED_PARAMETER PyObject
*, SAL_UNUSED_PARAMETER PyObject
* )
704 Sequence
< sal_Int8
> seq( 16 );
705 rtl_createUuid( reinterpret_cast<sal_uInt8
*>(seq
.getArray()) , nullptr , false );
710 ret
= runtime
.any2PyObject( Any( seq
) );
712 catch( const RuntimeException
& e
)
714 raisePyExceptionWithAny( Any(e
) );
716 return ret
.getAcquired();
719 static PyObject
*systemPathToFileUrl(
720 SAL_UNUSED_PARAMETER PyObject
*, PyObject
* args
)
722 PyObject
*obj
= extractOneStringArg( args
, "pyuno.systemPathToFileUrl" );
726 OUString sysPath
= pyString2ustring( obj
);
728 osl::FileBase::RC e
= osl::FileBase::getFileURLFromSystemPath( sysPath
, url
);
730 if( e
!= osl::FileBase::E_None
)
732 OUString buf
= "Couldn't convert " +
734 " to a file url for reason (" +
735 OUString::number( static_cast<sal_Int32
>(e
) ) +
737 raisePyExceptionWithAny(
738 Any( RuntimeException( buf
)));
741 return ustring2PyUnicode( url
).getAcquired();
744 static PyObject
* fileUrlToSystemPath(
745 SAL_UNUSED_PARAMETER PyObject
*, PyObject
* args
)
747 PyObject
*obj
= extractOneStringArg( args
, "pyuno.fileUrlToSystemPath" );
751 OUString url
= pyString2ustring( obj
);
753 osl::FileBase::RC e
= osl::FileBase::getSystemPathFromFileURL( url
, sysPath
);
755 if( e
!= osl::FileBase::E_None
)
757 OUString buf
= "Couldn't convert file url " +
759 " to a system path for reason (" +
760 OUString::number( static_cast<sal_Int32
>(e
) ) +
762 raisePyExceptionWithAny(
763 Any( RuntimeException( buf
)));
766 return ustring2PyUnicode( sysPath
).getAcquired();
769 static PyObject
* absolutize( SAL_UNUSED_PARAMETER PyObject
*, PyObject
* args
)
771 if( !PyTuple_Check( args
) || PyTuple_Size( args
) != 2 )
774 OUString ouPath
= pyString2ustring( PyTuple_GetItem( args
, 0 ) );
775 OUString ouRel
= pyString2ustring( PyTuple_GetItem( args
, 1 ) );
777 oslFileError e
= osl_getAbsoluteFileURL( ouPath
.pData
, ouRel
.pData
, &(ret
.pData
) );
778 if( e
!= osl_File_E_None
)
781 "Couldn't absolutize " +
786 OUString::number(static_cast<sal_Int32
>(e
) ) +
791 OUStringToOString(buf
,osl_getThreadTextEncoding()).getStr());
794 return ustring2PyUnicode( ret
).getAcquired();
797 static PyObject
* invoke(SAL_UNUSED_PARAMETER PyObject
*, PyObject
*args
)
799 PyObject
*ret
= nullptr;
800 if(PyTuple_Check(args
) && PyTuple_Size(args
) == 3)
802 PyObject
*object
= PyTuple_GetItem(args
, 0);
803 PyObject
*item1
= PyTuple_GetItem(args
, 1);
804 if (PyUnicode_Check(item1
))
806 const char *name
= PyUnicode_AsUTF8(item1
);
807 PyObject
*item2
= PyTuple_GetItem(args
, 2);
808 if(PyTuple_Check(item2
))
810 ret
= PyUNO_invoke(object
, name
, item2
);
814 OString buf
= OString::Concat("uno.invoke expects a tuple as 3rd argument, got ")
815 + PyUnicode_AsUTF8(PyObject_Str(item2
));
817 PyExc_RuntimeError
, buf
.getStr());
822 OString buf
= OString::Concat("uno.invoke expected a string as 2nd argument, got ")
823 + PyUnicode_AsUTF8(PyObject_Str(item1
));
825 PyExc_RuntimeError
, buf
.getStr());
830 OString buf
= "uno.invoke expects object, name, (arg1, arg2, ... )\n"_ostr
;
831 PyErr_SetString(PyExc_RuntimeError
, buf
.getStr());
836 static PyObject
*getCurrentContext(
837 SAL_UNUSED_PARAMETER PyObject
*, SAL_UNUSED_PARAMETER PyObject
* )
843 ret
= runtime
.any2PyObject(
844 Any( css::uno::getCurrentContext() ) );
846 catch( const css::uno::Exception
& e
)
848 raisePyExceptionWithAny( Any( e
) );
850 return ret
.getAcquired();
853 static PyObject
*setCurrentContext(
854 SAL_UNUSED_PARAMETER PyObject
*, SAL_UNUSED_PARAMETER PyObject
* args
)
859 if( PyTuple_Check( args
) && PyTuple_Size( args
) == 1 )
863 Any a
= runtime
.pyObject2Any( PyTuple_GetItem( args
, 0 ) );
865 Reference
< css::uno::XCurrentContext
> context
;
867 if( (a
.hasValue() && (a
>>= context
)) || ! a
.hasValue() )
869 ret
= css::uno::setCurrentContext( context
) ? Py_True
: Py_False
;
874 OString::Concat("uno.setCurrentContext expects an XComponentContext implementation, got ")
875 + PyUnicode_AsUTF8(PyObject_Str(PyTuple_GetItem(args
, 0)));
877 PyExc_RuntimeError
, buf
.getStr() );
882 OString buf
= "uno.setCurrentContext expects exactly one argument (the current Context)\n"_ostr
;
884 PyExc_RuntimeError
, buf
.getStr() );
887 catch( const css::uno::Exception
& e
)
889 raisePyExceptionWithAny( Any( e
) );
891 return ret
.getAcquired();
894 static PyObject
*sal_debug(
895 SAL_UNUSED_PARAMETER PyObject
*, SAL_UNUSED_PARAMETER PyObject
* args
)
897 Py_INCREF( Py_None
);
898 if( !PyTuple_Check( args
) || PyTuple_Size( args
) != 1 )
901 OUString line
= pyString2ustring( PyTuple_GetItem( args
, 0 ) );
910 #if defined __GNUC__ && !defined __clang__
911 #pragma GCC diagnostic push
912 #pragma GCC diagnostic ignored "-Wcast-function-type"
914 struct PyMethodDef PyUNOModule_methods
[] =
916 {"private_initTestEnvironment", initTestEnvironment
, METH_VARARGS
, nullptr},
917 {"private_deinitTestEnvironment", deinitTestEnvironment
, METH_VARARGS
, nullptr},
918 {"private_initTestEnvironmentGPG", initTestEnvironmentGPG
, METH_VARARGS
, nullptr},
919 {"private_deinitTestEnvironmentGPG", deinitTestEnvironmentGPG
, METH_VARARGS
, nullptr},
920 {"getComponentContext", getComponentContext
, METH_VARARGS
, nullptr},
921 #if defined __clang__
922 #pragma clang diagnostic push
923 #if __has_warning("-Wcast-function-type-mismatch")
924 #pragma clang diagnostic ignored "-Wcast-function-type-mismatch"
927 {"_createUnoStructHelper", reinterpret_cast<PyCFunction
>(createUnoStructHelper
), METH_VARARGS
| METH_KEYWORDS
, nullptr},
928 #if defined __clang__
929 #if __has_warning("-Wcast-function-type-mismatch")
930 #pragma clang diagnostic pop
933 {"getTypeByName", getTypeByName
, METH_VARARGS
, nullptr},
934 {"getConstantByName", getConstantByName
, METH_VARARGS
, nullptr},
935 {"getClass", getClass
, METH_VARARGS
, nullptr},
936 {"checkEnum", checkEnum
, METH_VARARGS
, nullptr},
937 {"checkType", checkType
, METH_VARARGS
, nullptr},
938 {"generateUuid", generateUuid
, METH_VARARGS
, nullptr},
939 {"systemPathToFileUrl", systemPathToFileUrl
, METH_VARARGS
, nullptr},
940 {"fileUrlToSystemPath", fileUrlToSystemPath
, METH_VARARGS
, nullptr},
941 {"absolutize", absolutize
, METH_VARARGS
| METH_KEYWORDS
, nullptr},
942 {"isInterface", isInterface
, METH_VARARGS
, nullptr},
943 {"invoke", invoke
, METH_VARARGS
| METH_KEYWORDS
, nullptr},
944 {"setCurrentContext", setCurrentContext
, METH_VARARGS
, nullptr},
945 {"getCurrentContext", getCurrentContext
, METH_VARARGS
, nullptr},
946 {"sal_debug", sal_debug
, METH_VARARGS
, nullptr},
947 {nullptr, nullptr, 0, nullptr}
949 #if defined __GNUC__ && !defined __clang__
950 #pragma GCC diagnostic pop
956 PyObject
* PyInit_pyuno()
959 PyUNOStruct_initType();
960 // noop when called already, otherwise needed to allow multiple threads
961 #if PY_VERSION_HEX < 0x03090000
962 PyEval_InitThreads();
964 static struct PyModuleDef moduledef
=
966 PyModuleDef_HEAD_INIT
,
967 "pyuno", // module name
968 nullptr, // module documentation
969 -1, // module keeps state in global variables,
970 PyUNOModule_methods
, // modules methods
971 nullptr, // m_reload (must be 0)
972 nullptr, // m_traverse
976 return PyModule_Create(&moduledef
);
979 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */