1 /* -*- Mode: C++; 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 <sal/config.h>
25 #include <rtl/ustrbuf.hxx>
27 #include <typelib/typedescription.hxx>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/lang/XTypeProvider.hpp>
31 #include <com/sun/star/beans/UnknownPropertyException.hpp>
32 #include <com/sun/star/container/XEnumerationAccess.hpp>
33 #include <com/sun/star/container/XIndexAccess.hpp>
34 #include <com/sun/star/container/XIndexContainer.hpp>
35 #include <com/sun/star/container/XIndexReplace.hpp>
36 #include <com/sun/star/container/XNameAccess.hpp>
37 #include <com/sun/star/container/XNameContainer.hpp>
38 #include <com/sun/star/container/XNameReplace.hpp>
39 #include <com/sun/star/script/CannotConvertException.hpp>
40 #include <com/sun/star/script/XInvocation2.hpp>
41 #include <com/sun/star/script/XTypeConverter.hpp>
42 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
43 #include <comphelper/servicehelper.hxx>
45 #include "pyuno_impl.hxx"
47 using com::sun::star::uno::Sequence
;
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::UNO_QUERY
;
52 using com::sun::star::uno::Type
;
53 using com::sun::star::uno::TypeClass
;
54 using com::sun::star::uno::TypeDescription
;
55 using com::sun::star::uno::RuntimeException
;
56 using com::sun::star::uno::Exception
;
57 using com::sun::star::lang::XSingleServiceFactory
;
58 using com::sun::star::lang::XServiceInfo
;
59 using com::sun::star::lang::XTypeProvider
;
60 using com::sun::star::lang::XUnoTunnel
;
61 using com::sun::star::script::XInvocation2
;
62 using com::sun::star::container::XEnumeration
;
63 using com::sun::star::container::XEnumerationAccess
;
64 using com::sun::star::container::XIndexAccess
;
65 using com::sun::star::container::XIndexContainer
;
66 using com::sun::star::container::XIndexReplace
;
67 using com::sun::star::container::XNameAccess
;
68 using com::sun::star::container::XNameContainer
;
69 using com::sun::star::container::XNameReplace
;
74 static PyObject
*PyUNO_str( PyObject
* self
);
76 static void PyUNO_del (PyObject
* self
)
78 PyUNO
* me
= reinterpret_cast< PyUNO
* > (self
);
80 PyThreadDetach antiguard
;
87 OUString
val2str( const void * pVal
, typelib_TypeDescriptionReference
* pTypeRef
, sal_Int32 mode
)
90 if (pTypeRef
->eTypeClass
== typelib_TypeClass_VOID
)
93 OUStringBuffer
buf( 64 );
94 buf
.append( "(" + OUString::unacquired(&pTypeRef
->pTypeName
) + ")" );
96 switch (pTypeRef
->eTypeClass
)
98 case typelib_TypeClass_INTERFACE
:
101 OUString::number( reinterpret_cast< sal_IntPtr
>(*static_cast<void * const *>(pVal
)), 16 ));
102 if( VAL2STR_MODE_DEEP
== mode
)
104 buf
.append( "{" ); Reference
< XInterface
> r
= *static_cast<Reference
< XInterface
> const *>(pVal
);
105 Reference
< XServiceInfo
> serviceInfo( r
, UNO_QUERY
);
106 Reference
< XTypeProvider
> typeProvider(r
,UNO_QUERY
);
107 if( serviceInfo
.is() )
109 buf
.append("implementationName="
110 + serviceInfo
->getImplementationName()
111 + ", supportedServices={" );
112 Sequence
< OUString
> seq
= serviceInfo
->getSupportedServiceNames();
113 for( int i
= 0 ; i
< seq
.getLength() ; i
++ )
115 buf
.append( seq
[i
] );
116 if( i
+1 != seq
.getLength() )
122 if( typeProvider
.is() )
124 buf
.append(", supportedInterfaces={" );
125 Sequence
< Type
> seq (typeProvider
->getTypes());
126 for( int i
= 0 ; i
< seq
.getLength() ; i
++ )
128 buf
.append(seq
[i
].getTypeName());
129 if( i
+1 != seq
.getLength() )
139 case typelib_TypeClass_STRUCT
:
140 case typelib_TypeClass_EXCEPTION
:
143 typelib_TypeDescription
* pTypeDescr
= nullptr;
144 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
145 assert( pTypeDescr
);
147 typelib_CompoundTypeDescription
* pCompType
= reinterpret_cast<typelib_CompoundTypeDescription
*>(pTypeDescr
);
148 sal_Int32 nDescr
= pCompType
->nMembers
;
150 if (pCompType
->pBaseTypeDescription
)
152 buf
.append( val2str( pVal
, pCompType
->pBaseTypeDescription
->aBase
.pWeakRef
, mode
) );
157 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompType
->ppTypeRefs
;
158 sal_Int32
* pMemberOffsets
= pCompType
->pMemberOffsets
;
159 rtl_uString
** ppMemberNames
= pCompType
->ppMemberNames
;
161 for ( sal_Int32 nPos
= 0; nPos
< nDescr
; ++nPos
)
163 buf
.append( OUString::unacquired(&ppMemberNames
[nPos
]) + " = " );
164 typelib_TypeDescription
* pMemberType
= nullptr;
165 TYPELIB_DANGER_GET( &pMemberType
, ppTypeRefs
[nPos
] );
166 buf
.append( val2str( static_cast<char const *>(pVal
) + pMemberOffsets
[nPos
], pMemberType
->pWeakRef
, mode
) );
167 TYPELIB_DANGER_RELEASE( pMemberType
);
168 if (nPos
< (nDescr
-1))
172 TYPELIB_DANGER_RELEASE( pTypeDescr
);
177 case typelib_TypeClass_SEQUENCE
:
179 typelib_TypeDescription
* pTypeDescr
= nullptr;
180 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
182 uno_Sequence
* pSequence
= *static_cast<uno_Sequence
* const *>(pVal
);
183 typelib_TypeDescription
* pElementTypeDescr
= nullptr;
184 TYPELIB_DANGER_GET( &pElementTypeDescr
, reinterpret_cast<typelib_IndirectTypeDescription
*>(pTypeDescr
)->pType
);
186 sal_Int32 nElementSize
= pElementTypeDescr
->nSize
;
187 sal_Int32 nElements
= pSequence
->nElements
;
192 char * pElements
= pSequence
->elements
;
193 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
195 buf
.append( val2str( pElements
+ (nElementSize
* nPos
), pElementTypeDescr
->pWeakRef
, mode
) );
196 if (nPos
< (nElements
-1))
205 TYPELIB_DANGER_RELEASE( pElementTypeDescr
);
206 TYPELIB_DANGER_RELEASE( pTypeDescr
);
209 case typelib_TypeClass_ANY
:
211 + val2str( static_cast<uno_Any
const *>(pVal
)->pData
,
212 static_cast<uno_Any
const *>(pVal
)->pType
,
216 case typelib_TypeClass_TYPE
:
217 buf
.append( (*static_cast<typelib_TypeDescriptionReference
* const *>(pVal
))->pTypeName
);
219 case typelib_TypeClass_STRING
:
221 OUString::unacquired(&*static_cast<rtl_uString
* const *>(pVal
)) +
224 case typelib_TypeClass_ENUM
:
226 typelib_TypeDescription
* pTypeDescr
= nullptr;
227 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
229 sal_Int32
* pValues
= reinterpret_cast<typelib_EnumTypeDescription
*>(pTypeDescr
)->pEnumValues
;
230 sal_Int32 nPos
= reinterpret_cast<typelib_EnumTypeDescription
*>(pTypeDescr
)->nEnumValues
;
233 if (pValues
[nPos
] == *static_cast<int const *>(pVal
))
237 buf
.append( reinterpret_cast<typelib_EnumTypeDescription
*>(pTypeDescr
)->ppEnumNames
[nPos
] );
241 TYPELIB_DANGER_RELEASE( pTypeDescr
);
244 case typelib_TypeClass_BOOLEAN
:
245 if (*static_cast<sal_Bool
const *>(pVal
))
246 buf
.append( "true" );
248 buf
.append( "false" );
250 case typelib_TypeClass_CHAR
:
252 + OUStringChar(*static_cast<sal_Unicode
const *>(pVal
) )
255 case typelib_TypeClass_FLOAT
:
256 buf
.append( *static_cast<float const *>(pVal
) );
258 case typelib_TypeClass_DOUBLE
:
259 buf
.append( *static_cast<double const *>(pVal
) );
261 case typelib_TypeClass_BYTE
:
263 OUString::number( static_cast<sal_Int32
>(*static_cast<sal_Int8
const *>(pVal
)), 16 ));
265 case typelib_TypeClass_SHORT
:
267 OUString::number( static_cast<sal_Int32
>(*static_cast<sal_Int16
const *>(pVal
)), 16 ));
269 case typelib_TypeClass_UNSIGNED_SHORT
:
271 OUString::number( static_cast<sal_Int32
>(*static_cast<sal_uInt16
const *>(pVal
)), 16 ));
273 case typelib_TypeClass_LONG
:
275 OUString::number( *static_cast<sal_Int32
const *>(pVal
), 16 ));
277 case typelib_TypeClass_UNSIGNED_LONG
:
279 OUString::number( static_cast<sal_Int64
>(*static_cast<sal_uInt32
const *>(pVal
)), 16 ));
281 case typelib_TypeClass_HYPER
:
282 case typelib_TypeClass_UNSIGNED_HYPER
:
284 #if defined(__GNUC__) && defined(SPARC)
285 // I guess this really should check if there are strict alignment
286 // requirements, not just "GCC on SPARC".
289 *(sal_Int32
*)&aVal
= *(sal_Int32
*)pVal
;
290 *((sal_Int32
*)&aVal
+1)= *((sal_Int32
*)pVal
+1);
291 buf
.append( aVal
, 16 );
294 buf
.append( *static_cast<sal_Int64
const *>(pVal
), 16 );
298 case typelib_TypeClass_VOID
:
299 case typelib_TypeClass_UNKNOWN
:
300 case typelib_TypeClass_SERVICE
:
301 case typelib_TypeClass_MODULE
:
306 return buf
.makeStringAndClear();
309 static sal_Int32
lcl_PyNumber_AsSal_Int32( PyObject
*pObj
)
311 // Check object is an index
312 PyRef
rIndex( PyNumber_Index( pObj
), SAL_NO_ACQUIRE
);
316 // Convert Python number to platform long, then check actual value against
317 // bounds of sal_Int32
319 long nResult
= PyLong_AsLongAndOverflow( pObj
, &nOverflow
);
320 if ( nOverflow
|| nResult
> SAL_MAX_INT32
|| nResult
< SAL_MIN_INT32
) {
321 PyErr_SetString( PyExc_IndexError
, "Python int too large to convert to UNO long" );
328 static int lcl_PySlice_GetIndicesEx( PyObject
*pObject
, sal_Int32 nLen
, sal_Int32
*nStart
, sal_Int32
*nStop
, sal_Int32
*nStep
, sal_Int32
*nSliceLength
)
330 Py_ssize_t nStart_ssize
, nStop_ssize
, nStep_ssize
, nSliceLength_ssize
;
332 int nResult
= PySlice_GetIndicesEx(pObject
,
333 nLen
, &nStart_ssize
, &nStop_ssize
, &nStep_ssize
, &nSliceLength_ssize
);
337 if ( nStart_ssize
> SAL_MAX_INT32
|| nStart_ssize
< SAL_MIN_INT32
338 || nStop_ssize
> SAL_MAX_INT32
|| nStop_ssize
< SAL_MIN_INT32
339 || nStep_ssize
> SAL_MAX_INT32
|| nStep_ssize
< SAL_MIN_INT32
340 || nSliceLength_ssize
> SAL_MAX_INT32
|| nSliceLength_ssize
< SAL_MIN_INT32
)
342 PyErr_SetString( PyExc_IndexError
, "Python int too large to convert to UNO long" );
346 *nStart
= static_cast<sal_Int32
>(nStart_ssize
);
347 *nStop
= static_cast<sal_Int32
>(nStop_ssize
);
348 *nStep
= static_cast<sal_Int32
>(nStep_ssize
);
349 *nSliceLength
= static_cast<sal_Int32
>(nSliceLength_ssize
);
353 static bool lcl_hasInterfaceByName( Any
const &object
, OUString
const & interfaceName
)
355 Reference
< XInterface
> xInterface( object
, UNO_QUERY
);
356 TypeDescription
typeDesc( interfaceName
);
357 Any aInterface
= xInterface
->queryInterface( typeDesc
.get()->pWeakRef
);
359 return aInterface
.hasValue();
362 static PyObject
*PyUNO_repr( PyObject
* self
)
364 return PyUNO_str( self
);
367 static Py_hash_t
PyUNO_hash( PyObject
*self
)
370 PyUNO
*me
= reinterpret_cast<PyUNO
*>(self
);
372 // Py_hash_t is not necessarily the same size as a pointer, but this is not
373 // important for hashing - it just has to return the same value each time
374 return sal::static_int_cast
< Py_hash_t
>( reinterpret_cast< sal_IntPtr
> (
375 *static_cast<void * const *>(me
->members
->wrappedObject
.getValue()) ) );
379 PyObject
*PyUNO_invoke( PyObject
*object
, const char *name
, PyObject
*args
)
386 PyRef paras
,callable
;
387 if( PyObject_IsInstance( object
, getPyUnoClass().get() ) )
389 PyUNO
* me
= reinterpret_cast<PyUNO
*>(object
);
390 OUString attrName
= OUString::createFromAscii(name
);
391 if (! me
->members
->xInvocation
->hasMethod (attrName
))
393 throw RuntimeException( "Attribute " + attrName
+ " unknown" );
395 callable
= PyUNO_callable_new (
396 me
->members
->xInvocation
,
403 // clean the tuple from uno.Any !
404 int size
= PyTuple_Size( args
);
405 { // for CC, keeping ref-count of tuple being 1
406 paras
= PyRef(PyTuple_New( size
), SAL_NO_ACQUIRE
);
408 for( int i
= 0 ; i
< size
;i
++ )
410 PyObject
* element
= PyTuple_GetItem( args
, i
);
411 if( PyObject_IsInstance( element
, getAnyClass( runtime
).get() ) )
413 element
= PyObject_GetAttrString(
418 Py_XINCREF( element
);
420 PyTuple_SetItem( paras
.get(), i
, element
);
422 callable
= PyRef( PyObject_GetAttrString( object
, name
), SAL_NO_ACQUIRE
);
426 ret
= PyRef( PyObject_CallObject( callable
.get(), paras
.get() ), SAL_NO_ACQUIRE
);
428 catch (const css::lang::IllegalArgumentException
&e
)
430 raisePyExceptionWithAny( css::uno::Any( e
) );
432 catch (const css::script::CannotConvertException
&e
)
434 raisePyExceptionWithAny( css::uno::Any( e
) );
436 catch (const css::uno::RuntimeException
&e
)
438 raisePyExceptionWithAny( css::uno::Any( e
) );
440 catch (const css::uno::Exception
&e
)
442 raisePyExceptionWithAny( css::uno::Any( e
) );
445 return ret
.getAcquired();
448 PyObject
*PyUNO_str( PyObject
* self
)
450 PyUNO
*me
= reinterpret_cast<PyUNO
*>(self
);
455 PyThreadDetach antiguard
;
457 OUString s
= val2str( me
->members
->wrappedObject
.getValue(),
458 me
->members
->wrappedObject
.getValueType().getTypeLibType() );
459 buf
= "pyuno object " + OUStringToOString(s
,RTL_TEXTENCODING_ASCII_US
);
462 return PyUnicode_FromString( buf
.getStr() );
465 static PyObject
* PyUNO_dir (PyObject
* self
)
467 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
469 PyObject
* member_list
= nullptr;
470 Sequence
<OUString
> oo_member_list
;
474 oo_member_list
= me
->members
->xInvocation
->getMemberNames ();
475 member_list
= PyList_New (oo_member_list
.getLength ());
476 for (int i
= 0; i
< oo_member_list
.getLength (); i
++)
478 // setitem steals a reference
479 PyList_SetItem (member_list
, i
, ustring2PyString(oo_member_list
[i
]).getAcquired() );
482 catch( const RuntimeException
&e
)
484 raisePyExceptionWithAny( Any(e
) );
490 static sal_Int32
lcl_detach_getLength( PyUNO
const *me
)
492 PyThreadDetach antiguard
;
494 // If both XIndexContainer and XNameContainer are implemented, it is
495 // assumed that getCount() gives the same result as the number of names
496 // returned by getElementNames(), or the user may be surprised.
498 // For XIndexContainer
499 Reference
< XIndexAccess
> xIndexAccess( me
->members
->xInvocation
, UNO_QUERY
);
500 if ( xIndexAccess
.is() )
502 return xIndexAccess
->getCount();
505 // For XNameContainer
506 // Not terribly efficient - get the count of all the names
507 Reference
< XNameAccess
> xNameAccess( me
->members
->xInvocation
, UNO_QUERY
);
508 if ( xNameAccess
.is() )
510 return xNameAccess
->getElementNames().getLength();
516 static int PyUNO_bool( PyObject
* self
)
518 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
522 int nLen
= lcl_detach_getLength( me
);
524 return nLen
== 0 ? 0 : 1;
526 // Anything which doesn't have members is a scalar object and therefore true
529 catch( const css::uno::RuntimeException
&e
)
531 raisePyExceptionWithAny( css::uno::Any( e
) );
537 static Py_ssize_t
PyUNO_len( PyObject
* self
)
539 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
543 int nLen
= lcl_detach_getLength( me
);
547 PyErr_SetString( PyExc_TypeError
, "object has no len()" );
549 catch( const css::uno::RuntimeException
&e
)
551 raisePyExceptionWithAny( css::uno::Any( e
) );
557 static void lcl_getRowsColumns( PyUNO
const * me
, sal_Int32
& nRows
, sal_Int32
& nColumns
)
559 Sequence
<short> aOutParamIndex
;
560 Sequence
<Any
> aOutParam
;
561 Sequence
<Any
> aParams
;
562 Any aRet
= me
->members
->xInvocation
->invoke ( u
"getRows"_ustr
, aParams
, aOutParamIndex
, aOutParam
);
563 Reference
< XIndexAccess
> xIndexAccessRows( aRet
, UNO_QUERY
);
564 nRows
= xIndexAccessRows
->getCount();
565 aRet
= me
->members
->xInvocation
->invoke ( u
"getColumns"_ustr
, aParams
, aOutParamIndex
, aOutParam
);
566 Reference
< XIndexAccess
> xIndexAccessCols( aRet
, UNO_QUERY
);
567 nColumns
= xIndexAccessCols
->getCount();
570 static PyRef
lcl_indexToSlice( const PyRef
& rIndex
)
572 Py_ssize_t nIndex
= PyNumber_AsSsize_t( rIndex
.get(), PyExc_IndexError
);
573 if (nIndex
== -1 && PyErr_Occurred())
575 PyRef
rStart( PyLong_FromSsize_t( nIndex
), SAL_NO_ACQUIRE
);
576 PyRef
rStop( PyLong_FromSsize_t( nIndex
+1 ), SAL_NO_ACQUIRE
);
577 PyRef
rStep( PyLong_FromLong( 1 ), SAL_NO_ACQUIRE
);
578 PyRef
rSlice( PySlice_New( rStart
.get(), rStop
.get(), rStep
.get() ), SAL_NO_ACQUIRE
);
583 static PyObject
* lcl_getitem_XCellRange( PyUNO
const * me
, PyObject
* pKey
)
587 Sequence
<short> aOutParamIndex
;
588 Sequence
<Any
> aOutParam
;
589 Sequence
<Any
> aParams
;
592 // Single string key is sugar for getCellRangeByName()
593 if ( PyUnicode_Check( pKey
) ) {
595 aParams
= { Any(pyString2ustring( pKey
)) };
597 PyThreadDetach antiguard
;
598 aRet
= me
->members
->xInvocation
->invoke (
599 u
"getCellRangeByName"_ustr
, aParams
, aOutParamIndex
, aOutParam
);
601 PyRef rRet
= runtime
.any2PyObject ( aRet
);
602 return rRet
.getAcquired();
607 if ( PyIndex_Check( pKey
) )
609 // [0] is equivalent to [0,:]
611 rKey1
= PySlice_New( nullptr, nullptr, nullptr );
613 else if ( PyTuple_Check( pKey
) && (PyTuple_Size( pKey
) == 2) )
615 rKey0
= PyTuple_GetItem( pKey
, 0 );
616 rKey1
= PyTuple_GetItem( pKey
, 1 );
620 PyErr_SetString( PyExc_KeyError
, "invalid subscript" );
624 // If both keys are indices, return the corresponding cell
625 if ( PyIndex_Check( rKey0
.get() ) && PyIndex_Check( rKey1
.get() ))
627 sal_Int32 nKey0_s
= lcl_PyNumber_AsSal_Int32( rKey0
.get() );
628 sal_Int32 nKey1_s
= lcl_PyNumber_AsSal_Int32( rKey1
.get() );
630 if ( ((nKey0_s
== -1) || (nKey1_s
== -1)) && PyErr_Occurred() )
633 aParams
= { Any(nKey1_s
), Any(nKey0_s
) };
635 PyThreadDetach antiguard
;
636 aRet
= me
->members
->xInvocation
->invoke (
637 u
"getCellByPosition"_ustr
, aParams
, aOutParamIndex
, aOutParam
);
639 PyRef rRet
= runtime
.any2PyObject( aRet
);
640 return rRet
.getAcquired();
643 // If either argument is an index, coerce it to a slice
644 if ( PyIndex_Check( rKey0
.get() ) )
645 rKey0
= lcl_indexToSlice( rKey0
);
647 if ( PyIndex_Check( rKey1
.get() ) )
648 rKey1
= lcl_indexToSlice( rKey1
);
650 // If both arguments are slices, return the corresponding cell range
651 if ( PySlice_Check( rKey0
.get() ) && PySlice_Check( rKey1
.get() ) )
653 sal_Int32 nLen0
= SAL_MAX_INT32
, nLen1
= SAL_MAX_INT32
;
654 sal_Int32 nStart0
= 0, nStop0
= 0, nStep0
= 0, nSliceLength0
= 0;
655 sal_Int32 nStart1
= 0, nStop1
= 0, nStep1
= 0, nSliceLength1
= 0;
658 PyThreadDetach antiguard
;
660 if ( lcl_hasInterfaceByName( me
->members
->wrappedObject
, u
"com.sun.star.table.XColumnRowRange"_ustr
) )
662 lcl_getRowsColumns (me
, nLen0
, nLen1
);
666 int nSuccess1
= lcl_PySlice_GetIndicesEx( rKey0
.get(), nLen0
, &nStart0
, &nStop0
, &nStep0
, &nSliceLength0
);
667 int nSuccess2
= lcl_PySlice_GetIndicesEx( rKey1
.get(), nLen1
, &nStart1
, &nStop1
, &nStep1
, &nSliceLength1
);
668 if ( ((nSuccess1
== -1) || (nSuccess2
== -1)) && PyErr_Occurred() )
671 if ( nSliceLength0
<= 0 || nSliceLength1
<= 0 )
673 PyErr_SetString( PyExc_KeyError
, "invalid number of rows or columns" );
677 if ( nStep0
== 1 && nStep1
== 1 )
679 aParams
= { Any(nStart1
), Any(nStart0
), Any(nStop1
- 1), Any(nStop0
- 1) };
681 PyThreadDetach antiguard
;
682 aRet
= me
->members
->xInvocation
->invoke (
683 u
"getCellRangeByPosition"_ustr
, aParams
, aOutParamIndex
, aOutParam
);
685 PyRef rRet
= runtime
.any2PyObject( aRet
);
686 return rRet
.getAcquired();
689 PyErr_SetString( PyExc_KeyError
, "step != 1 not supported" );
693 PyErr_SetString( PyExc_KeyError
, "invalid subscript" );
697 static PyObject
* lcl_getitem_index( PyUNO
const *me
, PyObject
*pKey
, Runtime
const & runtime
)
702 nIndex
= lcl_PyNumber_AsSal_Int32( pKey
);
703 if (nIndex
== -1 && PyErr_Occurred())
707 PyThreadDetach antiguard
;
709 Reference
< XIndexAccess
> xIndexAccess( me
->members
->xInvocation
, UNO_QUERY
);
710 if ( xIndexAccess
.is() )
713 nIndex
+= xIndexAccess
->getCount();
714 aRet
= xIndexAccess
->getByIndex( nIndex
);
717 if ( aRet
.hasValue() )
719 PyRef
rRet ( runtime
.any2PyObject( aRet
) );
720 return rRet
.getAcquired();
726 static PyObject
* lcl_getitem_slice( PyUNO
const *me
, PyObject
*pKey
)
730 Reference
< XIndexAccess
> xIndexAccess
;
734 PyThreadDetach antiguard
;
736 xIndexAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
737 if ( xIndexAccess
.is() )
738 nLen
= xIndexAccess
->getCount();
744 sal_Int32 nStart
= 0, nStop
= 0, nStep
= 0, nSliceLength
= 0;
745 int nSuccess
= lcl_PySlice_GetIndicesEx(pKey
, nLen
, &nStart
, &nStop
, &nStep
, &nSliceLength
);
746 if ( nSuccess
== -1 && PyErr_Occurred() )
749 PyRef
rTuple( PyTuple_New( nSliceLength
), SAL_NO_ACQUIRE
, NOT_NULL
);
751 for ( nCur
= nStart
, i
= 0; i
< nSliceLength
; nCur
+= nStep
, i
++ )
756 PyThreadDetach antiguard
;
758 aRet
= xIndexAccess
->getByIndex( nCur
);
760 PyRef rRet
= runtime
.any2PyObject( aRet
);
761 PyTuple_SetItem( rTuple
.get(), i
, rRet
.getAcquired() );
764 return rTuple
.getAcquired();
767 static PyObject
* lcl_getitem_string( PyUNO
const *me
, PyObject
*pKey
, Runtime
const & runtime
)
769 OUString sKey
= pyString2ustring( pKey
);
773 PyThreadDetach antiguard
;
775 Reference
< XNameAccess
> xNameAccess( me
->members
->xInvocation
, UNO_QUERY
);
776 if ( xNameAccess
.is() )
778 aRet
= xNameAccess
->getByName( sKey
);
781 if ( aRet
.hasValue() )
783 PyRef rRet
= runtime
.any2PyObject( aRet
);
784 return rRet
.getAcquired();
790 static PyObject
* PyUNO_getitem( PyObject
*self
, PyObject
*pKey
)
792 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
797 // XIndexAccess access by index
798 if ( PyIndex_Check( pKey
) )
800 PyObject
* pRet
= lcl_getitem_index( me
, pKey
, runtime
);
801 if ( pRet
!= nullptr || PyErr_Occurred() )
805 // XIndexAccess access by slice
806 if ( PySlice_Check( pKey
) )
808 PyObject
* pRet
= lcl_getitem_slice( me
, pKey
);
809 if ( pRet
!= nullptr || PyErr_Occurred() )
813 // XNameAccess access by key
814 if ( PyUnicode_Check( pKey
) )
816 PyObject
* pRet
= lcl_getitem_string( me
, pKey
, runtime
);
817 if ( pRet
!= nullptr )
821 // XCellRange/XColumnRowRange specialisation
822 // Uses reflection as we can't have a hard dependency on XCellRange here
823 bool hasXCellRange
= false;
826 PyThreadDetach antiguard
;
828 hasXCellRange
= lcl_hasInterfaceByName( me
->members
->wrappedObject
, u
"com.sun.star.table.XCellRange"_ustr
);
832 return lcl_getitem_XCellRange( me
, pKey
);
836 // If the object is an XIndexAccess and/or XNameAccess, but the
837 // key passed wasn't suitable, give a TypeError which specifically
839 Reference
< XIndexAccess
> xIndexAccess( me
->members
->xInvocation
, UNO_QUERY
);
840 Reference
< XNameAccess
> xNameAccess( me
->members
->xInvocation
, UNO_QUERY
);
841 if ( xIndexAccess
.is() || xNameAccess
.is() )
843 PyErr_SetString( PyExc_TypeError
, "subscription with invalid type" );
847 PyErr_SetString( PyExc_TypeError
, "object is not subscriptable" );
849 catch( const css::lang::IndexOutOfBoundsException
& )
851 PyErr_SetString( PyExc_IndexError
, "index out of range" );
853 catch( const css::container::NoSuchElementException
& )
855 PyErr_SetString( PyExc_KeyError
, "key not found" );
857 catch( const css::script::CannotConvertException
&e
)
859 raisePyExceptionWithAny( css::uno::Any( e
) );
861 catch( const css::lang::IllegalArgumentException
&e
)
863 raisePyExceptionWithAny( css::uno::Any( e
) );
865 catch( const css::lang::WrappedTargetException
&e
)
867 raisePyExceptionWithAny( css::uno::Any( e
) );
869 catch( const css::uno::RuntimeException
&e
)
871 raisePyExceptionWithAny( css::uno::Any( e
) );
877 static int lcl_setitem_index( PyUNO
const *me
, PyObject
*pKey
, PyObject
*pValue
)
881 Reference
< XIndexContainer
> xIndexContainer
;
882 Reference
< XIndexReplace
> xIndexReplace
;
883 sal_Int32 nIndex
= lcl_PyNumber_AsSal_Int32( pKey
);
884 if ( nIndex
== -1 && PyErr_Occurred() )
887 bool isTuple
= false;
890 if ( pValue
!= nullptr )
892 isTuple
= PyTuple_Check( pValue
);
896 aValue
= runtime
.pyObject2Any( pValue
);
898 catch ( const css::uno::RuntimeException
& )
900 // TODO pyObject2Any can't convert e.g. dicts but only throws
901 // RuntimeException on failure. Fixing this will require an audit of
902 // all the rest of PyUNO
903 throw css::script::CannotConvertException();
908 PyThreadDetach antiguard
;
910 xIndexContainer
.set( me
->members
->xInvocation
, UNO_QUERY
);
911 if ( xIndexContainer
.is() )
912 xIndexReplace
= xIndexContainer
;
914 xIndexReplace
.set( me
->members
->xInvocation
, UNO_QUERY
);
916 if ( xIndexReplace
.is() && nIndex
< 0 )
917 nIndex
+= xIndexReplace
->getCount();
919 // XIndexReplace replace by index
920 if ( (pValue
!= nullptr) && xIndexReplace
.is() )
924 // Apply type specialisation to ensure the correct kind of sequence is passed
925 Type aType
= xIndexReplace
->getElementType();
926 aValue
= runtime
.getImpl()->cargo
->xTypeConverter
->convertTo( aValue
, aType
);
929 xIndexReplace
->replaceByIndex( nIndex
, aValue
);
933 // XIndexContainer remove by index
934 if ( (pValue
== nullptr) && xIndexContainer
.is() )
936 xIndexContainer
->removeByIndex( nIndex
);
941 PyErr_SetString( PyExc_TypeError
, "cannot assign to object" );
945 static int lcl_setitem_slice( PyUNO
const *me
, PyObject
*pKey
, PyObject
*pValue
)
947 // XIndexContainer insert/remove/replace by slice
950 Reference
< XIndexReplace
> xIndexReplace
;
951 Reference
< XIndexContainer
> xIndexContainer
;
955 PyThreadDetach antiguard
;
957 xIndexContainer
.set( me
->members
->xInvocation
, UNO_QUERY
);
958 if ( xIndexContainer
.is() )
959 xIndexReplace
= xIndexContainer
;
961 xIndexReplace
.set( me
->members
->xInvocation
, UNO_QUERY
);
963 if ( xIndexReplace
.is() )
964 nLen
= xIndexReplace
->getCount();
967 if ( xIndexReplace
.is() )
969 sal_Int32 nStart
= 0, nStop
= 0, nStep
= 0, nSliceLength
= 0;
970 int nSuccess
= lcl_PySlice_GetIndicesEx( pKey
, nLen
, &nStart
, &nStop
, &nStep
, &nSliceLength
);
971 if ( (nSuccess
== -1) && PyErr_Occurred() )
974 if ( pValue
== nullptr )
976 pValue
= PyTuple_New( 0 );
979 if ( !PyTuple_Check (pValue
) )
981 PyErr_SetString( PyExc_TypeError
, "value is not a tuple" );
985 Py_ssize_t nTupleLength_ssize
= PyTuple_Size( pValue
);
986 if ( nTupleLength_ssize
> SAL_MAX_INT32
)
988 PyErr_SetString( PyExc_ValueError
, "tuple too large" );
991 sal_Int32 nTupleLength
= static_cast<sal_Int32
>(nTupleLength_ssize
);
993 if ( (nTupleLength
!= nSliceLength
) && (nStep
!= 1) )
995 PyErr_SetString( PyExc_ValueError
, "number of items assigned must be equal" );
999 if ( (nTupleLength
!= nSliceLength
) && !xIndexContainer
.is() )
1001 PyErr_SetString( PyExc_ValueError
, "cannot change length" );
1006 sal_Int32 nMax
= ::std::max( nSliceLength
, nTupleLength
);
1007 for ( nCur
= nStart
, i
= 0; i
< nMax
; nCur
+= nStep
, i
++ )
1009 if ( i
< nTupleLength
)
1011 PyRef rItem
= PyTuple_GetItem( pValue
, i
);
1012 bool isTuple
= PyTuple_Check( rItem
.get() );
1017 aItem
= runtime
.pyObject2Any( rItem
.get() );
1019 catch ( const css::uno::RuntimeException
& )
1021 // TODO pyObject2Any can't convert e.g. dicts but only throws
1022 // RuntimeException on failure. Fixing this will require an audit of
1023 // all the rest of PyUNO
1024 throw css::script::CannotConvertException();
1028 PyThreadDetach antiguard
;
1032 // Apply type specialisation to ensure the correct kind of sequence is passed
1033 Type aType
= xIndexReplace
->getElementType();
1034 aItem
= runtime
.getImpl()->cargo
->xTypeConverter
->convertTo( aItem
, aType
);
1037 if ( i
< nSliceLength
)
1039 xIndexReplace
->replaceByIndex( nCur
, aItem
);
1043 xIndexContainer
->insertByIndex( nCur
, aItem
);
1049 PyThreadDetach antiguard
;
1051 xIndexContainer
->removeByIndex( nCur
);
1059 PyErr_SetString( PyExc_TypeError
, "cannot assign to object" );
1063 static int lcl_setitem_string( PyUNO
const *me
, PyObject
*pKey
, PyObject
*pValue
)
1067 OUString sKey
= pyString2ustring( pKey
);
1068 bool isTuple
= false;
1071 if ( pValue
!= nullptr)
1073 isTuple
= PyTuple_Check( pValue
);
1076 aValue
= runtime
.pyObject2Any( pValue
);
1078 catch( const css::uno::RuntimeException
& )
1080 // TODO pyObject2Any can't convert e.g. dicts but only throws
1081 // RuntimeException on failure. Fixing this will require an audit of
1082 // all the rest of PyUNO
1083 throw css::script::CannotConvertException();
1088 PyThreadDetach antiguard
;
1090 Reference
< XNameContainer
> xNameContainer( me
->members
->xInvocation
, UNO_QUERY
);
1091 Reference
< XNameReplace
> xNameReplace
;
1092 if ( xNameContainer
.is() )
1093 xNameReplace
= xNameContainer
;
1095 xNameReplace
.set( me
->members
->xInvocation
, UNO_QUERY
);
1097 if ( xNameReplace
.is() )
1099 if ( isTuple
&& aValue
.hasValue() )
1101 // Apply type specialisation to ensure the correct kind of sequence is passed
1102 Type aType
= xNameReplace
->getElementType();
1103 aValue
= runtime
.getImpl()->cargo
->xTypeConverter
->convertTo( aValue
, aType
);
1106 if ( aValue
.hasValue() )
1108 if ( xNameContainer
.is() )
1111 xNameContainer
->insertByName( sKey
, aValue
);
1114 catch( const css::container::ElementExistException
& )
1116 // Fall through, try replace instead
1120 xNameReplace
->replaceByName( sKey
, aValue
);
1123 else if ( xNameContainer
.is() )
1125 xNameContainer
->removeByName( sKey
);
1131 PyErr_SetString( PyExc_TypeError
, "cannot assign to object" );
1135 static int PyUNO_setitem( PyObject
*self
, PyObject
*pKey
, PyObject
*pValue
)
1137 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
1141 if ( PyIndex_Check( pKey
) )
1143 return lcl_setitem_index( me
, pKey
, pValue
);
1145 else if ( PySlice_Check( pKey
) )
1147 return lcl_setitem_slice( me
, pKey
, pValue
);
1149 else if ( PyUnicode_Check( pKey
) )
1151 return lcl_setitem_string( me
, pKey
, pValue
);
1154 PyErr_SetString( PyExc_TypeError
, "list index has invalid type" );
1156 catch( const css::lang::IndexOutOfBoundsException
& )
1158 PyErr_SetString( PyExc_IndexError
, "list index out of range" );
1160 catch( const css::container::NoSuchElementException
& )
1162 PyErr_SetString( PyExc_KeyError
, "key not found" );
1164 catch( const css::lang::IllegalArgumentException
& )
1166 PyErr_SetString( PyExc_TypeError
, "value has invalid type" );
1168 catch( const css::script::CannotConvertException
& )
1170 PyErr_SetString( PyExc_TypeError
, "value has invalid type" );
1172 catch( const css::container::ElementExistException
&e
)
1174 raisePyExceptionWithAny( css::uno::Any( e
) );
1176 catch( const css::lang::WrappedTargetException
&e
)
1178 raisePyExceptionWithAny( css::uno::Any( e
) );
1180 catch( const css::uno::RuntimeException
&e
)
1182 raisePyExceptionWithAny( css::uno::Any( e
) );
1188 static PyObject
* PyUNO_iter( PyObject
*self
)
1190 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
1194 Reference
< XEnumerationAccess
> xEnumerationAccess
;
1195 Reference
< XEnumeration
> xEnumeration
;
1196 Reference
< XIndexAccess
> xIndexAccess
;
1197 Reference
< XNameAccess
> xNameAccess
;
1200 PyThreadDetach antiguard
;
1202 xEnumerationAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1203 if ( xEnumerationAccess
.is() )
1204 xEnumeration
= xEnumerationAccess
->createEnumeration();
1206 xEnumeration
.set( me
->members
->wrappedObject
, UNO_QUERY
);
1208 if ( !xEnumeration
.is() )
1209 xIndexAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1211 if ( !xIndexAccess
.is() )
1212 xNameAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1215 // XEnumerationAccess iterator
1216 // XEnumeration iterator
1217 if (xEnumeration
.is())
1219 return PyUNO_iterator_new( xEnumeration
);
1222 // XIndexAccess iterator
1223 if ( xIndexAccess
.is() )
1225 // We'd like to be able to use PySeqIter_New() here, but we're not
1226 // allowed to because we also implement the mapping protocol
1227 return PyUNO_list_iterator_new( xIndexAccess
);
1230 // XNameAccess iterator
1231 if (xNameAccess
.is())
1233 // There's no generic mapping iterator, but we can cobble our own
1234 // together using PySeqIter_New()
1239 PyThreadDetach antiguard
;
1240 aRet
<<= xNameAccess
->getElementNames();
1242 PyRef rNames
= runtime
.any2PyObject( aRet
);
1243 return PySeqIter_New( rNames
.getAcquired() );
1246 PyErr_SetString ( PyExc_TypeError
, "object is not iterable" );
1248 catch( css::script::CannotConvertException
&e
)
1250 raisePyExceptionWithAny( css::uno::Any( e
) );
1252 catch( css::lang::IllegalArgumentException
&e
)
1254 raisePyExceptionWithAny( css::uno::Any( e
) );
1256 catch( const css::uno::RuntimeException
&e
)
1258 raisePyExceptionWithAny( css::uno::Any( e
) );
1264 static int PyUNO_contains( PyObject
*self
, PyObject
*pKey
)
1266 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
1275 aValue
= runtime
.pyObject2Any( pKey
);
1277 catch( const css::uno::RuntimeException
& )
1279 // TODO pyObject2Any can't convert e.g. dicts but only throws
1280 // RuntimeException on failure. Fixing this will require an audit of
1281 // all the rest of PyUNO
1282 throw css::script::CannotConvertException();
1285 // XNameAccess is tried first, because checking key presence is much more
1286 // useful for objects which implement both XIndexAccess and XNameAccess
1289 if ( PyUnicode_Check( pKey
) )
1293 Reference
< XNameAccess
> xNameAccess
;
1296 PyThreadDetach antiguard
;
1298 xNameAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1299 if ( xNameAccess
.is() )
1301 bool hasKey
= xNameAccess
->hasByName( sKey
);
1302 return hasKey
? 1 : 0;
1307 // For any other type of PyUNO iterable: Ugly iterative search by
1308 // content (XIndexAccess, XEnumerationAccess, XEnumeration)
1309 PyRef
rIterator( PyUNO_iter( self
), SAL_NO_ACQUIRE
);
1310 if ( rIterator
.is() )
1312 while ( PyObject
* pItem
= PyIter_Next( rIterator
.get() ) )
1314 PyRef
rItem( pItem
, SAL_NO_ACQUIRE
);
1315 if ( PyObject_RichCompareBool( pKey
, rItem
.get(), Py_EQ
) == 1 )
1323 PyErr_SetString( PyExc_TypeError
, "argument is not iterable" );
1325 catch( const css::script::CannotConvertException
& )
1327 PyErr_SetString( PyExc_TypeError
, "invalid type passed as left argument to 'in'" );
1329 catch( const css::container::NoSuchElementException
&e
)
1331 raisePyExceptionWithAny( css::uno::Any( e
) );
1333 catch( const css::lang::IndexOutOfBoundsException
&e
)
1335 raisePyExceptionWithAny( css::uno::Any( e
) );
1337 catch( const css::lang::IllegalArgumentException
&e
)
1339 raisePyExceptionWithAny( css::uno::Any( e
) );
1341 catch( const css::lang::WrappedTargetException
&e
)
1343 raisePyExceptionWithAny( css::uno::Any( e
) );
1345 catch( const css::uno::RuntimeException
&e
)
1347 raisePyExceptionWithAny( css::uno::Any( e
) );
1353 static PyObject
* PyUNO_getattr (PyObject
* self
, char* name
)
1360 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
1361 if (strcmp (name
, "__dict__") == 0)
1363 Py_INCREF (Py_TYPE(me
)->tp_dict
);
1364 return Py_TYPE(me
)->tp_dict
;
1366 if (strcmp (name
, "__class__") == 0)
1368 Py_INCREF (Py_None
);
1372 PyObject
*pRet
= PyObject_GenericGetAttr( self
, PyUnicode_FromString( name
) );
1377 OUString
attrName( OUString::createFromAscii( name
) );
1378 //We need to find out if it's a method...
1381 PyThreadDetach antiguard
;
1382 isMethod
= me
->members
->xInvocation
->hasMethod (attrName
);
1386 //Create a callable object to invoke this...
1387 PyRef ret
= PyUNO_callable_new (
1388 me
->members
->xInvocation
,
1390 Py_XINCREF( ret
.get() );
1399 PyThreadDetach antiguard
;
1400 isProperty
= me
->members
->xInvocation
->hasProperty ( attrName
);
1403 //Return the value of the property
1404 anyRet
= me
->members
->xInvocation
->getValue (attrName
);
1409 PyRef ret
= runtime
.any2PyObject(anyRet
);
1410 Py_XINCREF( ret
.get() );
1415 PyErr_SetString (PyExc_AttributeError
, name
);
1417 catch( const css::reflection::InvocationTargetException
& e
)
1419 raisePyExceptionWithAny( e
.TargetException
);
1421 catch( const css::beans::UnknownPropertyException
& e
)
1423 raisePyExceptionWithAny( Any(e
) );
1425 catch( const css::lang::IllegalArgumentException
&e
)
1427 raisePyExceptionWithAny( Any(e
) );
1429 catch( const css::script::CannotConvertException
&e
)
1431 raisePyExceptionWithAny( Any(e
) );
1433 catch( const RuntimeException
&e
)
1435 raisePyExceptionWithAny( Any(e
) );
1441 static int PyUNO_setattr (PyObject
* self
, char* name
, PyObject
* value
)
1445 me
= reinterpret_cast<PyUNO
*>(self
);
1449 Any val
= runtime
.pyObject2Any(value
, ACCEPT_UNO_ANY
);
1451 OUString
attrName( OUString::createFromAscii( name
) );
1453 PyThreadDetach antiguard
;
1454 if (me
->members
->xInvocation
->hasProperty (attrName
))
1456 me
->members
->xInvocation
->setValue (attrName
, val
);
1457 return 0; //Keep with Python's boolean system
1461 catch( const css::reflection::InvocationTargetException
& e
)
1463 raisePyExceptionWithAny( e
.TargetException
);
1466 catch( const css::beans::UnknownPropertyException
& e
)
1468 raisePyExceptionWithAny( Any(e
) );
1471 catch( const css::script::CannotConvertException
&e
)
1473 raisePyExceptionWithAny( Any(e
) );
1476 catch( const RuntimeException
& e
)
1478 raisePyExceptionWithAny( Any( e
) );
1481 PyErr_SetString (PyExc_AttributeError
, name
);
1482 return -1; //as above.
1485 static PyObject
* PyUNO_cmp( PyObject
*self
, PyObject
*that
, int op
)
1489 if(op
!= Py_EQ
&& op
!= Py_NE
)
1491 PyErr_SetString(PyExc_TypeError
, "only '==' and '!=' comparisons are defined");
1496 result
= (op
== Py_EQ
? Py_True
: Py_False
);
1503 if( PyObject_IsInstance( that
, getPyUnoClass().get() ) )
1506 PyUNO
*me
= reinterpret_cast< PyUNO
*> ( self
);
1507 PyUNO
*other
= reinterpret_cast< PyUNO
*> (that
);
1508 css::uno::TypeClass tcMe
= me
->members
->wrappedObject
.getValueTypeClass();
1509 css::uno::TypeClass tcOther
= other
->members
->wrappedObject
.getValueTypeClass();
1511 if( tcMe
== tcOther
)
1513 if( me
->members
->wrappedObject
== other
->members
->wrappedObject
)
1515 result
= (op
== Py_EQ
? Py_True
: Py_False
);
1522 catch( const css::uno::RuntimeException
& e
)
1524 raisePyExceptionWithAny( Any( e
) );
1527 result
= (op
== Py_EQ
? Py_False
: Py_True
);
1532 #if defined __GNUC__ && !defined __clang__
1533 #pragma GCC diagnostic push
1534 #pragma GCC diagnostic ignored "-Wcast-function-type"
1536 static PyMethodDef PyUNOMethods
[] =
1538 #if defined __clang__
1539 #if __has_warning("-Wcast-function-type-mismatch")
1540 #pragma clang diagnostic push
1541 #pragma clang diagnostic ignored "-Wcast-function-type-mismatch"
1544 {"__dir__", reinterpret_cast<PyCFunction
>(PyUNO_dir
), METH_NOARGS
, nullptr},
1545 #if defined __clang__
1546 #if __has_warning("-Wcast-function-type-mismatch")
1547 #pragma clang diagnostic pop
1550 {nullptr, nullptr, 0, nullptr}
1552 #if defined __GNUC__ && !defined __clang__
1553 #pragma GCC diagnostic pop
1556 static PyNumberMethods PyUNONumberMethods
[] =
1558 nullptr, /* nb_add */
1559 nullptr, /* nb_subtract */
1560 nullptr, /* nb_multiply */
1561 nullptr, /* nb_remainder */
1562 nullptr, /* nb_divmod */
1563 nullptr, /* nb_power */
1564 nullptr, /* nb_negative */
1565 nullptr, /* nb_positive */
1566 nullptr, /* nb_absolute */
1567 PyUNO_bool
, /* nb_bool */
1568 nullptr, /* nb_invert */
1569 nullptr, /* nb_lshift */
1570 nullptr, /* nb_rshift */
1571 nullptr, /* nb_and */
1572 nullptr, /* nb_xor */
1573 nullptr, /* nb_or */
1574 nullptr, /* nb_int */
1575 nullptr, /* nb_reserved */
1576 nullptr, /* nb_float */
1577 nullptr, /* nb_inplace_add */
1578 nullptr, /* nb_inplace_subtract */
1579 nullptr, /* nb_inplace_multiply */
1580 nullptr, /* nb_inplace_remainder */
1581 nullptr, /* nb_inplace_power */
1582 nullptr, /* nb_inplace_lshift */
1583 nullptr, /* nb_inplace_rshift */
1584 nullptr, /* nb_inplace_and */
1585 nullptr, /* nb_inplace_xor */
1586 nullptr, /* nb_inplace_or */
1588 nullptr, /* nb_floor_divide */
1589 nullptr, /* nb_true_divide */
1590 nullptr, /* nb_inplace_floor_divide */
1591 nullptr, /* nb_inplace_true_divide */
1593 nullptr, /* nb_index */
1594 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
1595 nullptr, /* nb_matrix_multiply */
1596 nullptr, /* nb_inplace_matrix_multiply */
1600 static PySequenceMethods PyUNOSequenceMethods
[] =
1602 nullptr, /* sq_length */
1603 nullptr, /* sq_concat */
1604 nullptr, /* sq_repeat */
1605 nullptr, /* sq_item */
1606 nullptr, /* sq_slice */
1607 nullptr, /* sq_ass_item */
1608 nullptr, /* sq_ass_slice */
1609 PyUNO_contains
, /* sq_contains */
1610 nullptr, /* sq_inplace_concat */
1611 nullptr /* sq_inplace_repeat */
1614 static PyMappingMethods PyUNOMappingMethods
[] =
1616 PyUNO_len
, /* mp_length */
1617 PyUNO_getitem
, /* mp_subscript */
1618 PyUNO_setitem
, /* mp_ass_subscript */
1621 static PyTypeObject PyUNOType
=
1623 PyVarObject_HEAD_INIT( &PyType_Type
, 0 )
1628 #if PY_VERSION_HEX >= 0x03080000
1629 0, // Py_ssize_t tp_vectorcall_offset
1631 nullptr, // printfunc tp_print
1635 /* this type does not exist in Python 3: (cmpfunc) */ nullptr,
1638 PyUNOSequenceMethods
,
1639 PyUNOMappingMethods
,
1646 Py_TPFLAGS_HAVE_ITER
| Py_TPFLAGS_HAVE_RICHCOMPARE
| Py_TPFLAGS_HAVE_SEQUENCE_IN
,
1674 #if PY_VERSION_HEX >= 0x03040000
1676 #if PY_VERSION_HEX >= 0x03080000
1677 , nullptr // vectorcallfunc tp_vectorcall
1678 #if PY_VERSION_HEX < 0x03090000
1679 #if defined __clang__
1680 #pragma clang diagnostic push
1681 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1683 , nullptr // tp_print
1684 #if defined __clang__
1685 #pragma clang diagnostic pop
1688 #if PY_VERSION_HEX >= 0x030C00A1
1695 int PyUNO_initType()
1697 return PyType_Ready(&PyUNOType
);
1700 PyRef
getPyUnoClass()
1702 return PyRef( reinterpret_cast< PyObject
* > ( &PyUNOType
) );
1706 const Any
&targetInterface
,
1707 const Reference
<XSingleServiceFactory
> &ssf
)
1709 Reference
<XInvocation2
> xInvocation
;
1712 PyThreadDetach antiguard
;
1714 ssf
->createInstanceWithArguments( Sequence
<Any
>( &targetInterface
, 1 ) ), css::uno::UNO_QUERY_THROW
);
1716 auto that
= comphelper::getFromUnoTunnel
<Adapter
>(
1717 xInvocation
->getIntrospection()->queryAdapter(cppu::UnoType
<XUnoTunnel
>::get()));
1719 return that
->getWrappedObject();
1721 if( !Py_IsInitialized() )
1722 throw RuntimeException();
1724 PyUNO
* self
= PyObject_New (PyUNO
, &PyUNOType
);
1725 if (self
== nullptr)
1726 return PyRef(); // == error
1727 self
->members
= new PyUNOInternals
;
1728 self
->members
->xInvocation
= std::move(xInvocation
);
1729 self
->members
->wrappedObject
= targetInterface
;
1730 return PyRef( reinterpret_cast<PyObject
*>(self
), SAL_NO_ACQUIRE
);
1736 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */