How to translate a Python script to Lua script?

2.4k Views Asked by At

I am trying to translate a piece of code I wrote from Python to Lua. I am using this code inside of compositing package Blackmagic Fusion.

Any help would be greatly appreciated!

Python script (working):

try:
    comp.ActiveTool()                            # checks if a tool is selected
except:
    print("nothing selected")
    comp.AddTool("PolylineMask", -32768, -32768) # adds a tool if nothing's selected

Lua script (still not working and erroring):

if pcall (comp:ActiveTool()) then
    print "Node Selected"
else
   comp:AddTool("PolylineMask", -32768, -32768)
end
4

There are 4 best solutions below

0
On BEST ANSWER

Lua's exception handling works a bit differently than in other languages. Instead of wrapping code in try/catch statements, you instead run a function in a 'protected environment' with pcall.

The general syntax for pcall is:

local ok, err = pcall(myfunc, arg1, arg2, ...)
if not ok then
    print("The error message was "..err)
else
    print("The call went OK!")
end

Where myfunc is the function you want to call and arg1 and so on are the arguments. Note that you aren't actually calling the function, you are just passing it so that pcall can call it for you.

BUT keep in mind that tbl:method(arg1, arg2) in Lua is syntax sugar for tbl.method(tbl, arg1, arg2). However, since you aren't calling the function yourself, you can't use that syntax. You need to pass in the table to pcall as the first argument, like so:

pcall(tbl.method, tbl, arg1, arg2, ...)

Thus, in your case it would be:

local ok, err = pcall(comp.ActiveTool, comp)
5
On

You aren't using pcall correctly. you need to pass it the function you actually want called, and it'll call it in a protected mode where it can trap errors.

pcall returns 2 values, a bool indicating if the call succeeded or not, and an error code if the call did not succeed.

your lua code should look more something like this:

local ok, err = pcall(comp.ActiveTool, comp)
if not ok then
    print(err, 'nothing selected')
    comp.AddTool(...)
else -- the call succeeded
    print 'Node Selected'
end

and in the case that you want to call functions using pcall that take params, you can simply pass them as additional values to pcall, and it'll pass those on to the method you gave it when it calls it.

local ok, err = pcall(comp.AddTool, 'PolylineMask', -32768, -32768)

as an example.

the above line roughly translates to:

try {
    comp.AddTool('PolylineMask', -32768, -32768);
    return true
} 
catch (err) {
    return false, err
}
2
On

Note the difference:

pcall (foo())
pcall (foo)

The first line calls the function foo then passes its result to pcall. If foo throws an error, pcall will never be called.

The second line passes the function foo to pcall. pcall calls foo. If foo throws an error pcall captures it and returns an error message.


In your example, you're making a method call, where comp:ActiveTool() is syntax sugar for comp.ActiveTool(comp) so you'll have to take that into consideration when calling pcall: comp:ActiveTool() => pcall(comp.ActiveTool, comp).

0
On
-- test.lua
require "try-catch"

try {
   function ()
      error('oops')
   end,

   catch {
      function (error)
         print('caught error: ' .. error)
      end
   }
}

...

-- try-catch.lua
function catch (what)
   return what[1]
end

function try (what)
   status, result = pcall(what[1])

   if not status then
      what[2](result)
   end

   return result
end

Original https://gist.github.com/cwarden/1207556