[ANN] Lupa 0.17 released - Lua in Python

Stefan Behnel stefan_ml at behnel.de
Sat Nov 6 00:16:44 CET 2010

Hi all,

I am happy to announce the release of Lupa 0.17.


Have fun,


What is Lupa?

Lupa integrates the LuaJIT2 runtime [1] into CPython. It is a rewrite of 
LunaticPython in Cython with several advanced features.

This release features iteration support for Python objects in Lua.

Changes in this release:

0.17 (2010-11-05)

     * new helper function "python.enumerate()" in Lua that returns a Lua
       iterator for a Python object and adds the 0-based index to each item.
     * new helper function "python.iterex()" in Lua that returns a Lua
       iterator for a Python object and unpacks any tuples that the
       iterator yields into separate Lua arguments.
     * new helper function "python.iter()" in Lua that returns a Lua
       iterator for a Python object.
     * resurrected the "python.as_function()" helper function for Lua code
       as it can be needed in cases where Lua cannot determine how to run a
       Python function.

[1] LuaJIT2: http://luajit.org/


* separate Lua runtime states through a LuaRuntime class
* frees the GIL and supports threading in separate runtimes when
   calling into Lua
* Python compatible coroutine wrapper for Lua coroutines
* iteration support for Python objects in Lua and Lua objects in Python
* proper encoding and decoding of strings (configurable per runtime,
   UTF-8 by default)
* supports Python 2.x and 3.x, potentially starting with Python 2.3
  (currently untested)
* written for LuaJIT2, as opposed to the Lua interpreter (tested with
   LuaJIT 2.0.0-beta5)
* easy to hack on and extend as it is written in Cython, not C

Why use it?

It complements Python very well. Lua is a language as dynamic as Python, 
but LuaJIT compiles it to very fast machine code, sometimes faster than 
many other compiled languages for computational code. The language runtime 
is extremely small and carefully designed for embedding. The complete 
binary module of Lupa, including a statically linked LuaJIT2 runtime, is 
only some 500KB on a 64 bit machine.

However, the Lua ecosystem lacks many of the batteries that Python readily 
includes, either directly in its standard library or as third party 
packages. This makes real-world Lua applications harder to write than 
equivalent Python applications. Lua is therefore not commonly used as 
primary language for large applications, but it makes for a fast, 
high-level and resource-friendly backup language inside of Python when raw 
speed is required and the edit-compile-run cycle of binary extension 
modules is too heavy and too static for agile development or hot-deployment.

Lupa is a very fast and thin wrapper around LuaJIT. It makes it easy to 
write dynamic Lua code that accompanies dynamic Python code by switching 
between the two languages at runtime, based on the tradeoff between 
simplicity and speed.


>>> from lupa import LuaRuntime
>>> lua = LuaRuntime()

>>> lua.eval('1+1')

>>> lua_func = lua.eval('function(f, n) return f(n) end')

>>> def py_add1(n): return n+1
>>> lua_func(py_add1, 2)

>>> lua_code = '''\
...     function(N)
...         for i=0,N do
...             coroutine.yield( i%2 )
...         end
...     end
... '''
>>> f = lua.eval(lua_code)

>>> gen = f.coroutine(4)
>>> list(enumerate(gen))
[(0, 0), (1, 1), (2, 0), (3, 1), (4, 0)]

>>> lua_code = '''\
...     function(L)
...         for item in python.iter(L) do
...             if item == 3 then return 1 end
...         end
...         return 0
...     end
... '''

>>> f = lua.eval(lua_code)
>>> f([1,2,3])
>>> f([1,2])

More information about the Python-announce-list mailing list