NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #743 most downloaded on PyPI
Python wrapper around Lua and LuaJIT
Last release 5 months ago
15 Apr 2026
Release timing varies
gaps range from 8 days to 1.7 years
Nearly every release is documented
notes for 47 of 47 stable releases
Nothing withdrawn
no release was ever pulled
16 years old
48 releases · first in 2010
* GH#288: No changes in source or functionality, just removed files from the sdist content that prevented it from building on non-x86_64 platforms.
2.8 (2026-04-15)
----------------
* GH#288: No changes in source or functionality, just removed files from the
sdist content that prevented it from building on non-x86_64 platforms.
* Py3.8 wheels were excluded due to lack of usage. The package still builds
and is tested on Py3.8, but no pre-built wheels are provided.
* In Lua 5.5, the string hash seed can be configured for each LuaRuntime.
2.7 (2026-04-07)
----------------
* In Lua 5.5, the string hash seed can be configured for each ``LuaRuntime``.
* The bundled LuaJIT versions were updated to the latest git branches.
* Lua 5.5 is included in the binary wheels.
* Lupa can be built as abi3 wheel.
* Some lesser used platforms are served with abi3 wheels.
* Built with Cython 3.2.4.
One column per quarter.
* The bundled LuaJIT versions were updated to the latest git branches.
2.6 (2025-10-24)
----------------
* The bundled LuaJIT versions were updated to the latest git branches.
* Built with Cython 3.1.6.
* GH#284: Lua uses dlopen() again, which was lost in Lupa 2.3. Patch by Philipp Krones.
2.5 (2025-06-15)
----------------
* GH#284: Lua uses ``dlopen()`` again, which was lost in Lupa 2.3.
Patch by Philipp Krones.
* The bundled Lua 5.4 was updated to 5.4.8.
* The bundled LuaJIT versions were updated to the latest git branches.
* Built with Cython 3.1.2.
* The Windows wheels now bundle LuaJIT 2.0 and 2.1. (patch by Michal Plichta)
2.4 (2025-01-10)
----------------
* The Windows wheels now bundle LuaJIT 2.0 and 2.1.
(patch by Michal Plichta)
* Failures in the test suite didn't set a non-zero process exit value.
* The bundled LuaJIT versions were updated to the latest git branches.
2.3 (2025-01-09)
----------------
* The bundled LuaJIT versions were updated to the latest git branches.
* The bundled Lua 5.4 was updated to 5.4.7.
* Removed support for Python 2.x.
* Built with Cython 3.0.11.
A new method LuaRuntime.gccollect() was added to trigger the Lua garbage collector.
A new method LuaRuntime.gccollect() was added to trigger the Lua garbage collector.
A new context manager LuaRuntime.nogc() was added to temporarily disable the Lua garbage collector.
Freeing Python objects from a thread while running Lua code could run into a deadlock.
The bundled LuaJIT versions were updated to the latest git branches.
Built with Cython 3.0.10.
GH#199: The table_from() method gained a new keyword argument recursive=False. If true, Python data structures will be recursively mapped to Lua table
GH#199: The table_from() method gained a new keyword argument recursive=False. If true, Python data structures will be recursively mapped to Lua tables, taking care of loops and duplicates via identity de-duplication.
GH#248: The LuaRuntime methods "eval", "execute" and "compile" gained new keyword options mode and name that allow constraining the input type and modifying the (chunk) name shown in error messages, following similar arguments in the Lua load() function. See https://www.lua.org/manual/5.4/manual.html#pdf-load
GH#246: Loading Lua modules did not work for the version specific Lua modules introduced in Lupa 2.0. It turned out that it can only be enabled for one of them in a given Python run, so it is now left to users to enable it explicitly at need. (original patch by Richard Connon)
GH#234: The bundled Lua 5.1 was updated to 5.1.5 and Lua 5.2 to 5.2.4. (patch by xxyzz)
The bundled Lua 5.4 was updated to 5.4.6.
The bundled LuaJIT versions were updated to the latest git branches.
Built with Cython 3.0.9 for improved support of Python 3.12/13.
GH#217: Lua stack traces in Python exception messages are now reversed to match the order of Python stack traces.
GH#217: Lua stack traces in Python exception messages are now reversed to match the order of Python stack traces.
GH#196: Lupa now ships separate extension modules built with Lua 5.3, Lua 5.4, LuaJIT 2.0 and LuaJIT 2.1 beta. Note that this is build specific and may depend on the platform. A normal Python import cascade can be used.
GH#211: A new option max_memory allows to limit the memory usage of Lua code. (patch by Leo Developer)
GH#171: Python references in Lua are now more safely reference counted to prevent garbage collection glitches. (patch by Guilherme Dantas)
GH#146: Lua integers in Lua 5.3+ are converted from and to Python integers. (patch by Guilherme Dantas)
GH#180: The python.enumerate() function now returns indices as integers if supported by Lua. (patch by Guilherme Dantas)
GH#178: The Lua integer limits can be read from the module as LUA_MAXINTEGER and LUA_MININTEGER. (patch by Guilherme Dantas)
GH#174: Failures while calling the __index method in Lua during a table index lookup from Python could crash Python. (patch by Guilherme Dantas)
GH#137: Passing None as a dict key into table_from() crashed. (patch by Leo Developer)
GH#176: A new function python.args(*args, **kwargs) was added to help with building Python argument tuples and keyword argument dicts for Python function calls from Lua code.
GH#177: Tables that are not sequences raise IndexError when unpacking them. Previously, non-sequential items were simply ignored.
GH#179: Resolve some C compiler warnings about signed/unsigned comparisons. (patch by Guilherme Dantas)
Built with Cython 0.29.34.
Rebuild with Cython 0.29.32 to support Python 3.11.
Rebuild with Cython 0.29.32 to support Python 3.11.
Bundled Lua source files were missing in the source distribution.
Bundled Lua source files were missing in the source distribution.
GH#197: Some binary wheels in the last releases were not correctly linked with Lua.
GH#197: Some binary wheels in the last releases were not correctly linked with Lua.
GH#194: An absolute file path appeared in the SOURCES.txt metadata of the source distribution.
Use Lua 5.4.4 in binary wheels and as bundled Lua.
Use Lua 5.4.4 in binary wheels and as bundled Lua.
Built with Cython 0.29.28 to support Python 3.10/11.
GH#147: Lua 5.4 is supported. (patch by Russel Davis)
GH#147: Lua 5.4 is supported. (patch by Russel Davis)
The runtime version of the Lua library as a tuple (e.g. (5,3)) is provided via lupa.LUA_VERSION and LuaRuntime.lua_version.
The Lua implementation name and version string is provided as LuaRuntime.lua_implementation.
setup.py accepts new command line arguments --lua-lib and --lua-includes to specify the
Use Lua 5.4.3 in binary wheels and as bundled Lua.
Built with Cython 0.29.24 to support Python 3.9.
Build against Lua 5.3 if available.
Build against Lua 5.3 if available.
Use Lua 5.3.5 in binary wheels and as bundled Lua.
GH#129: Fix Lua module loading in Python 3.x.
GH#126: Fix build on Linux systems that install Lua as "lua52" package.
Built with Cython 0.29.14 for better Py3.8 compatibility.
GH#107: Fix a deprecated import in Py3.
GH#107: Fix a deprecated import in Py3.
Built with Cython 0.29.3 for better Py3.7 compatibility.
GH#103: Provide wheels for MS Windows and fix MSVC build on Py2.7.
GH#103: Provide wheels for MS Windows and fix MSVC build on Py2.7.
GH#95: Improved compatibility with Lua 5.3. (patch by TitanSnow)
GH#95: Improved compatibility with Lua 5.3. (patch by TitanSnow)
GH#93: New method LuaRuntime.compile() to compile Lua code without executing it. (patch by TitanSnow)
GH#93: New method LuaRuntime.compile() to compile Lua code without executing it. (patch by TitanSnow)
GH#91: Lua 5.3 is bundled in the source distribution to simplify one-shot installs. (patch by TitanSnow)
GH#87: Lua stack trace is included in output in debug mode. (patch by aaiyer)
GH#78: Allow Lua code to intercept Python exceptions. (patch by Sergey Dobrov)
Built with Cython 0.26.1.
GH#82: Lua coroutines were using the wrong runtime state (patch by Sergey Dobrov)
GH#82: Lua coroutines were using the wrong runtime state (patch by Sergey Dobrov)
GH#81: copy locally provided Lua DLL into installed package on Windows (patch by Gareth Coles)
built with Cython 0.25.2
GH#70: eval() and execute() accept optional positional arguments (patch by John Vandenberg)
GH#70: eval() and execute() accept optional positional arguments (patch by John Vandenberg)
GH#65: calling str() on a Python object from Lua could fail if the LuaRuntime is set up without auto-encoding (patch by Mikhail Korobov)
GH#63: attribute/keyword names were not properly encoded if the LuaRuntime is set up without auto-encoding (patch by Mikhail Korobov)
built with Cython 0.24
callbacks returned from Lua coroutines were incorrectly mixing coroutine state with global Lua state (patch by Mikhail Korobov)
callbacks returned from Lua coroutines were incorrectly mixing coroutine state with global Lua state (patch by Mikhail Korobov)
availability of python.builtins in Lua can be disabled via LuaRuntime option.
built with Cython 0.23.4
new module function lupa.lua_type() that returns the Lua type of a wrapped object as string, or None for normal Python objects
new module function lupa.lua_type() that returns the Lua type of a wrapped object as string, or None for normal Python objects
new helper method LuaRuntime.table_from(...) that creates a Lua table from one or more Python mappings and/or sequences
new lupa.unpacks_lua_table and lupa.unpacks_lua_table_method decorators to allow calling Python functions from Lua using named arguments
fix a hang on shutdown where the LuaRuntime failed to deallocate due to reference cycles
Lupa now plays more nicely with other Lua extensions that create userdata objects
fix a crash when requesting attributes of wrapped Lua coroutine objects
fix a crash when requesting attributes of wrapped Lua coroutine objects
looking up attributes on Lua objects that do not support it now always raises an AttributeError instead of sometimes raising a TypeError depending on the attribute name
NOTE: this release includes the major backwards incompatible changes listed below. It is believed that they simplify the interaction between Python co…
NOTE: this release includes the major backwards incompatible changes listed below. It is believed that they simplify the interaction between Python code and Lua code by more strongly following idiomatic Lua on the Lua side.
Instead of passing a wrapped python.none object into Lua, None return values are now mapped to nil, making them more straight forward to handle in Lua code. This makes the behaviour more consistent, as it was previously somewhat arbitrary where none could appear and where a nil value was used. The only remaining exception is during iteration, where the first returned value must not be nil in Lua, or otherwise the loop terminates prematurely. To prevent this, any None value that the iterator returns, or any first item in exploded tuples that is None, is still mapped to python.none. Any further values returned in the same iteration will be mapped to nil if they are None, not to none. This means that only the first argument needs to be manually checked for this special case. For the enumerate() iterator, the counter is never None and thus the following unpacked items will never be mapped to python.none.
When unpack_returned_tuples=True, iteration now also unpacks tuple values, including enumerate() iteration, which yields a flat sequence of counter and unpacked values.
When calling bound Python methods from Lua as "obj:meth()", Lupa now prevents Python from prepending the self argument a second time, so that the Python method is now called as "obj.meth()". Previously, it was called as "obj.meth(obj)". Note that this can be undesired when the object itself is explicitly passed as first argument from Lua, e.g. when calling "func(obj)" where "func" is "obj.meth", but these constellations should be rare. As a work-around for this case, user code can wrap the bound method in another function so that the final call comes from Python.
garbage collection works for reference cycles that span both runtimes, Python and Lua
calling from Python into Lua and back into Python did not clean up the Lua call arguments before the innermost call, so that they could leak into the nested Python call or its return arguments
support for Lua 5.2 (in addition to Lua 5.1 and LuaJIT 2.0)
Lua tables support Python's "del" statement for item deletion (patch by Jason Fried)
Attribute lookup can use a more fine-grained control mechanism by implementing explicit getter and setter functions for a LuaRuntime (attribute_handlers argument). Patch by Brian Moe.
item assignments/lookups on Lua objects from Python no longer special case double underscore names (as opposed to attribute lookups)
Nothing published for this version
some garbage collection issues were cleaned up using new Cython features
some garbage collection issues were cleaned up using new Cython features
new LuaRuntime option unpack_returned_tuples which automatically unpacks tuples returned from Python functions into separate Lua objects (instead of returning a single Python tuple object)
some internal wrapper classes were removed from the module API
Windows build fixes
Py3.x build fixes
support for building with Lua 5.1 instead of LuaJIT (setup.py --no-luajit)
no longer uses Cython by default when building from released sources (pass --with-cython to explicitly request a rebuild)
requires Cython 0.20+ when building from unreleased sources
built with Cython 0.20.1
fix "deallocating None" crash while iterating over Lua tables in Python code
fix "deallocating None" crash while iterating over Lua tables in Python code
support for filtering attribute access to Python objects for Lua code
fix: setting source encoding for Lua code was broken
fix serious resource leak when creating multiple LuaRuntime instances
fix serious resource leak when creating multiple LuaRuntime instances
portability fix for binary module importing
fix iteration by returning Py_None object for None instead of nil, which would terminate the iteration
fix iteration by returning Py_None object for None instead of nil, which would terminate the iteration
when converting Python values to Lua, represent None as a Py_None object in places where nil has a special meaning, but leave it as nil where it doesn't hurt
support for counter start value in python.enumerate()
native implementation for python.enumerate() that is several times faster
much faster Lua iteration over Python objects
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.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.
new helper function python.iter() in Lua that returns a Lua iterator for a Python object.
reestablished 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.
dropped python.as_function() helper function for Lua as all Python objects are callable from Lua now (potentially raising a TypeError at call time if
dropped python.as_function() helper function for Lua as all Python objects are callable from Lua now (potentially raising a TypeError at call time if they are not callable)
fix regression in 0.13 and later where ordinary Lua functions failed to print due to an accidentally used meta table
fix crash when calling str() on wrapped Lua objects without metatable
support for loading binary Lua modules on systems that support it
support for loading binary Lua modules on systems that support it
relicensed to the MIT license used by LuaJIT2 to simplify licensing considerations
relicensed to the MIT license used by LuaJIT2 to simplify licensing considerations
fix Cython generated C file using Cython 0.13
fix Cython generated C file using Cython 0.13
fixed undefined behaviour on str(lua_object) when the object's __tostring() meta method fails
fixed undefined behaviour on str(lua_object) when the object's __tostring() meta method fails
removed redundant "error:" prefix from LuaError messages
access to Python's python.builtins from Lua code
more generic wrapping rules for Python objects based on supported protocols (callable, getitem, getattr)
new helper functions as_attrgetter() and as_itemgetter() to specify the Python object protocol used by Lua indexing when wrapping Python objects in Python code
new helper functions python.as_attrgetter(), python.as_itemgetter() and python.as_function() to specify the Python object protocol used by Lua indexing of Python objects in Lua code
item and attribute access for Python objects from Lua code
fix Lua stack leak during table iteration
fix Lua stack leak during table iteration
fix lost Lua object reference after iteration
error reporting on Lua syntax errors failed to clean up the stack so that errors could leak into the next Lua run
error reporting on Lua syntax errors failed to clean up the stack so that errors could leak into the next Lua run
Lua error messages were not properly decoded
much faster locking of the LuaRuntime, especially in the single threaded case (see http://code.activestate.com/recipes/577336-fast-re-entrant-optimist
much faster locking of the LuaRuntime, especially in the single threaded case (see http://code.activestate.com/recipes/577336-fast-re-entrant-optimistic-lock-implemented-in-cyt/)
fixed several error handling problems when executing Python code inside of Lua
fixed Python special double-underscore method access on LuaObject instances
fixed Python special double-underscore method access on LuaObject instances
Lua coroutine support through dedicated wrapper classes, including Python iteration support. In Python space, Lua coroutines behave exactly like Python generators.
support for returning multiple values from Lua evaluation
support for returning multiple values from Lua evaluation
repr() support for Lua objects
LuaRuntime.table() method for creating Lua tables from Python space
encoding fix for str(LuaObject)
LuaRuntime.require() and LuaRuntime.globals() methods
LuaRuntime.require() and LuaRuntime.globals() methods
renamed LuaRuntime.run() to LuaRuntime.execute()
support for len(), setattr() and subscripting of Lua objects
provide all built-in Lua libraries in LuaRuntime, including support for library loading
fixed a thread locking issue
fix passing Lua objects back into the runtime from Python space
Python iteration support for Lua objects (e.g. tables)
Python iteration support for Lua objects (e.g. tables)
threading fixes
fix compile warnings
explicit encoding options per LuaRuntime instance to decode/encode strings and Lua code
explicit encoding options per LuaRuntime instance to decode/encode strings and Lua code
attribute read access on Lua objects, e.g. to read Lua table values from Python
attribute read access on Lua objects, e.g. to read Lua table values from Python
str() on Lua objects
include .hg repository in source downloads
added missing files to source distribution
safely free the GIL when calling into Lua
fix several threading issues
safely free the GIL when calling into Lua
propagate Python exceptions through Lua calls
propagate Python exceptions through Lua calls
* first public release
first public release
Your coding agent can read these notes before it upgrades. Set up the MCP server →