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::makeAny
;
52 using com::sun::star::uno::UNO_QUERY
;
53 using com::sun::star::uno::Type
;
54 using com::sun::star::uno::TypeClass
;
55 using com::sun::star::uno::TypeDescription
;
56 using com::sun::star::uno::RuntimeException
;
57 using com::sun::star::uno::Exception
;
58 using com::sun::star::lang::XSingleServiceFactory
;
59 using com::sun::star::lang::XServiceInfo
;
60 using com::sun::star::lang::XTypeProvider
;
61 using com::sun::star::lang::XUnoTunnel
;
62 using com::sun::star::script::XInvocation2
;
63 using com::sun::star::container::XEnumeration
;
64 using com::sun::star::container::XEnumerationAccess
;
65 using com::sun::star::container::XIndexAccess
;
66 using com::sun::star::container::XIndexContainer
;
67 using com::sun::star::container::XIndexReplace
;
68 using com::sun::star::container::XNameAccess
;
69 using com::sun::star::container::XNameContainer
;
70 using com::sun::star::container::XNameReplace
;
75 static PyObject
*PyUNO_str( PyObject
* self
);
77 static void PyUNO_del (PyObject
* self
)
79 PyUNO
* me
= reinterpret_cast< PyUNO
* > (self
);
81 PyThreadDetach antiguard
;
88 OUString
val2str( const void * pVal
, typelib_TypeDescriptionReference
* pTypeRef
, sal_Int32 mode
)
91 if (pTypeRef
->eTypeClass
== typelib_TypeClass_VOID
)
94 OUStringBuffer
buf( 64 );
95 buf
.append( "(" + OUString::unacquired(&pTypeRef
->pTypeName
) + ")" );
97 switch (pTypeRef
->eTypeClass
)
99 case typelib_TypeClass_INTERFACE
:
102 OUString::number( reinterpret_cast< sal_IntPtr
>(*static_cast<void * const *>(pVal
)), 16 ));
103 if( VAL2STR_MODE_DEEP
== mode
)
105 buf
.append( "{" ); Reference
< XInterface
> r
= *static_cast<Reference
< XInterface
> const *>(pVal
);
106 Reference
< XServiceInfo
> serviceInfo( r
, UNO_QUERY
);
107 Reference
< XTypeProvider
> typeProvider(r
,UNO_QUERY
);
108 if( serviceInfo
.is() )
110 buf
.append("implementationName=" );
111 buf
.append(serviceInfo
->getImplementationName() );
112 buf
.append(", supportedServices={" );
113 Sequence
< OUString
> seq
= serviceInfo
->getSupportedServiceNames();
114 for( int i
= 0 ; i
< seq
.getLength() ; i
++ )
116 buf
.append( seq
[i
] );
117 if( i
+1 != seq
.getLength() )
123 if( typeProvider
.is() )
125 buf
.append(", supportedInterfaces={" );
126 Sequence
< Type
> seq (typeProvider
->getTypes());
127 for( int i
= 0 ; i
< seq
.getLength() ; i
++ )
129 buf
.append(seq
[i
].getTypeName());
130 if( i
+1 != seq
.getLength() )
140 case typelib_TypeClass_STRUCT
:
141 case typelib_TypeClass_EXCEPTION
:
144 typelib_TypeDescription
* pTypeDescr
= nullptr;
145 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
146 assert( pTypeDescr
);
148 typelib_CompoundTypeDescription
* pCompType
= reinterpret_cast<typelib_CompoundTypeDescription
*>(pTypeDescr
);
149 sal_Int32 nDescr
= pCompType
->nMembers
;
151 if (pCompType
->pBaseTypeDescription
)
153 buf
.append( val2str( pVal
, pCompType
->pBaseTypeDescription
->aBase
.pWeakRef
, mode
) );
158 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompType
->ppTypeRefs
;
159 sal_Int32
* pMemberOffsets
= pCompType
->pMemberOffsets
;
160 rtl_uString
** ppMemberNames
= pCompType
->ppMemberNames
;
162 for ( sal_Int32 nPos
= 0; nPos
< nDescr
; ++nPos
)
164 buf
.append( OUString::unacquired(&ppMemberNames
[nPos
]) + " = " );
165 typelib_TypeDescription
* pMemberType
= nullptr;
166 TYPELIB_DANGER_GET( &pMemberType
, ppTypeRefs
[nPos
] );
167 buf
.append( val2str( static_cast<char const *>(pVal
) + pMemberOffsets
[nPos
], pMemberType
->pWeakRef
, mode
) );
168 TYPELIB_DANGER_RELEASE( pMemberType
);
169 if (nPos
< (nDescr
-1))
173 TYPELIB_DANGER_RELEASE( pTypeDescr
);
178 case typelib_TypeClass_SEQUENCE
:
180 typelib_TypeDescription
* pTypeDescr
= nullptr;
181 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
183 uno_Sequence
* pSequence
= *static_cast<uno_Sequence
* const *>(pVal
);
184 typelib_TypeDescription
* pElementTypeDescr
= nullptr;
185 TYPELIB_DANGER_GET( &pElementTypeDescr
, reinterpret_cast<typelib_IndirectTypeDescription
*>(pTypeDescr
)->pType
);
187 sal_Int32 nElementSize
= pElementTypeDescr
->nSize
;
188 sal_Int32 nElements
= pSequence
->nElements
;
193 char * pElements
= pSequence
->elements
;
194 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
196 buf
.append( val2str( pElements
+ (nElementSize
* nPos
), pElementTypeDescr
->pWeakRef
, mode
) );
197 if (nPos
< (nElements
-1))
206 TYPELIB_DANGER_RELEASE( pElementTypeDescr
);
207 TYPELIB_DANGER_RELEASE( pTypeDescr
);
210 case typelib_TypeClass_ANY
:
212 buf
.append( val2str( static_cast<uno_Any
const *>(pVal
)->pData
,
213 static_cast<uno_Any
const *>(pVal
)->pType
,
217 case typelib_TypeClass_TYPE
:
218 buf
.append( (*static_cast<typelib_TypeDescriptionReference
* const *>(pVal
))->pTypeName
);
220 case typelib_TypeClass_STRING
:
222 OUString::unacquired(&*static_cast<rtl_uString
* const *>(pVal
)) +
225 case typelib_TypeClass_ENUM
:
227 typelib_TypeDescription
* pTypeDescr
= nullptr;
228 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
230 sal_Int32
* pValues
= reinterpret_cast<typelib_EnumTypeDescription
*>(pTypeDescr
)->pEnumValues
;
231 sal_Int32 nPos
= reinterpret_cast<typelib_EnumTypeDescription
*>(pTypeDescr
)->nEnumValues
;
234 if (pValues
[nPos
] == *static_cast<int const *>(pVal
))
238 buf
.append( reinterpret_cast<typelib_EnumTypeDescription
*>(pTypeDescr
)->ppEnumNames
[nPos
] );
242 TYPELIB_DANGER_RELEASE( pTypeDescr
);
245 case typelib_TypeClass_BOOLEAN
:
246 if (*static_cast<sal_Bool
const *>(pVal
))
247 buf
.append( "true" );
249 buf
.append( "false" );
251 case typelib_TypeClass_CHAR
:
253 buf
.append( *static_cast<sal_Unicode
const *>(pVal
) );
256 case typelib_TypeClass_FLOAT
:
257 buf
.append( *static_cast<float const *>(pVal
) );
259 case typelib_TypeClass_DOUBLE
:
260 buf
.append( *static_cast<double const *>(pVal
) );
262 case typelib_TypeClass_BYTE
:
264 OUString::number( static_cast<sal_Int32
>(*static_cast<sal_Int8
const *>(pVal
)), 16 ));
266 case typelib_TypeClass_SHORT
:
268 OUString::number( static_cast<sal_Int32
>(*static_cast<sal_Int16
const *>(pVal
)), 16 ));
270 case typelib_TypeClass_UNSIGNED_SHORT
:
272 OUString::number( static_cast<sal_Int32
>(*static_cast<sal_uInt16
const *>(pVal
)), 16 ));
274 case typelib_TypeClass_LONG
:
276 OUString::number( *static_cast<sal_Int32
const *>(pVal
), 16 ));
278 case typelib_TypeClass_UNSIGNED_LONG
:
280 OUString::number( static_cast<sal_Int64
>(*static_cast<sal_uInt32
const *>(pVal
)), 16 ));
282 case typelib_TypeClass_HYPER
:
283 case typelib_TypeClass_UNSIGNED_HYPER
:
285 #if defined(__GNUC__) && defined(SPARC)
286 // I guess this really should check if there are strict alignment
287 // requirements, not just "GCC on SPARC".
290 *(sal_Int32
*)&aVal
= *(sal_Int32
*)pVal
;
291 *((sal_Int32
*)&aVal
+1)= *((sal_Int32
*)pVal
+1);
292 buf
.append( aVal
, 16 );
295 buf
.append( *static_cast<sal_Int64
const *>(pVal
), 16 );
299 case typelib_TypeClass_VOID
:
300 case typelib_TypeClass_UNKNOWN
:
301 case typelib_TypeClass_SERVICE
:
302 case typelib_TypeClass_MODULE
:
307 return buf
.makeStringAndClear();
310 static sal_Int32
lcl_PyNumber_AsSal_Int32( PyObject
*pObj
)
312 // Check object is an index
313 PyRef
rIndex( PyNumber_Index( pObj
), SAL_NO_ACQUIRE
);
317 // Convert Python number to platform long, then check actual value against
318 // bounds of sal_Int32
320 long nResult
= PyLong_AsLongAndOverflow( pObj
, &nOverflow
);
321 if ( nOverflow
|| nResult
> SAL_MAX_INT32
|| nResult
< SAL_MIN_INT32
) {
322 PyErr_SetString( PyExc_IndexError
, "Python int too large to convert to UNO long" );
329 static int lcl_PySlice_GetIndicesEx( PyObject
*pObject
, sal_Int32 nLen
, sal_Int32
*nStart
, sal_Int32
*nStop
, sal_Int32
*nStep
, sal_Int32
*nSliceLength
)
331 Py_ssize_t nStart_ssize
, nStop_ssize
, nStep_ssize
, nSliceLength_ssize
;
333 int nResult
= PySlice_GetIndicesEx(pObject
,
334 nLen
, &nStart_ssize
, &nStop_ssize
, &nStep_ssize
, &nSliceLength_ssize
);
338 if ( nStart_ssize
> SAL_MAX_INT32
|| nStart_ssize
< SAL_MIN_INT32
339 || nStop_ssize
> SAL_MAX_INT32
|| nStop_ssize
< SAL_MIN_INT32
340 || nStep_ssize
> SAL_MAX_INT32
|| nStep_ssize
< SAL_MIN_INT32
341 || nSliceLength_ssize
> SAL_MAX_INT32
|| nSliceLength_ssize
< SAL_MIN_INT32
)
343 PyErr_SetString( PyExc_IndexError
, "Python int too large to convert to UNO long" );
347 *nStart
= static_cast<sal_Int32
>(nStart_ssize
);
348 *nStop
= static_cast<sal_Int32
>(nStop_ssize
);
349 *nStep
= static_cast<sal_Int32
>(nStep_ssize
);
350 *nSliceLength
= static_cast<sal_Int32
>(nSliceLength_ssize
);
354 static bool lcl_hasInterfaceByName( Any
const &object
, OUString
const & interfaceName
)
356 Reference
< XInterface
> xInterface( object
, UNO_QUERY
);
357 TypeDescription
typeDesc( interfaceName
);
358 Any aInterface
= xInterface
->queryInterface( typeDesc
.get()->pWeakRef
);
360 return aInterface
.hasValue();
363 static PyObject
*PyUNO_repr( PyObject
* self
)
365 return PyUNO_str( self
);
368 static Py_hash_t
PyUNO_hash( PyObject
*self
)
371 PyUNO
*me
= reinterpret_cast<PyUNO
*>(self
);
373 // Py_hash_t is not necessarily the same size as a pointer, but this is not
374 // important for hashing - it just has to return the same value each time
375 return sal::static_int_cast
< Py_hash_t
>( reinterpret_cast< sal_IntPtr
> (
376 *static_cast<void * const *>(me
->members
->wrappedObject
.getValue()) ) );
380 PyObject
*PyUNO_invoke( PyObject
*object
, const char *name
, PyObject
*args
)
387 PyRef paras
,callable
;
388 if( PyObject_IsInstance( object
, getPyUnoClass().get() ) )
390 PyUNO
* me
= reinterpret_cast<PyUNO
*>(object
);
391 OUString attrName
= OUString::createFromAscii(name
);
392 if (! me
->members
->xInvocation
->hasMethod (attrName
))
394 throw RuntimeException( "Attribute " + attrName
+ " unknown" );
396 callable
= PyUNO_callable_new (
397 me
->members
->xInvocation
,
404 // clean the tuple from uno.Any !
405 int size
= PyTuple_Size( args
);
406 { // for CC, keeping ref-count of tuple being 1
407 paras
= PyRef(PyTuple_New( size
), SAL_NO_ACQUIRE
);
409 for( int i
= 0 ; i
< size
;i
++ )
411 PyObject
* element
= PyTuple_GetItem( args
, i
);
412 if( PyObject_IsInstance( element
, getAnyClass( runtime
).get() ) )
414 element
= PyObject_GetAttrString(
419 Py_XINCREF( element
);
421 PyTuple_SetItem( paras
.get(), i
, element
);
423 callable
= PyRef( PyObject_GetAttrString( object
, name
), SAL_NO_ACQUIRE
);
427 ret
= PyRef( PyObject_CallObject( callable
.get(), paras
.get() ), SAL_NO_ACQUIRE
);
429 catch (const css::lang::IllegalArgumentException
&e
)
431 raisePyExceptionWithAny( css::uno::makeAny( e
) );
433 catch (const css::script::CannotConvertException
&e
)
435 raisePyExceptionWithAny( css::uno::makeAny( e
) );
437 catch (const css::uno::RuntimeException
&e
)
439 raisePyExceptionWithAny( css::uno::makeAny( e
) );
441 catch (const css::uno::Exception
&e
)
443 raisePyExceptionWithAny( css::uno::makeAny( e
) );
446 return ret
.getAcquired();
449 PyObject
*PyUNO_str( PyObject
* self
)
451 PyUNO
*me
= reinterpret_cast<PyUNO
*>(self
);
456 PyThreadDetach antiguard
;
458 OUString s
= val2str( me
->members
->wrappedObject
.getValue(),
459 me
->members
->wrappedObject
.getValueType().getTypeLibType() );
460 buf
= "pyuno object " + OUStringToOString(s
,RTL_TEXTENCODING_ASCII_US
);
463 return PyUnicode_FromString( buf
.getStr() );
466 static PyObject
* PyUNO_dir (PyObject
* self
)
468 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
470 PyObject
* member_list
= nullptr;
471 Sequence
<OUString
> oo_member_list
;
475 oo_member_list
= me
->members
->xInvocation
->getMemberNames ();
476 member_list
= PyList_New (oo_member_list
.getLength ());
477 for (int i
= 0; i
< oo_member_list
.getLength (); i
++)
479 // setitem steals a reference
480 PyList_SetItem (member_list
, i
, ustring2PyString(oo_member_list
[i
]).getAcquired() );
483 catch( const RuntimeException
&e
)
485 raisePyExceptionWithAny( makeAny(e
) );
491 static sal_Int32
lcl_detach_getLength( PyUNO
const *me
)
493 PyThreadDetach antiguard
;
495 // If both XIndexContainer and XNameContainer are implemented, it is
496 // assumed that getCount() gives the same result as the number of names
497 // returned by getElementNames(), or the user may be surprised.
499 // For XIndexContainer
500 Reference
< XIndexAccess
> xIndexAccess( me
->members
->xInvocation
, UNO_QUERY
);
501 if ( xIndexAccess
.is() )
503 return xIndexAccess
->getCount();
506 // For XNameContainer
507 // Not terribly efficient - get the count of all the names
508 Reference
< XNameAccess
> xNameAccess( me
->members
->xInvocation
, UNO_QUERY
);
509 if ( xNameAccess
.is() )
511 return xNameAccess
->getElementNames().getLength();
517 static int PyUNO_bool( PyObject
* self
)
519 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
523 int nLen
= lcl_detach_getLength( me
);
525 return nLen
== 0 ? 0 : 1;
527 // Anything which doesn't have members is a scalar object and therefore true
530 catch( const css::uno::RuntimeException
&e
)
532 raisePyExceptionWithAny( css::uno::makeAny( e
) );
538 static Py_ssize_t
PyUNO_len( PyObject
* self
)
540 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
544 int nLen
= lcl_detach_getLength( me
);
548 PyErr_SetString( PyExc_TypeError
, "object has no len()" );
550 catch( const css::uno::RuntimeException
&e
)
552 raisePyExceptionWithAny( css::uno::makeAny( e
) );
558 static void lcl_getRowsColumns( PyUNO
const * me
, sal_Int32
& nRows
, sal_Int32
& nColumns
)
560 Sequence
<short> aOutParamIndex
;
561 Sequence
<Any
> aOutParam
;
562 Sequence
<Any
> aParams
;
563 Any aRet
= me
->members
->xInvocation
->invoke ( "getRows", aParams
, aOutParamIndex
, aOutParam
);
564 Reference
< XIndexAccess
> xIndexAccessRows( aRet
, UNO_QUERY
);
565 nRows
= xIndexAccessRows
->getCount();
566 aRet
= me
->members
->xInvocation
->invoke ( "getColumns", aParams
, aOutParamIndex
, aOutParam
);
567 Reference
< XIndexAccess
> xIndexAccessCols( aRet
, UNO_QUERY
);
568 nColumns
= xIndexAccessCols
->getCount();
571 static PyRef
lcl_indexToSlice( const PyRef
& rIndex
)
573 Py_ssize_t nIndex
= PyNumber_AsSsize_t( rIndex
.get(), PyExc_IndexError
);
574 if (nIndex
== -1 && PyErr_Occurred())
576 PyRef
rStart( PyLong_FromSsize_t( nIndex
), SAL_NO_ACQUIRE
);
577 PyRef
rStop( PyLong_FromSsize_t( nIndex
+1 ), SAL_NO_ACQUIRE
);
578 PyRef
rStep( PyLong_FromLong( 1 ), SAL_NO_ACQUIRE
);
579 PyRef
rSlice( PySlice_New( rStart
.get(), rStop
.get(), rStep
.get() ), SAL_NO_ACQUIRE
);
584 static PyObject
* lcl_getitem_XCellRange( PyUNO
const * me
, PyObject
* pKey
)
588 Sequence
<short> aOutParamIndex
;
589 Sequence
<Any
> aOutParam
;
590 Sequence
<Any
> aParams
;
593 // Single string key is sugar for getCellRangeByName()
594 if ( PyUnicode_Check( pKey
) ) {
597 aParams
[0] <<= pyString2ustring( pKey
);
599 PyThreadDetach antiguard
;
600 aRet
= me
->members
->xInvocation
->invoke (
601 "getCellRangeByName", aParams
, aOutParamIndex
, aOutParam
);
603 PyRef rRet
= runtime
.any2PyObject ( aRet
);
604 return rRet
.getAcquired();
609 if ( PyIndex_Check( pKey
) )
611 // [0] is equivalent to [0,:]
613 rKey1
= PySlice_New( nullptr, nullptr, nullptr );
615 else if ( PyTuple_Check( pKey
) && (PyTuple_Size( pKey
) == 2) )
617 rKey0
= PyTuple_GetItem( pKey
, 0 );
618 rKey1
= PyTuple_GetItem( pKey
, 1 );
622 PyErr_SetString( PyExc_KeyError
, "invalid subscript" );
626 // If both keys are indices, return the corresponding cell
627 if ( PyIndex_Check( rKey0
.get() ) && PyIndex_Check( rKey1
.get() ))
629 sal_Int32 nKey0_s
= lcl_PyNumber_AsSal_Int32( rKey0
.get() );
630 sal_Int32 nKey1_s
= lcl_PyNumber_AsSal_Int32( rKey1
.get() );
632 if ( ((nKey0_s
== -1) || (nKey1_s
== -1)) && PyErr_Occurred() )
635 aParams
.realloc( 2 );
636 aParams
[0] <<= nKey1_s
;
637 aParams
[1] <<= nKey0_s
;
639 PyThreadDetach antiguard
;
640 aRet
= me
->members
->xInvocation
->invoke (
641 "getCellByPosition", aParams
, aOutParamIndex
, aOutParam
);
643 PyRef rRet
= runtime
.any2PyObject( aRet
);
644 return rRet
.getAcquired();
647 // If either argument is an index, coerce it to a slice
648 if ( PyIndex_Check( rKey0
.get() ) )
649 rKey0
= lcl_indexToSlice( rKey0
);
651 if ( PyIndex_Check( rKey1
.get() ) )
652 rKey1
= lcl_indexToSlice( rKey1
);
654 // If both arguments are slices, return the corresponding cell range
655 if ( PySlice_Check( rKey0
.get() ) && PySlice_Check( rKey1
.get() ) )
657 sal_Int32 nLen0
= SAL_MAX_INT32
, nLen1
= SAL_MAX_INT32
;
658 sal_Int32 nStart0
= 0, nStop0
= 0, nStep0
= 0, nSliceLength0
= 0;
659 sal_Int32 nStart1
= 0, nStop1
= 0, nStep1
= 0, nSliceLength1
= 0;
662 PyThreadDetach antiguard
;
664 if ( lcl_hasInterfaceByName( me
->members
->wrappedObject
, "com.sun.star.table.XColumnRowRange" ) )
666 lcl_getRowsColumns (me
, nLen0
, nLen1
);
670 int nSuccess1
= lcl_PySlice_GetIndicesEx( rKey0
.get(), nLen0
, &nStart0
, &nStop0
, &nStep0
, &nSliceLength0
);
671 int nSuccess2
= lcl_PySlice_GetIndicesEx( rKey1
.get(), nLen1
, &nStart1
, &nStop1
, &nStep1
, &nSliceLength1
);
672 if ( ((nSuccess1
== -1) || (nSuccess2
== -1)) && PyErr_Occurred() )
675 if ( nSliceLength0
<= 0 || nSliceLength1
<= 0 )
677 PyErr_SetString( PyExc_KeyError
, "invalid number of rows or columns" );
681 if ( nStep0
== 1 && nStep1
== 1 )
684 aParams
[0] <<= nStart1
;
685 aParams
[1] <<= nStart0
;
686 aParams
[2] <<= nStop1
- 1;
687 aParams
[3] <<= nStop0
- 1;
689 PyThreadDetach antiguard
;
690 aRet
= me
->members
->xInvocation
->invoke (
691 "getCellRangeByPosition", aParams
, aOutParamIndex
, aOutParam
);
693 PyRef rRet
= runtime
.any2PyObject( aRet
);
694 return rRet
.getAcquired();
697 PyErr_SetString( PyExc_KeyError
, "step != 1 not supported" );
701 PyErr_SetString( PyExc_KeyError
, "invalid subscript" );
705 static PyObject
* lcl_getitem_index( PyUNO
const *me
, PyObject
*pKey
, Runtime
const & runtime
)
710 nIndex
= lcl_PyNumber_AsSal_Int32( pKey
);
711 if (nIndex
== -1 && PyErr_Occurred())
715 PyThreadDetach antiguard
;
717 Reference
< XIndexAccess
> xIndexAccess( me
->members
->xInvocation
, UNO_QUERY
);
718 if ( xIndexAccess
.is() )
721 nIndex
+= xIndexAccess
->getCount();
722 aRet
= xIndexAccess
->getByIndex( nIndex
);
725 if ( aRet
.hasValue() )
727 PyRef
rRet ( runtime
.any2PyObject( aRet
) );
728 return rRet
.getAcquired();
734 static PyObject
* lcl_getitem_slice( PyUNO
const *me
, PyObject
*pKey
)
738 Reference
< XIndexAccess
> xIndexAccess
;
742 PyThreadDetach antiguard
;
744 xIndexAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
745 if ( xIndexAccess
.is() )
746 nLen
= xIndexAccess
->getCount();
749 if ( xIndexAccess
.is() )
751 sal_Int32 nStart
= 0, nStop
= 0, nStep
= 0, nSliceLength
= 0;
752 int nSuccess
= lcl_PySlice_GetIndicesEx(pKey
, nLen
, &nStart
, &nStop
, &nStep
, &nSliceLength
);
753 if ( nSuccess
== -1 && PyErr_Occurred() )
756 PyRef
rTuple( PyTuple_New( nSliceLength
), SAL_NO_ACQUIRE
, NOT_NULL
);
758 for ( nCur
= nStart
, i
= 0; i
< nSliceLength
; nCur
+= nStep
, i
++ )
763 PyThreadDetach antiguard
;
765 aRet
= xIndexAccess
->getByIndex( nCur
);
767 PyRef rRet
= runtime
.any2PyObject( aRet
);
768 PyTuple_SetItem( rTuple
.get(), i
, rRet
.getAcquired() );
771 return rTuple
.getAcquired();
777 static PyObject
* lcl_getitem_string( PyUNO
const *me
, PyObject
*pKey
, Runtime
const & runtime
)
779 OUString sKey
= pyString2ustring( pKey
);
783 PyThreadDetach antiguard
;
785 Reference
< XNameAccess
> xNameAccess( me
->members
->xInvocation
, UNO_QUERY
);
786 if ( xNameAccess
.is() )
788 aRet
= xNameAccess
->getByName( sKey
);
791 if ( aRet
.hasValue() )
793 PyRef rRet
= runtime
.any2PyObject( aRet
);
794 return rRet
.getAcquired();
800 static PyObject
* PyUNO_getitem( PyObject
*self
, PyObject
*pKey
)
802 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
807 // XIndexAccess access by index
808 if ( PyIndex_Check( pKey
) )
810 PyObject
* pRet
= lcl_getitem_index( me
, pKey
, runtime
);
811 if ( pRet
!= nullptr || PyErr_Occurred() )
815 // XIndexAccess access by slice
816 if ( PySlice_Check( pKey
) )
818 PyObject
* pRet
= lcl_getitem_slice( me
, pKey
);
819 if ( pRet
!= nullptr || PyErr_Occurred() )
823 // XNameAccess access by key
824 if ( PyUnicode_Check( pKey
) )
826 PyObject
* pRet
= lcl_getitem_string( me
, pKey
, runtime
);
827 if ( pRet
!= nullptr )
831 // XCellRange/XColumnRowRange specialisation
832 // Uses reflection as we can't have a hard dependency on XCellRange here
833 bool hasXCellRange
= false;
836 PyThreadDetach antiguard
;
838 hasXCellRange
= lcl_hasInterfaceByName( me
->members
->wrappedObject
, "com.sun.star.table.XCellRange" );
842 return lcl_getitem_XCellRange( me
, pKey
);
846 // If the object is an XIndexAccess and/or XNameAccess, but the
847 // key passed wasn't suitable, give a TypeError which specifically
849 Reference
< XIndexAccess
> xIndexAccess( me
->members
->xInvocation
, UNO_QUERY
);
850 Reference
< XNameAccess
> xNameAccess( me
->members
->xInvocation
, UNO_QUERY
);
851 if ( xIndexAccess
.is() || xNameAccess
.is() )
853 PyErr_SetString( PyExc_TypeError
, "subscription with invalid type" );
857 PyErr_SetString( PyExc_TypeError
, "object is not subscriptable" );
859 catch( const css::lang::IndexOutOfBoundsException
& )
861 PyErr_SetString( PyExc_IndexError
, "index out of range" );
863 catch( const css::container::NoSuchElementException
& )
865 PyErr_SetString( PyExc_KeyError
, "key not found" );
867 catch( const css::script::CannotConvertException
&e
)
869 raisePyExceptionWithAny( css::uno::makeAny( e
) );
871 catch( const css::lang::IllegalArgumentException
&e
)
873 raisePyExceptionWithAny( css::uno::makeAny( e
) );
875 catch( const css::lang::WrappedTargetException
&e
)
877 raisePyExceptionWithAny( css::uno::makeAny( e
) );
879 catch( const css::uno::RuntimeException
&e
)
881 raisePyExceptionWithAny( css::uno::makeAny( e
) );
887 static int lcl_setitem_index( PyUNO
const *me
, PyObject
*pKey
, PyObject
*pValue
)
891 Reference
< XIndexContainer
> xIndexContainer
;
892 Reference
< XIndexReplace
> xIndexReplace
;
893 sal_Int32 nIndex
= lcl_PyNumber_AsSal_Int32( pKey
);
894 if ( nIndex
== -1 && PyErr_Occurred() )
897 bool isTuple
= false;
900 if ( pValue
!= nullptr )
902 isTuple
= PyTuple_Check( pValue
);
906 aValue
= runtime
.pyObject2Any( pValue
);
908 catch ( const css::uno::RuntimeException
& )
910 // TODO pyObject2Any can't convert e.g. dicts but only throws
911 // RuntimeException on failure. Fixing this will require an audit of
912 // all the rest of PyUNO
913 throw css::script::CannotConvertException();
918 PyThreadDetach antiguard
;
920 xIndexContainer
.set( me
->members
->xInvocation
, UNO_QUERY
);
921 if ( xIndexContainer
.is() )
922 xIndexReplace
= xIndexContainer
;
924 xIndexReplace
.set( me
->members
->xInvocation
, UNO_QUERY
);
926 if ( xIndexReplace
.is() && nIndex
< 0 )
927 nIndex
+= xIndexReplace
->getCount();
929 // XIndexReplace replace by index
930 if ( (pValue
!= nullptr) && xIndexReplace
.is() )
934 // Apply type specialisation to ensure the correct kind of sequence is passed
935 Type aType
= xIndexReplace
->getElementType();
936 aValue
= runtime
.getImpl()->cargo
->xTypeConverter
->convertTo( aValue
, aType
);
939 xIndexReplace
->replaceByIndex( nIndex
, aValue
);
943 // XIndexContainer remove by index
944 if ( (pValue
== nullptr) && xIndexContainer
.is() )
946 xIndexContainer
->removeByIndex( nIndex
);
951 PyErr_SetString( PyExc_TypeError
, "cannot assign to object" );
955 static int lcl_setitem_slice( PyUNO
const *me
, PyObject
*pKey
, PyObject
*pValue
)
957 // XIndexContainer insert/remove/replace by slice
960 Reference
< XIndexReplace
> xIndexReplace
;
961 Reference
< XIndexContainer
> xIndexContainer
;
965 PyThreadDetach antiguard
;
967 xIndexContainer
.set( me
->members
->xInvocation
, UNO_QUERY
);
968 if ( xIndexContainer
.is() )
969 xIndexReplace
= xIndexContainer
;
971 xIndexReplace
.set( me
->members
->xInvocation
, UNO_QUERY
);
973 if ( xIndexReplace
.is() )
974 nLen
= xIndexReplace
->getCount();
977 if ( xIndexReplace
.is() )
979 sal_Int32 nStart
= 0, nStop
= 0, nStep
= 0, nSliceLength
= 0;
980 int nSuccess
= lcl_PySlice_GetIndicesEx( pKey
, nLen
, &nStart
, &nStop
, &nStep
, &nSliceLength
);
981 if ( (nSuccess
== -1) && PyErr_Occurred() )
984 if ( pValue
== nullptr )
986 pValue
= PyTuple_New( 0 );
989 if ( !PyTuple_Check (pValue
) )
991 PyErr_SetString( PyExc_TypeError
, "value is not a tuple" );
995 Py_ssize_t nTupleLength_ssize
= PyTuple_Size( pValue
);
996 if ( nTupleLength_ssize
> SAL_MAX_INT32
)
998 PyErr_SetString( PyExc_ValueError
, "tuple too large" );
1001 sal_Int32 nTupleLength
= static_cast<sal_Int32
>(nTupleLength_ssize
);
1003 if ( (nTupleLength
!= nSliceLength
) && (nStep
!= 1) )
1005 PyErr_SetString( PyExc_ValueError
, "number of items assigned must be equal" );
1009 if ( (nTupleLength
!= nSliceLength
) && !xIndexContainer
.is() )
1011 PyErr_SetString( PyExc_ValueError
, "cannot change length" );
1016 sal_Int32 nMax
= ::std::max( nSliceLength
, nTupleLength
);
1017 for ( nCur
= nStart
, i
= 0; i
< nMax
; nCur
+= nStep
, i
++ )
1019 if ( i
< nTupleLength
)
1021 PyRef rItem
= PyTuple_GetItem( pValue
, i
);
1022 bool isTuple
= PyTuple_Check( rItem
.get() );
1027 aItem
= runtime
.pyObject2Any( rItem
.get() );
1029 catch ( const css::uno::RuntimeException
& )
1031 // TODO pyObject2Any can't convert e.g. dicts but only throws
1032 // RuntimeException on failure. Fixing this will require an audit of
1033 // all the rest of PyUNO
1034 throw css::script::CannotConvertException();
1038 PyThreadDetach antiguard
;
1042 // Apply type specialisation to ensure the correct kind of sequence is passed
1043 Type aType
= xIndexReplace
->getElementType();
1044 aItem
= runtime
.getImpl()->cargo
->xTypeConverter
->convertTo( aItem
, aType
);
1047 if ( i
< nSliceLength
)
1049 xIndexReplace
->replaceByIndex( nCur
, aItem
);
1053 xIndexContainer
->insertByIndex( nCur
, aItem
);
1059 PyThreadDetach antiguard
;
1061 xIndexContainer
->removeByIndex( nCur
);
1069 PyErr_SetString( PyExc_TypeError
, "cannot assign to object" );
1073 static int lcl_setitem_string( PyUNO
const *me
, PyObject
*pKey
, PyObject
*pValue
)
1077 OUString sKey
= pyString2ustring( pKey
);
1078 bool isTuple
= false;
1081 if ( pValue
!= nullptr)
1083 isTuple
= PyTuple_Check( pValue
);
1086 aValue
= runtime
.pyObject2Any( pValue
);
1088 catch( const css::uno::RuntimeException
& )
1090 // TODO pyObject2Any can't convert e.g. dicts but only throws
1091 // RuntimeException on failure. Fixing this will require an audit of
1092 // all the rest of PyUNO
1093 throw css::script::CannotConvertException();
1098 PyThreadDetach antiguard
;
1100 Reference
< XNameContainer
> xNameContainer( me
->members
->xInvocation
, UNO_QUERY
);
1101 Reference
< XNameReplace
> xNameReplace
;
1102 if ( xNameContainer
.is() )
1103 xNameReplace
= xNameContainer
;
1105 xNameReplace
.set( me
->members
->xInvocation
, UNO_QUERY
);
1107 if ( xNameReplace
.is() )
1109 if ( isTuple
&& aValue
.hasValue() )
1111 // Apply type specialisation to ensure the correct kind of sequence is passed
1112 Type aType
= xNameReplace
->getElementType();
1113 aValue
= runtime
.getImpl()->cargo
->xTypeConverter
->convertTo( aValue
, aType
);
1116 if ( aValue
.hasValue() )
1118 if ( xNameContainer
.is() )
1121 xNameContainer
->insertByName( sKey
, aValue
);
1124 catch( const css::container::ElementExistException
& )
1126 // Fall through, try replace instead
1130 xNameReplace
->replaceByName( sKey
, aValue
);
1133 else if ( xNameContainer
.is() )
1135 xNameContainer
->removeByName( sKey
);
1141 PyErr_SetString( PyExc_TypeError
, "cannot assign to object" );
1145 static int PyUNO_setitem( PyObject
*self
, PyObject
*pKey
, PyObject
*pValue
)
1147 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
1151 if ( PyIndex_Check( pKey
) )
1153 return lcl_setitem_index( me
, pKey
, pValue
);
1155 else if ( PySlice_Check( pKey
) )
1157 return lcl_setitem_slice( me
, pKey
, pValue
);
1159 else if ( PyUnicode_Check( pKey
) )
1161 return lcl_setitem_string( me
, pKey
, pValue
);
1164 PyErr_SetString( PyExc_TypeError
, "list index has invalid type" );
1166 catch( const css::lang::IndexOutOfBoundsException
& )
1168 PyErr_SetString( PyExc_IndexError
, "list index out of range" );
1170 catch( const css::container::NoSuchElementException
& )
1172 PyErr_SetString( PyExc_KeyError
, "key not found" );
1174 catch( const css::lang::IllegalArgumentException
& )
1176 PyErr_SetString( PyExc_TypeError
, "value has invalid type" );
1178 catch( const css::script::CannotConvertException
& )
1180 PyErr_SetString( PyExc_TypeError
, "value has invalid type" );
1182 catch( const css::container::ElementExistException
&e
)
1184 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1186 catch( const css::lang::WrappedTargetException
&e
)
1188 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1190 catch( const css::uno::RuntimeException
&e
)
1192 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1198 static PyObject
* PyUNO_iter( PyObject
*self
)
1200 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
1204 Reference
< XEnumerationAccess
> xEnumerationAccess
;
1205 Reference
< XEnumeration
> xEnumeration
;
1206 Reference
< XIndexAccess
> xIndexAccess
;
1207 Reference
< XNameAccess
> xNameAccess
;
1210 PyThreadDetach antiguard
;
1212 xEnumerationAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1213 if ( xEnumerationAccess
.is() )
1214 xEnumeration
= xEnumerationAccess
->createEnumeration();
1216 xEnumeration
.set( me
->members
->wrappedObject
, UNO_QUERY
);
1218 if ( !xEnumeration
.is() )
1219 xIndexAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1221 if ( !xIndexAccess
.is() )
1222 xNameAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1225 // XEnumerationAccess iterator
1226 // XEnumeration iterator
1227 if (xEnumeration
.is())
1229 return PyUNO_iterator_new( xEnumeration
);
1232 // XIndexAccess iterator
1233 if ( xIndexAccess
.is() )
1235 // We'd like to be able to use PySeqIter_New() here, but we're not
1236 // allowed to because we also implement the mapping protocol
1237 return PyUNO_list_iterator_new( xIndexAccess
);
1240 // XNameAccess iterator
1241 if (xNameAccess
.is())
1243 // There's no generic mapping iterator, but we can cobble our own
1244 // together using PySeqIter_New()
1249 PyThreadDetach antiguard
;
1250 aRet
<<= xNameAccess
->getElementNames();
1252 PyRef rNames
= runtime
.any2PyObject( aRet
);
1253 return PySeqIter_New( rNames
.getAcquired() );
1256 PyErr_SetString ( PyExc_TypeError
, "object is not iterable" );
1258 catch( css::script::CannotConvertException
&e
)
1260 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1262 catch( css::lang::IllegalArgumentException
&e
)
1264 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1266 catch( const css::uno::RuntimeException
&e
)
1268 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1274 static int PyUNO_contains( PyObject
*self
, PyObject
*pKey
)
1276 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
1285 aValue
= runtime
.pyObject2Any( pKey
);
1287 catch( const css::uno::RuntimeException
& )
1289 // TODO pyObject2Any can't convert e.g. dicts but only throws
1290 // RuntimeException on failure. Fixing this will require an audit of
1291 // all the rest of PyUNO
1292 throw css::script::CannotConvertException();
1295 // XNameAccess is tried first, because checking key presence is much more
1296 // useful for objects which implement both XIndexAccess and XNameAccess
1299 if ( PyUnicode_Check( pKey
) )
1303 Reference
< XNameAccess
> xNameAccess
;
1306 PyThreadDetach antiguard
;
1308 xNameAccess
.set( me
->members
->xInvocation
, UNO_QUERY
);
1309 if ( xNameAccess
.is() )
1311 bool hasKey
= xNameAccess
->hasByName( sKey
);
1312 return hasKey
? 1 : 0;
1317 // For any other type of PyUNO iterable: Ugly iterative search by
1318 // content (XIndexAccess, XEnumerationAccess, XEnumeration)
1319 PyRef
rIterator( PyUNO_iter( self
), SAL_NO_ACQUIRE
);
1320 if ( rIterator
.is() )
1322 while ( PyObject
* pItem
= PyIter_Next( rIterator
.get() ) )
1324 PyRef
rItem( pItem
, SAL_NO_ACQUIRE
);
1325 if ( PyObject_RichCompareBool( pKey
, rItem
.get(), Py_EQ
) == 1 )
1333 PyErr_SetString( PyExc_TypeError
, "argument is not iterable" );
1335 catch( const css::script::CannotConvertException
& )
1337 PyErr_SetString( PyExc_TypeError
, "invalid type passed as left argument to 'in'" );
1339 catch( const css::container::NoSuchElementException
&e
)
1341 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1343 catch( const css::lang::IndexOutOfBoundsException
&e
)
1345 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1347 catch( const css::lang::IllegalArgumentException
&e
)
1349 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1351 catch( const css::lang::WrappedTargetException
&e
)
1353 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1355 catch( const css::uno::RuntimeException
&e
)
1357 raisePyExceptionWithAny( css::uno::makeAny( e
) );
1363 static PyObject
* PyUNO_getattr (PyObject
* self
, char* name
)
1370 PyUNO
* me
= reinterpret_cast<PyUNO
*>(self
);
1371 if (strcmp (name
, "__dict__") == 0)
1373 Py_INCREF (Py_TYPE(me
)->tp_dict
);
1374 return Py_TYPE(me
)->tp_dict
;
1376 if (strcmp (name
, "__class__") == 0)
1378 Py_INCREF (Py_None
);
1382 PyObject
*pRet
= PyObject_GenericGetAttr( self
, PyUnicode_FromString( name
) );
1387 OUString
attrName( OUString::createFromAscii( name
) );
1388 //We need to find out if it's a method...
1389 if (me
->members
->xInvocation
->hasMethod (attrName
))
1391 //Create a callable object to invoke this...
1392 PyRef ret
= PyUNO_callable_new (
1393 me
->members
->xInvocation
,
1395 Py_XINCREF( ret
.get() );
1401 if (me
->members
->xInvocation
->hasProperty ( attrName
))
1403 //Return the value of the property
1406 PyThreadDetach antiguard
;
1407 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( makeAny(e
) );
1425 catch( const css::lang::IllegalArgumentException
&e
)
1427 raisePyExceptionWithAny( makeAny(e
) );
1429 catch( const css::script::CannotConvertException
&e
)
1431 raisePyExceptionWithAny( makeAny(e
) );
1433 catch( const RuntimeException
&e
)
1435 raisePyExceptionWithAny( makeAny(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( makeAny(e
) );
1471 catch( const css::script::CannotConvertException
&e
)
1473 raisePyExceptionWithAny( makeAny(e
) );
1476 catch( const RuntimeException
& e
)
1478 raisePyExceptionWithAny( makeAny( 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( makeAny( e
) );
1527 result
= (op
== Py_EQ
? Py_False
: Py_True
);
1532 static PyMethodDef PyUNOMethods
[] =
1534 {"__dir__", reinterpret_cast<PyCFunction
>(PyUNO_dir
), METH_NOARGS
, nullptr},
1535 {nullptr, nullptr, 0, nullptr}
1538 static PyNumberMethods PyUNONumberMethods
[] =
1540 nullptr, /* nb_add */
1541 nullptr, /* nb_subtract */
1542 nullptr, /* nb_multiply */
1543 nullptr, /* nb_remainder */
1544 nullptr, /* nb_divmod */
1545 nullptr, /* nb_power */
1546 nullptr, /* nb_negative */
1547 nullptr, /* nb_positive */
1548 nullptr, /* nb_absolute */
1549 PyUNO_bool
, /* nb_bool */
1550 nullptr, /* nb_invert */
1551 nullptr, /* nb_lshift */
1552 nullptr, /* nb_rshift */
1553 nullptr, /* nb_and */
1554 nullptr, /* nb_xor */
1555 nullptr, /* nb_or */
1556 nullptr, /* nb_int */
1557 nullptr, /* nb_reserved */
1558 nullptr, /* nb_float */
1559 nullptr, /* nb_inplace_add */
1560 nullptr, /* nb_inplace_subtract */
1561 nullptr, /* nb_inplace_multiply */
1562 nullptr, /* nb_inplace_remainder */
1563 nullptr, /* nb_inplace_power */
1564 nullptr, /* nb_inplace_lshift */
1565 nullptr, /* nb_inplace_rshift */
1566 nullptr, /* nb_inplace_and */
1567 nullptr, /* nb_inplace_xor */
1568 nullptr, /* nb_inplace_or */
1570 nullptr, /* nb_floor_divide */
1571 nullptr, /* nb_true_divide */
1572 nullptr, /* nb_inplace_floor_divide */
1573 nullptr, /* nb_inplace_true_divide */
1575 nullptr, /* nb_index */
1576 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
1577 nullptr, /* nb_matrix_multiply */
1578 nullptr, /* nb_inplace_matrix_multiply */
1582 static PySequenceMethods PyUNOSequenceMethods
[] =
1584 nullptr, /* sq_length */
1585 nullptr, /* sq_concat */
1586 nullptr, /* sq_repeat */
1587 nullptr, /* sq_item */
1588 nullptr, /* sq_slice */
1589 nullptr, /* sq_ass_item */
1590 nullptr, /* sq_ass_slice */
1591 PyUNO_contains
, /* sq_contains */
1592 nullptr, /* sq_inplace_concat */
1593 nullptr /* sq_inplace_repeat */
1596 static PyMappingMethods PyUNOMappingMethods
[] =
1598 PyUNO_len
, /* mp_length */
1599 PyUNO_getitem
, /* mp_subscript */
1600 PyUNO_setitem
, /* mp_ass_subscript */
1603 static PyTypeObject PyUNOType
=
1605 PyVarObject_HEAD_INIT( &PyType_Type
, 0 )
1610 #if PY_VERSION_HEX >= 0x03080000
1611 0, // Py_ssize_t tp_vectorcall_offset
1613 nullptr, // printfunc tp_print
1617 /* this type does not exist in Python 3: (cmpfunc) */ nullptr,
1620 PyUNOSequenceMethods
,
1621 PyUNOMappingMethods
,
1628 Py_TPFLAGS_HAVE_ITER
| Py_TPFLAGS_HAVE_RICHCOMPARE
| Py_TPFLAGS_HAVE_SEQUENCE_IN
,
1656 #if PY_VERSION_HEX >= 0x03040000
1658 #if PY_VERSION_HEX >= 0x03080000
1659 , nullptr // vectorcallfunc tp_vectorcall
1660 #if PY_VERSION_HEX < 0x03090000
1661 #if defined __clang__
1662 #pragma clang diagnostic push
1663 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1665 , nullptr // tp_print
1666 #if defined __clang__
1667 #pragma clang diagnostic pop
1674 int PyUNO_initType()
1676 return PyType_Ready(&PyUNOType
);
1679 PyRef
getPyUnoClass()
1681 return PyRef( reinterpret_cast< PyObject
* > ( &PyUNOType
) );
1685 const Any
&targetInterface
,
1686 const Reference
<XSingleServiceFactory
> &ssf
)
1688 Reference
<XInvocation2
> xInvocation
;
1691 PyThreadDetach antiguard
;
1693 ssf
->createInstanceWithArguments( Sequence
<Any
>( &targetInterface
, 1 ) ), css::uno::UNO_QUERY_THROW
);
1695 auto that
= comphelper::getUnoTunnelImplementation
<Adapter
>(
1696 xInvocation
->getIntrospection()->queryAdapter(cppu::UnoType
<XUnoTunnel
>::get()));
1698 return that
->getWrappedObject();
1700 if( !Py_IsInitialized() )
1701 throw RuntimeException();
1703 PyUNO
* self
= PyObject_New (PyUNO
, &PyUNOType
);
1704 if (self
== nullptr)
1705 return PyRef(); // == error
1706 self
->members
= new PyUNOInternals
;
1707 self
->members
->xInvocation
= xInvocation
;
1708 self
->members
->wrappedObject
= targetInterface
;
1709 return PyRef( reinterpret_cast<PyObject
*>(self
), SAL_NO_ACQUIRE
);
1715 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */