PYTHON-LUA(7)

NAME
python-lua - using lua scripts from python

SYNOPSIS
import lua
lua_handle.run(script = None, var = None, value = None, name = python string)
lua_handle.run_file(script_file)
lua_handle.module(name, my_module)
lua_table._dict()
lua_table._list()

DESCRIPTION
The lua module interfaces Python code to the Lua library, thus allowing Lua scripts to be run from Python. For most operations, a lua.Lua object must be created. This object does all the work. Creating multiple Lua objects from one Python program should work, but is mostly untested. They are supposed to be completely independent of each other; they don't even share global variables. When creating a Lua instance with debug set to False (the default), it will automatically run self.run(b'debug = nil'), which will disable the debugging library.

lua.run is the main entry point into lua code. It allows running a script (which may be uncompiled or compiled lua code). It can also be used to set the value of a global lua variable to any Python value. script may be omitted, in which case only the assignment is performed. If var is omitted, only the script is run. If both are present, the variable is assigned before the script is run. To assign a variable inside a table, you can use lua_handle.run(b'table.foo = tmp', 'tmp', value). The name is used for error reporting.

When using Python objects from Lua, their python operations are used when invoked. For example, the __add__ function will be called when something is added to the object in lua. This is particularly useful for functions, which can be called from lua this way. Note that passing a method to Lua works fine, but the library will raise an exception if Lua tries to call it with a different object instance. Also, the library may raise exceptions when lua scripts don't expect them, for example when referencing a nonexistent member.

lua.run_file is similar to lua.run, but it takes a filename where the code is located. It does not support variable assignment, so if that is required, a call to lua.run should be used first.

lua.module allows importing an object into lua as a module. This works reasonably well, but there are some limitations, see BUGS.

Lua tables are wrapped in a Python object when they are returned. When changes are made to this Python object, the change is passed through to the lua object. In other words, Lua remains the owner of the table.

Python objects (which are owned by Python) can be created from Lua code using the python module. It has two members, list and dict, which convert a table to a list and dict respectively. In addition, it has a member bytes, which is described in the section STRINGS below.

There are two things to remember when using python.list. First, Lua starts counting at 1, but Python starts at 0. A value called a[3] in Lua is called python.list(a)[2]. Second, when using python.list on a table which contains non-integer keys, those elements are not present in the returned list. In fact, the generated list only has values up to the first index that is not in the table. Note that nil cannot be a value. Setting it will instead remove the corresponding key from the table.

The table wrapper supports most Python operations. It can also be useful to copy it to a dict. This is what python.dict() does. Changes made to this dict are not reflected in the lua table that it was copied from.

STRINGS
Python makes a clear distinction between strings containing text characters, and byte strings containing binary data. Lua makes no such distinction. Because of that, this module needed to make some choices on how to map the two types between the languages.

Lua strings are considered to be text by this module. What this means is that setting a variable to a Python value of type str will result in a Lua string value, and a Lua string is also returned as type str. It is assumed to be encoded as utf-8 in Lua. A non-utf-8 binary string in Lua will not properly transfer to Python unless special precautions are taken.

On the other hand, Python bytes objects can be passed into Lua. They are treated as Python-owned objects. This means that they can be normally accessed, for example by indexing them. Note that because they are Python-owned, the index of the first element is 0.

If bytes objects are needed to be generated by Lua, this can be done using the bytes function in the python module. As an argument, it can take a table (which is treated as a list of bytes, each of which must be an integer), a str (which is first encoded as utf-8, so non-utf-8 sequences in it will NOT survive!) or in integer (which creates a bytes object of the given length, filled with zeroes).

This means that it is possible to pass a binary (non-utf-8) byte string to Python, but the Lua script must first build a table of integers from it. This can be done using python.bytes(value:byte(1, #value)).

SECURITY CONSIDERATIONS
By default, lua has the ability to load any libraries from the system. Lua should not be used for scripts from untrusted sources when this is the case.

On the other hand, this module is secure by default: it disables the debug library and loading of external libraries. If this functionality is needed, it must be enabled in the constructor.

When all is set to True in the constructor, all potentially insecure features are enabled.

BUGS
For module definitions, Lua only supports plain tables, not user objects. This means that no callbacks can be added for events which happen in the top level of the module. In particular, when a Python module is used as a lua module (which is a common use case), a list is built at registration time and passed to lua. When new variables are added to the Python module, or existing variables are changed so they link to new objects, those changes will not be reflected in lua. Similarly, such changes made from lua are not visible in Python. Changing the contents of variables is not affected by this problem.

As a workaround, when changing or creating such variables from Python, you can manually add them to lua as well, using lua.run(var = '<name>', value = <module.name>). When using variables which may have been changed by lua, instead of using their value directly from the python module, use lua.run(<name>).

AUTHOR
Python-lua was written by Bas Wijnen <wijnen@debian.org>