tdf#169229: pyuno: Allow Any when calling a method

Previously when creating a callable object for an attribute on an
object (ie, a method), it would mark it with a special mode to disallow
passing a pyuno.Any as an argument. There doesn’t seem to be a good
reason to do this and it makes it difficult to use an explicit type when
calling a method that can take an Any. This patch instead just removes
the mode parameter from pyobject2Any entirely.

The example in the bug report is trying to call
createInstanceWithArgumentsAndContext which takes a Sequence of Anys as
an argument. Without this patch it is difficult to pass a null interface
as one of the arguments.

Change-Id: I8756bdc2821ebf247ff67a66f071263ac00e3890
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195452
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@collabora.com>
This commit is contained in:
Neil Roberts
2025-12-18 10:05:39 +01:00
committed by Stephan Bergmann
parent 8ca7c97770
commit 507b6c2b90
9 changed files with 22 additions and 33 deletions
+1 -5
View File
@@ -150,9 +150,6 @@ public:
//struct stRuntimeImpl;
typedef struct stRuntimeImpl RuntimeImpl;
enum ConversionMode { ACCEPT_UNO_ANY, REJECT_UNO_ANY };
/** The pyuno::Runtime class keeps the internal state of the python UNO bridge
for the currently in use python interpreter.
@@ -229,8 +226,7 @@ public:
@throws css::uno::RuntimeException
*/
css::uno::Any pyObject2Any (
const PyRef & source , enum ConversionMode mode = REJECT_UNO_ANY ) const;
css::uno::Any pyObject2Any ( const PyRef & source ) const;
/** extracts a proper uno exception from a given python exception
*/
+2 -5
View File
@@ -392,10 +392,7 @@ PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args )
{
throw RuntimeException( "Attribute " + attrName + " unknown" );
}
callable = PyUNO_callable_new (
me->members->xInvocation,
attrName,
ACCEPT_UNO_ANY);
callable = PyUNO_callable_new ( me->members->xInvocation, attrName );
paras = args;
}
else
@@ -1446,7 +1443,7 @@ static int PyUNO_setattr (PyObject* self, char* name, PyObject* value)
try
{
Runtime runtime;
Any val= runtime.pyObject2Any(value, ACCEPT_UNO_ANY);
Any val= runtime.pyObject2Any(value);
OUString attrName( OUString::createFromAscii( name ) );
{
+1 -1
View File
@@ -235,7 +235,7 @@ Any Adapter::invoke( const OUString &aFunctionName,
raiseInvocationTargetExceptionWhenNeeded( runtime);
if( pyRet.is() )
{
ret = runtime.pyObject2Any( pyRet, ACCEPT_UNO_ANY );
ret = runtime.pyObject2Any( pyRet );
if( ret.hasValue() &&
ret.getValueTypeClass() == css::uno::TypeClass_SEQUENCE &&
+2 -5
View File
@@ -37,7 +37,6 @@ struct PyUNO_callable_Internals
{
Reference<XInvocation2> xInvocation;
OUString methodName;
ConversionMode mode;
};
struct PyUNO_callable
@@ -75,7 +74,7 @@ static PyObject* PyUNO_callable_call(
{
Runtime runtime;
cargo = runtime.getImpl()->cargo;
any_params = runtime.pyObject2Any (args, me->members->mode);
any_params = runtime.pyObject2Any (args);
if (any_params.getValueTypeClass () == css::uno::TypeClass_SEQUENCE)
{
@@ -256,8 +255,7 @@ static PyTypeObject PyUNO_callable_Type =
PyRef PyUNO_callable_new (
const Reference<XInvocation2> &my_inv,
const OUString & methodName,
enum ConversionMode mode )
const OUString & methodName )
{
PyUNO_callable* self;
@@ -270,7 +268,6 @@ PyRef PyUNO_callable_new (
self->members = new PyUNO_callable_Internals;
self->members->xInvocation = my_inv;
self->members->methodName = methodName;
self->members->mode = mode;
return PyRef( reinterpret_cast<PyObject*>(self), SAL_NO_ACQUIRE );
}
+1 -2
View File
@@ -177,8 +177,7 @@ void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime );
PyRef PyUNO_callable_new (
const css::uno::Reference<css::script::XInvocation2> &xInv,
const OUString &methodName,
ConversionMode mode = REJECT_UNO_ANY );
const OUString &methodName );
PyObject* PyUNO_Type_new (const char *typeName , css::uno::TypeClass t , const Runtime &r );
PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r );
+2 -2
View File
@@ -161,7 +161,7 @@ void fillStruct(
{
state.setInitialised(OUMemberName);
state.setUsed(pyMemberName);
Any a = runtime.pyObject2Any( element, ACCEPT_UNO_ANY );
Any a = runtime.pyObject2Any( element );
inv->setValue( OUMemberName, a );
}
}
@@ -174,7 +174,7 @@ void fillStruct(
const OUString aMemberName (pCompType->ppMemberNames[i]);
state.setInitialised(aMemberName, tupleIndex);
PyObject *element = PyTuple_GetItem( initializer, tupleIndex );
Any a = runtime.pyObject2Any( element, ACCEPT_UNO_ANY );
Any a = runtime.pyObject2Any( element );
inv->setValue( aMemberName, a );
}
}
+3 -10
View File
@@ -662,7 +662,7 @@ bool Runtime::pyIterUnpack( PyObject *const pObj, Any &a ) const
return true;
}
Any Runtime::pyObject2Any(const PyRef & source, enum ConversionMode mode) const
Any Runtime::pyObject2Any(const PyRef & source) const
{
if (!impl || !impl->cargo->valid)
{
@@ -726,7 +726,7 @@ Any Runtime::pyObject2Any(const PyRef & source, enum ConversionMode mode) const
auto sRange = asNonConstRange(s);
for (Py_ssize_t i = 0; i < PyTuple_Size (o); i++)
{
sRange[i] = pyObject2Any (PyTuple_GetItem (o, i), mode );
sRange[i] = pyObject2Any (PyTuple_GetItem (o, i) );
}
a <<= s;
}
@@ -737,7 +737,7 @@ Any Runtime::pyObject2Any(const PyRef & source, enum ConversionMode mode) const
auto sRange = asNonConstRange(s);
for (Py_ssize_t i = 0; i < l; i++)
{
sRange[i] = pyObject2Any (PyList_GetItem (o, i), mode );
sRange[i] = pyObject2Any (PyList_GetItem (o, i) );
}
a <<= s;
}
@@ -797,13 +797,6 @@ Any Runtime::pyObject2Any(const PyRef & source, enum ConversionMode mode) const
}
else if( PyObject_IsInstance( o, getAnyClass( runtime ).get() ) )
{
if( ACCEPT_UNO_ANY != mode )
{
throw RuntimeException(
u"uno.Any instance not accepted during method call, "
"use uno.invoke instead"_ustr );
}
a = pyObject2Any( PyRef( PyObject_GetAttrString( o , "value" ), SAL_NO_ACQUIRE) );
Type t;
pyObject2Any( PyRef( PyObject_GetAttrString( o, "type" ), SAL_NO_ACQUIRE ) ) >>= t;
+1 -1
View File
@@ -188,7 +188,7 @@ static int PyUNOStruct_setattr (PyObject* self, char* name, PyObject* value)
try
{
Runtime runtime;
Any val= runtime.pyObject2Any(value, ACCEPT_UNO_ANY);
Any val= runtime.pyObject2Any(value);
OUString attrName( OUString::createFromAscii( name ) );
{
+9 -2
View File
@@ -315,7 +315,9 @@ class ByteSequence:
class Any:
"""Represents a UNO Any value.
Use only in connection with uno.invoke() to pass an explicit typed Any.
Use to pass an explicit typed Any. Note that before LibreOffice 26.8 it was not possible to pass
an Any as an argument to a method call and you had to use uno.invoke instead.
"""
def __init__(self, type, value):
@@ -328,7 +330,12 @@ class Any:
def invoke(object, methodname, argTuple):
"""Use this function to pass exactly typed Anys to the callee (using uno.Any)."""
"""Use this function to call an interface method named by a string.
Note that before LibreOffice 26.8 this function was needed in order to pass an Any as an
argument to a method call, but now it is possible to just directly call the method instead.
"""
return pyuno.invoke(object, methodname, argTuple)