david
david

Reputation: 2638

How can I return a list from a python function

https://stackoverflow.com/a/8978435/1335492

...shows how to call a python script from LibreOffice BASIC: (How can I call a Python macro in a cell formula in OpenOffice.Org Calc? )

Function invokeScriptFunc(..., args As Array, outIdxs As Array, outArgs As Array)
   ...
   invokeScriptFunc = oScript.invoke(args, outIdxs, outArgs)
end Function

But that doesn't work for me. I get "BASIC runtime error. Argument is not optional" for outArgs. On the other hand, "oScript.invoke(args, Array(), Array())" is not an error.

The example has not been wrong for 10 years, it's unlikely to be wrong today. But I've not got an example of it working with a python script that returns a list: perhaps that is my problem.

The script I am trying to use is:

def MyFunc(a,b):
  return [a,b]

I don't get the error when I try

Function invokeScriptFunc(..., args As Array, outIdxs As Array)
   ...
   dim outArgs as array
   invokeScriptFunc = oScript.invoke(args, outIdxs, outArgs)
end Function

or

   invokeScriptFunc = oScript.invoke(args, outIdxs, array())

but either way, I'm no closer to seeing the return value I want. FWIW, when I "dim outArgs as array", .invoke returns an object with lbound=0 and ubound=-1. outArgs(0) is not valid.

I'm not trying to parse the output: that comes later. I'm just trying to get it to run without error.

Upvotes: 0

Views: 143

Answers (2)

Jim K
Jim K

Reputation: 13819

Everything necessary for returning a list is explained in the documentation at https://help.libreoffice.org/latest/en-US/text/sbasic/guide/basic_2_python.html. Here is working code.

Function invokeScriptFunc(args As Array)
    oScript = GetPythonScript("filename.py$MyFunc", "user")
    invokeScriptFunc = oScript.invoke(args, Array(), Array())
End Function

Sub call_invokeScriptFunct
    result = invokeScriptFunc(Array(5, 5))
    MsgBox result(1)
End Sub

I modified the python code so that it actually does something.

def MyFunc(a, b):
    return [a+1, b-1]

Result: 4 which is 5 minus 1

Upvotes: 0

david
david

Reputation: 2638

The first parameter to .invoke is (all arguments).

The second parameter to .invoke is a list indicating which arguments are output arguments.

The third parameter to .invoke is (output arguments). Because in Java, method arguments are immutable. The Java interface returns values in (output arguments). The python interface does not use (output arguments): output is returned as the return value of .invoke.

So for python scripts, outIdxs should be an empty array, and outArgs will be an empty array.

This does not explain why passing an empty array to outIdxs and to outArgs is sometimes an error, depending on how the empty array has been declared. That has to do with how declarations happen and errors are defined, detected and reported in LibreOffice BASIC, which is a completely separate subject.

Upvotes: 0

Related Questions