A sandboxed Lua 5.5 interpreter written in pure Python. No dependencies, no C extensions.
pip install abstra-luafromabstra_luaimportLuaSessionsession=LuaSession()
# Execute Lua code, get printed outputoutput=session.execute('print("hello world")')
# output == "hello world"# Evaluate expressions, get Python values backsession.eval("1 + 2") # 3session.eval('"hello"') # "hello"session.eval("{1, 2, 3}") # [1, 2, 3]session.eval("{x = 1}") # {"x": 1}# Pass Python values into Luasession.set("config", {"host": "localhost", "port": 8080})
session.eval("config.host") # "localhost"# Get Lua values back as Pythonsession.execute("function double(x) return x * 2 end")
fn=session.get("double")
fn(21) # 42Types: nil, boolean, number (integer + float), string, table, function
Operators: arithmetic (+-*///%^), comparison (==~=<><=>=), logical (andornot), bitwise (&|~<<>>), concat (..), length (#)
Control flow:if/elseif/else, while, repeat/until, numeric for, generic for, do/end, break, return
Functions: closures, multiple return values, varargs (...), method calls (: syntax), string/table call shorthand
Tables: constructors, dot/bracket access, metatables (__index, __newindex, __call, __add, __sub, __mul, __div, __mod, __pow, __unm, __idiv, __eq, __lt, __le, __len, __concat, __tostring, __band, __bor, __bxor, __bnot, __shl, __shr)
Standard library:
- basic:
print,type,tostring,tonumber,assert,error,pcall,xpcall,pairs,ipairs,next,select,rawget,rawset,rawlen,rawequal,setmetatable,getmetatable,unpack - string:
byte,char,find,format,gmatch,gsub,len,lower,match,rep,reverse,sub,upper— plus method syntax (s:upper()) - table:
concat,insert,move,pack,remove,sort,unpack - math:
abs,acos,asin,atan,ceil,cos,exp,floor,huge,log,max,maxinteger,min,mininteger,pi,random,randomseed,sin,sqrt,tan,tointeger,type - os:
clock,difftime,time
The interpreter is sandboxed by default. There is no access to the filesystem, network, OS commands, or the Python runtime. The following are not available: io, os.execute, os.remove, debug, load, loadfile, dofile, require, package.
Resource limits prevent untrusted code from hanging or exhausting memory:
session=LuaSession(
max_instructions=1_000_000, # VM ops per execute/eval callmax_call_depth=200, # function call nestingmax_output_bytes=1_000_000, # total print output
)| Threat | Protection |
|---|---|
| Infinite loops | Instruction counter (resets each call) |
| Infinite recursion | Call depth limit + Python RecursionError catch |
| Memory bomb via strings | 10 MB concat limit |
| Output flood | Output byte limit |
| File/network access | No io, os.execute, require |
| Code injection | No load, loadstring, dofile |
| Introspection | No debug library |
fromabstra_luaimportLuaSession, LuaSyntaxError, LuaRuntimeErrorsession=LuaSession()
try:
session.execute("if then end")
exceptLuaSyntaxErrorase:
print(e) # syntax errortry:
session.execute('error("boom")')
exceptLuaRuntimeErrorase:
print(e) # boom| Python | Lua | Python |
|---|---|---|
None | nil | None |
bool | boolean | bool |
int | integer | int |
float | float | float |
str | string | str |
dict | table | dict |
list | table (1-indexed) | list or dict |
callable | function | callable |