Skip to main content

Python wrapper around Lua and LuaJIT

Project description

Lupa

logo/logo-220x200.png

Lupa integrates the runtimes of Lua or LuaJIT2 into CPython. It is a partial rewrite of LunaticPython in Cython with some additional features such as proper coroutine support.

For questions not answered here, please contact the Lupa mailing list.

Major features

  • separate Lua runtime states through a LuaRuntime class

  • Python 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)

  • frees the GIL and supports threading in separate runtimes when calling into Lua

  • tested with Python 3.8 and later

  • ships with Lua 5.1, 5.2, 5.3 and 5.4 as well as LuaJIT 2.0 and 2.1 on systems that support it.

  • easy to hack on and extend as it is written in Cython, not C

Why the name?

In Latin, “lupa” is a female wolf, as elegant and wild as it sounds. If you don’t like this kind of straight forward allegory to an endangered species, you may also happily assume it’s just an amalgamation of the phonetic sounds that start the words “Lua” and “Python”, two from each to keep the balance.

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 statically compiled languages for computational code. The language runtime is very small and carefully designed for embedding. The complete binary module of Lupa, including a statically linked LuaJIT2 runtime, only weighs some 800KB on a 64 bit machine. With standard Lua 5.2, it’s less than 600KB.

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 Lua or 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.

Which Lua version?

The binary wheels include different Lua versions as well as LuaJIT, if supported. By default, import lupa uses the latest Lua version, but you can choose a specific one via import:

try:
    import lupa.luajit21 as lupa
except ImportError:
    try:
        import lupa.lua54 as lupa
    except ImportError:
        try:
            import lupa.lua53 as lupa
        except ImportError:
            import lupa

print(f"Using {lupa.LuaRuntime().lua_implementation} (compiled with {lupa.LUA_VERSION})")

Examples

>>> from lupa.lua54 import LuaRuntime
>>> lua = LuaRuntime(unpack_returned_tuples=True)

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

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

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

>>> lua.eval('python.eval(" 2 ** 2 ")') == 4
True
>>> lua.eval('python.builtins.str(4)') == '4'
True

The function lua_type(obj) can be used to find out the type of a wrapped Lua object in Python code, as provided by Lua’s type() function:

>>> lupa.lua_type(lua_func)
'function'
>>> lupa.lua_type(lua.eval('{}'))
'table'

To help in distinguishing between wrapped Lua objects and normal Python objects, it returns None for the latter:

>>> lupa.lua_type(123) is None
True
>>> lupa.lua_type('abc') is None
True
>>> lupa.lua_type({}) is None
True

Note the flag unpack_returned_tuples=True that is passed to create the Lua runtime. It is new in Lupa 0.21 and changes the behaviour of tuples that get returned by Python functions. With this flag, they explode into separate Lua values:

>>> lua.execute('a,b,c = python.eval("(1,2)")')
>>> g = lua.globals()
>>> g.a
1
>>> g.b
2
>>> g.c is None
True

When set to False, functions that return a tuple pass it through to the Lua code:

>>> non_explode_lua = lupa.LuaRuntime(unpack_returned_tuples=False)
>>> non_explode_lua.execute('a,b,c = python.eval("(1,2)")')
>>> g = non_explode_lua.globals()
>>> g.a
(1, 2)
>>> g.b is None
True
>>> g.c is None
True

Since the default behaviour (to not explode tuples) might change in a later version of Lupa, it is best to always pass this flag explicitly.

Python objects in Lua

Python objects are either converted when passed into Lua (e.g. numbers and strings) or passed as wrapped object references.

>>> wrapped_type = lua.globals().type     # Lua's own type() function
>>> wrapped_type(1) == 'number'
True
>>> wrapped_type('abc') == 'string'
True

Wrapped Lua objects get unwrapped when they are passed back into Lua, and arbitrary Python objects get wrapped in different ways:

>>> wrapped_type(wrapped_type) == 'function'  # unwrapped Lua function
True
>>> wrapped_type(len) == 'userdata'       # wrapped Python function
True
>>> wrapped_type([]) == 'userdata'        # wrapped Python object
True

Lua supports two main protocols on objects: calling and indexing. It does not distinguish between attribute access and item access like Python does, so the Lua operations obj[x] and obj.x both map to indexing. To decide which Python protocol to use for Lua wrapped objects, Lupa employs a simple heuristic.

Pratically all Python objects allow attribute access, so if the object also has a __getitem__ method, it is preferred when turning it into an indexable Lua object. Otherwise, it becomes a simple object that uses attribute access for indexing from inside Lua.

Obviously, this heuristic will fail to provide the required behaviour in many cases, e.g. when attribute access is required to an object that happens to support item access. To be explicit about the protocol that should be used, Lupa provides the helper functions as_attrgetter() and as_itemgetter() that restrict the view on an object to a certain protocol, both from Python and from inside Lua:

>>> lua_func = lua.eval('function(obj) return obj["get"] end')
>>> d = {'get' : 'value'}

>>> value = lua_func(d)
>>> value == d['get'] == 'value'
True

>>> value = lua_func( lupa.as_itemgetter(d) )
>>> value == d['get'] == 'value'
True

>>> dict_get = lua_func( lupa.as_attrgetter(d) )
>>> dict_get == d.get
True
>>> dict_get('get') == d.get('get') == 'value'
True

>>> lua_func = lua.eval(
...     'function(obj) return python.as_attrgetter(obj)["get"] end')
>>> dict_get = lua_func(d)
>>> dict_get('get') == d.get('get') == 'value'
True

Note that unlike Lua function objects, callable Python objects support indexing in Lua:

>>> def py_func(): pass
>>> py_func.ATTR = 2

>>> lua_func = lua.eval('function(obj) return obj.ATTR end')
>>> lua_func(py_func)
2
>>> lua_func = lua.eval(
...     'function(obj) return python.as_attrgetter(obj).ATTR end')
>>> lua_func(py_func)
2
>>> lua_func = lua.eval(
...     'function(obj) return python.as_attrgetter(obj)["ATTR"] end')
>>> lua_func(py_func)
2

Iteration in Lua

Iteration over Python objects from Lua’s for-loop is fully supported. However, Python iterables need to be converted using one of the utility functions which are described here. This is similar to the functions like pairs() in Lua.

To iterate over a plain Python iterable, use the python.iter() function. For example, you can manually copy a Python list into a Lua table like this:

>>> lua_copy = lua.eval('''
...     function(L)
...         local t, i = {}, 1
...         for item in python.iter(L) do
...             t[i] = item
...             i = i + 1
...         end
...         return t
...     end
... ''')

>>> table = lua_copy([1,2,3,4])
>>> len(table)
4
>>> table[1]   # Lua indexing
1

Python’s enumerate() function is also supported, so the above could be simplified to:

>>> lua_copy = lua.eval('''
...     function(L)
...         local t = {}
...         for index, item in python.enumerate(L) do
...             t[ index+1 ] = item
...         end
...         return t
...     end
... ''')

>>> table = lua_copy([1,2,3,4])
>>> len(table)
4
>>> table[1]   # Lua indexing
1

For iterators that return tuples, such as dict.iteritems(), it is convenient to use the special python.iterex() function that automatically explodes the tuple items into separate Lua arguments:

>>> lua_copy = lua.eval('''
...     function(d)
...         local t = {}
...         for key, value in python.iterex(d.items()) do
...             t[key] = value
...         end
...         return t
...     end
... ''')

>>> d = dict(a=1, b=2, c=3)
>>> table = lua_copy( lupa.as_attrgetter(d) )
>>> table['b']
2

Note that accessing the d.items method from Lua requires passing the dict as attrgetter. Otherwise, attribute access in Lua would use the getitem protocol of Python dicts and look up d['items'] instead.

None vs. nil

While None in Python and nil in Lua differ in their semantics, they usually just mean the same thing: no value. Lupa therefore tries to map one directly to the other whenever possible:

>>> lua.eval('nil') is None
True
>>> is_nil = lua.eval('function(x) return x == nil end')
>>> is_nil(None)
True

The only place where this cannot work is during iteration, because Lua considers a nil value the termination marker of iterators. Therefore, Lupa special cases None values here and replaces them by a constant python.none instead of returning nil:

>>> _ = lua.require("table")
>>> func = lua.eval('''
...     function(items)
...         local t = {}
...         for value in python.iter(items) do
...             table.insert(t, value == python.none)
...         end
...         return t
...     end
... ''')

>>> items = [1, None ,2]
>>> list(func(items).values())
[False, True, False]

Lupa avoids this value escaping whenever it’s obviously not necessary. Thus, when unpacking tuples during iteration, only the first value will be subject to python.none replacement, as Lua does not look at the other items for loop termination anymore. And on enumerate() iteration, the first value is known to be always a number and never None, so no replacement is needed.

>>> func = lua.eval('''
...     function(items)
...         for a, b, c, d in python.iterex(items) do
...             return {a == python.none, a == nil,   -->  a == python.none
...                     b == python.none, b == nil,   -->  b == nil
...                     c == python.none, c == nil,   -->  c == nil
...                     d == python.none, d == nil}   -->  d == nil ...
...         end
...     end
... ''')

>>> items = [(None, None, None, None)]
>>> list(func(items).values())
[True, False, False, True, False, True, False, True]

>>> items = [(None, None)]   # note: no values for c/d => nil in Lua
>>> list(func(items).values())
[True, False, False, True, False, True, False, True]

Note that this behaviour changed in Lupa 1.0. Previously, the python.none replacement was done in more places, which made it not always very predictable.

Lua Tables

Lua tables mimic Python’s mapping protocol. For the special case of array tables, Lua automatically inserts integer indices as keys into the table. Therefore, indexing starts from 1 as in Lua instead of 0 as in Python. For the same reason, negative indexing does not work. It is best to think of Lua tables as mappings rather than arrays, even for plain array tables.

>>> table = lua.eval('{10,20,30,40}')
>>> table[1]
10
>>> table[4]
40
>>> list(table)
[1, 2, 3, 4]
>>> dict(table)
{1: 10, 2: 20, 3: 30, 4: 40}
>>> list(table.values())
[10, 20, 30, 40]
>>> len(table)
4

>>> mapping = lua.eval('{ [1] = -1 }')
>>> list(mapping)
[1]

>>> mapping = lua.eval('{ [20] = -20; [3] = -3 }')
>>> mapping[20]
-20
>>> mapping[3]
-3
>>> sorted(mapping.values())
[-20, -3]
>>> sorted(mapping.items())
[(3, -3), (20, -20)]

>>> mapping[-3] = 3     # -3 used as key, not index!
>>> mapping[-3]
3
>>> sorted(mapping)
[-3, 3, 20]
>>> sorted(mapping.items())
[(-3, 3), (3, -3), (20, -20)]

To simplify the table creation from Python, the LuaRuntime comes with a helper method that creates a Lua table from Python arguments:

>>> t = lua.table(10, 20, 30, 40)
>>> lupa.lua_type(t)
'table'
>>> list(t)
[1, 2, 3, 4]
>>> list(t.values())
[10, 20, 30, 40]

>>> t = lua.table(10, 20, 30, 40, a=1, b=2)
>>> t[3]
30
>>> t['b']
2

A second helper method, .table_from(), was added in Lupa 1.1 and accepts any number of mappings and sequences/iterables as arguments. It collects all values and key-value pairs and builds a single Lua table from them. Any keys that appear in multiple mappings get overwritten with their last value (going from left to right).

>>> t = lua.table_from([10, 20, 30], {'a': 11, 'b': 22}, (40, 50), {'b': 42})
>>> t['a']
11
>>> t['b']
42
>>> t[5]
50
>>> sorted(t.values())
[10, 11, 20, 30, 40, 42, 50]

Since Lupa 2.1, passing recursive=True will map data structures recursively to Lua tables.

>>> t = lua.table_from(
...     [
...         # t1:
...         [
...             [10, 20, 30],
...             {'a': 11, 'b': 22}
...         ],
...         # t2:
...         [
...             (40, 50),
...             {'b': 42}
...         ]
...     ],
...     recursive=True
... )
>>> t1, t2 = t.values()
>>> list(t1[1].values())
[10, 20, 30]
>>> t1[2]['a']
11
>>> t1[2]['b']
22
>>> t2[2]['b']
42
>>> list(t1[1].values())
[10, 20, 30]
>>> list(t2[1].values())
[40, 50]

A lookup of non-existing keys or indices returns None (actually nil inside of Lua). A lookup is therefore more similar to the .get() method of Python dicts than to a mapping lookup in Python.

>>> table = lua.table(10, 20, 30, 40)
>>> table[1000000] is None
True
>>> table['no such key'] is None
True

>>> mapping = lua.eval('{ [20] = -20; [3] = -3 }')
>>> mapping['no such key'] is None
True

Note that len() does the right thing for array tables but does not work on mappings:

>>> len(table)
4
>>> len(mapping)
0

This is because len() is based on the # (length) operator in Lua and because of the way Lua defines the length of a table. Remember that unset table indices always return nil, including indices outside of the table size. Thus, Lua basically looks for an index that returns nil and returns the index before that. This works well for array tables that do not contain nil values, gives barely predictable results for tables with ‘holes’ and does not work at all for mapping tables. For tables with both sequential and mapping content, this ignores the mapping part completely.

Note that it is best not to rely on the behaviour of len() for mappings. It might change in a later version of Lupa.

Similar to the table interface provided by Lua, Lupa also supports attribute access to table members:

>>> table = lua.eval('{ a=1, b=2 }')
>>> table.a, table.b
(1, 2)
>>> table.a == table['a']
True

This enables access to Lua ‘methods’ that are associated with a table, as used by the standard library modules:

>>> string = lua.eval('string')    # get the 'string' library table
>>> print( string.lower('A') )
a

Python Callables

As discussed earlier, Lupa allows Lua scripts to call Python functions and methods:

>>> def add_one(num):
...     return num + 1
>>> lua_func = lua.eval('function(num, py_func) return py_func(num) end')
>>> lua_func(48, add_one)
49

>>> class MyClass():
...     def my_method(self):
...         return 345
>>> obj = MyClass()
>>> lua_func = lua.eval('function(py_obj) return py_obj:my_method() end')
>>> lua_func(obj)
345

Lua doesn’t have a dedicated syntax for named arguments, so by default Python callables can only be called using positional arguments.

A common pattern for implementing named arguments in Lua is passing them in a table as the first and only function argument. See http://lua-users.org/wiki/NamedParameters for more details. Lupa supports this pattern by providing two decorators: lupa.unpacks_lua_table for Python functions and lupa.unpacks_lua_table_method for methods of Python objects.

Python functions/methods wrapped in these decorators can be called from Lua code as func(foo, bar), func{foo=foo, bar=bar} or func{foo, bar=bar}. Example:

>>> @lupa.unpacks_lua_table
... def add(a, b):
...     return a + b
>>> lua_func = lua.eval('function(a, b, py_func) return py_func{a=a, b=b} end')
>>> lua_func(5, 6, add)
11
>>> lua_func = lua.eval('function(a, b, py_func) return py_func{a, b=b} end')
>>> lua_func(5, 6, add)
11

If you do not control the function implementation, you can also just manually wrap a callable object when passing it into Lupa:

>>> import operator
>>> wrapped_py_add = lupa.unpacks_lua_table(operator.add)

>>> lua_func = lua.eval('function(a, b, py_func) return py_func{a, b} end')
>>> lua_func(5, 6, wrapped_py_add)
11

There are some limitations:

  1. Avoid using lupa.unpacks_lua_table and lupa.unpacks_lua_table_method for functions where the first argument can be a Lua table. In this case py_func{foo=bar} (which is the same as py_func({foo=bar}) in Lua) becomes ambiguous: it could mean either “call py_func with a named foo argument” or “call py_func with a positional {foo=bar} argument”.

  2. One should be careful with passing nil values to callables wrapped in lupa.unpacks_lua_table or lupa.unpacks_lua_table_method decorators. Depending on the context, passing nil as a parameter can mean either “omit a parameter” or “pass None”. This even depends on the Lua version.

    It is possible to use python.none instead of nil to pass None values robustly. Arguments with nil values are also fine when standard braces func(a, b, c) syntax is used.

Because of these limitations lupa doesn’t enable named arguments for all Python callables automatically. Decorators allow to enable named arguments on a per-callable basis.

Lua Coroutines

The next is an example of Lua coroutines. A wrapped Lua coroutine behaves exactly like a Python coroutine. It needs to get created at the beginning, either by using the .coroutine() method of a function or by creating it in Lua code. Then, values can be sent into it using the .send() method or it can be iterated over. Note that the .throw() method is not supported, though.

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

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

An example where values are passed into the coroutine using its .send() method:

>>> lua_code = '''\
...     function()
...         local t,i = {},0
...         local value = coroutine.yield()
...         while value do
...             t[i] = value
...             i = i + 1
...             value = coroutine.yield()
...         end
...         return t
...     end
... '''
>>> f = lua.eval(lua_code)

>>> co = f.coroutine()   # create coroutine
>>> co.send(None)        # start coroutine (stops at first yield)

>>> for i in range(3):
...     co.send(i*2)

>>> mapping = co.send(None)   # loop termination signal
>>> sorted(mapping.items())
[(0, 0), (1, 2), (2, 4)]

It also works to create coroutines in Lua and to pass them back into Python space:

>>> lua_code = '''\
...   function f(N)
...         for i=0,N do
...             coroutine.yield( i%2 )
...         end
...   end ;
...   co1 = coroutine.create(f) ;
...   co2 = coroutine.create(f) ;
...
...   status, first_result = coroutine.resume(co2, 2) ;   -- starting!
...
...   return f, co1, co2, status, first_result
... '''

>>> lua = LuaRuntime()
>>> f, co, lua_gen, status, first_result = lua.execute(lua_code)

>>> # a running coroutine:

>>> status
True
>>> first_result
0
>>> list(lua_gen)
[1, 0]
>>> list(lua_gen)
[]

>>> # an uninitialised coroutine:

>>> gen = co(4)
>>> list(enumerate(gen))
[(0, 0), (1, 1), (2, 0), (3, 1), (4, 0)]

>>> gen = co(2)
>>> list(enumerate(gen))
[(0, 0), (1, 1), (2, 0)]

>>> # a plain function:

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

Threading

The following example calculates a mandelbrot image in parallel threads and displays the result in PIL. It is based on a benchmark implementation for the Computer Language Benchmarks Game.

lua_code = '''\
    function(N, i, total)
        local char, unpack = string.char, table.unpack
        local result = ""
        local M, ba, bb, buf = 2/N, 2^(N%8+1)-1, 2^(8-N%8), {}
        local start_line, end_line = N/total * (i-1), N/total * i - 1
        for y=start_line,end_line do
            local Ci, b, p = y*M-1, 1, 0
            for x=0,N-1 do
                local Cr = x*M-1.5
                local Zr, Zi, Zrq, Ziq = Cr, Ci, Cr*Cr, Ci*Ci
                b = b + b
                for i=1,49 do
                    Zi = Zr*Zi*2 + Ci
                    Zr = Zrq-Ziq + Cr
                    Ziq = Zi*Zi
                    Zrq = Zr*Zr
                    if Zrq+Ziq > 4.0 then b = b + 1; break; end
                end
                if b >= 256 then p = p + 1; buf[p] = 511 - b; b = 1; end
            end
            if b ~= 1 then p = p + 1; buf[p] = (ba-b)*bb; end
            result = result .. char(unpack(buf, 1, p))
        end
        return result
    end
'''

image_size = 1280   # == 1280 x 1280
thread_count = 8

from lupa import LuaRuntime
lua_funcs = [ LuaRuntime(encoding=None).eval(lua_code)
              for _ in range(thread_count) ]

results = [None] * thread_count
def mandelbrot(i, lua_func):
    results[i] = lua_func(image_size, i+1, thread_count)

import threading
threads = [ threading.Thread(target=mandelbrot, args=(i,lua_func))
            for i, lua_func in enumerate(lua_funcs) ]
for thread in threads:
    thread.start()
for thread in threads:
    thread.join()

result_buffer = b''.join(results)

# use Pillow to display the image
from PIL import Image
image = Image.frombytes('1', (image_size, image_size), result_buffer)
image.show()

Note how the example creates a separate LuaRuntime for each thread to enable parallel execution. Each LuaRuntime is protected by a global lock that prevents concurrent access to it. The low memory footprint of Lua makes it reasonable to use multiple runtimes, but this setup also means that values cannot easily be exchanged between threads inside of Lua. They must either get copied through Python space (passing table references will not work, either) or use some Lua mechanism for explicit communication, such as a pipe or some kind of shared memory setup.

Restricting Lua access to Python objects

Lupa provides a simple mechanism to control access to Python objects. Each attribute access can be passed through a filter function as follows:

>>> def filter_attribute_access(obj, attr_name, is_setting):
...     if isinstance(attr_name, unicode):
...         if not attr_name.startswith('_'):
...             return attr_name
...     raise AttributeError('access denied')

>>> lua = lupa.LuaRuntime(
...           register_eval=False,
...           attribute_filter=filter_attribute_access)
>>> func = lua.eval('function(x) return x.__class__ end')
>>> func(lua)
Traceback (most recent call last):
 ...
AttributeError: access denied

The is_setting flag indicates whether the attribute is being read or set.

Note that the attributes of Python functions provide access to the current globals() and therefore to the builtins etc. If you want to safely restrict access to a known set of Python objects, it is best to work with a whitelist of safe attribute names. One way to do that could be to use a well selected list of dedicated API objects that you provide to Lua code, and to only allow Python attribute access to the set of public attribute/method names of these objects.

Since Lupa 1.0, you can alternatively provide dedicated getter and setter function implementations for a LuaRuntime:

>>> def getter(obj, attr_name):
...     if attr_name == 'yes':
...         return getattr(obj, attr_name)
...     raise AttributeError(
...         'not allowed to read attribute "%s"' % attr_name)

>>> def setter(obj, attr_name, value):
...     if attr_name == 'put':
...         setattr(obj, attr_name, value)
...         return
...     raise AttributeError(
...         'not allowed to write attribute "%s"' % attr_name)

>>> class X:
...     yes = 123
...     put = 'abc'
...     noway = 2.1

>>> x = X()

>>> lua = lupa.LuaRuntime(attribute_handlers=(getter, setter))
>>> func = lua.eval('function(x) return x.yes end')
>>> func(x)  # getting 'yes'
123
>>> func = lua.eval('function(x) x.put = "ABC"; end')
>>> func(x)  # setting 'put'
>>> print(x.put)
ABC
>>> func = lua.eval('function(x) x.noway = 42; end')
>>> func(x)  # setting 'noway'
Traceback (most recent call last):
 ...
AttributeError: not allowed to write attribute "noway"

Restricting Lua Memory Usage

Lupa provides a simple mechanism to control the maximum memory usage of the Lua Runtime since version 2.0. By default Lupa does not interfere with Lua’s memory allocation, to opt-in you must set the max_memory when creating the LuaRuntime.

The LuaRuntime provides three methods for controlling and reading the memory usage:

  1. get_memory_used(total=False) to get the current memory usage of the LuaRuntime.

  2. get_max_memory(total=False) to get the current memory limit. 0 means there is no memory limitation.

  3. set_max_memory(max_memory, total=False) to change the memory limit. Values below or equal to 0 mean no limit.

There is always some memory used by the LuaRuntime itself (around ~20KiB, depending on your lua version and other factors) which is excluded from all calculations unless you specify total=True.

>>> from lupa import lua52
>>> lua = lua52.LuaRuntime(max_memory=0)  # 0 for unlimited, default is None
>>> lua.get_memory_used()  # memory used by your code
0
>>> total_lua_memory = lua.get_memory_used(total=True)  # includes memory used by the runtime itself
>>> assert total_lua_memory > 0  # exact amount depends on your lua version and other factors

Lua code hitting the memory limit will receive memory errors:

>>> lua.set_max_memory(100)
>>> lua.eval("string.rep('a', 1000)")   # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
 ...
lupa.LuaMemoryError: not enough memory

LuaMemoryError inherits from LuaError and MemoryError.

Importing Lua binary modules

This will usually work as is, but here are the details, in case anything goes wrong for you.

To use binary modules in Lua, you need to compile them against the header files of the LuaJIT sources that you used to build Lupa, but do not link them against the LuaJIT library.

Furthermore, CPython needs to enable global symbol visibility for shared libraries before loading the Lupa module. This can be done by calling sys.setdlopenflags(flag_values). Importing the lupa module will automatically try to set up the correct dlopen flags if it can find the platform specific DLFCN Python module that defines the necessary flag constants. In that case, using binary modules in Lua should work out of the box.

If this setup fails, however, you have to set the flags manually. When using the above configuration call, the argument flag_values must represent the sum of your system’s values for RTLD_NEW and RTLD_GLOBAL. If RTLD_NEW is 2 and RTLD_GLOBAL is 256, you need to call sys.setdlopenflags(258).

Assuming that the Lua luaposix (posix) module is available, the following should work on a Linux system:

>>> import sys
>>> orig_dlflags = sys.getdlopenflags()
>>> sys.setdlopenflags(258)
>>> import lupa
>>> sys.setdlopenflags(orig_dlflags)

>>> lua = lupa.LuaRuntime()
>>> posix_module = lua.require('posix')     # doctest: +SKIP

Building with different Lua versions

The build is configured to automatically search for an installed version of first LuaJIT and then Lua, and failing to find either, to use the bundled LuaJIT or Lua version.

If you wish to build Lupa with a specific version of Lua, you can configure the following options on setup:

Option

Description

--lua-lib <libfile>

Lua library file path, e.g. --lua-lib /usr/local/lib/lualib.a

--lua-includes <incdir>

Lua include directory, e.g. --lua-includes /usr/local/include

--use-bundle

Use bundled LuaJIT or Lua instead of searching for an installed version.

--no-bundle

Don’t use the bundled LuaJIT/Lua, search for an installed version of LuaJIT or Lua, e.g. using pkg-config.

--no-lua-jit

Don’t use or search for LuaJIT, only use or search Lua instead.

Installing lupa

Building with LuaJIT2

  1. Download and unpack lupa

    http://pypi.python.org/pypi/lupa

  2. Download LuaJIT2

    http://luajit.org/download.html

  3. Unpack the archive into the lupa base directory, e.g.:

    .../lupa-0.1/LuaJIT-2.0.2
  4. Build LuaJIT:

    cd LuaJIT-2.0.2
    make
    cd ..

    If you need specific C compiler flags, pass them to make as follows:

    make CFLAGS="..."

    For trickier target platforms like Windows and MacOS-X, please see the official installation instructions for LuaJIT.

    NOTE: When building on Windows, make sure that lua51.lib is made in addition to lua51.dll. The MSVC build produces this file, MinGW does NOT.

  5. Build lupa:

    python setup.py build_ext -i

    Or any other distutils target of your choice, such as build or one of the bdist targets. See the distutils documentation for help, also the hints on building extension modules.

    Note that on 64bit MacOS-X installations, the following additional compiler flags are reportedly required due to the embedded LuaJIT:

    -pagezero_size 10000 -image_base 100000000

    You can find additional installation hints for MacOS-X in this somewhat unclear blog post, which may or may not tell you at which point in the installation process to provide these flags.

    Also, on 64bit MacOS-X, you will typically have to set the environment variable ARCHFLAGS to make sure it only builds for your system instead of trying to generate a fat binary with both 32bit and 64bit support:

    export ARCHFLAGS="-arch x86_64"

    Note that this applies to both LuaJIT and Lupa, so make sure you try a clean build of everything if you forgot to set it initially.

Building with Lua 5.x

It also works to use Lupa with the standard (non-JIT) Lua runtime. The easiest way is to use the bundled lua submodule:

  1. Clone the submodule:

    $ git submodule update --init third-party/lua
  2. Build Lupa:

    $ python3 setup.py bdist_wheel --use-bundle --with-cython

You can also build it by installing a Lua 5.x package, including any development packages (header files etc.). On systems that use the “pkg-config” configuration mechanism, Lupa’s setup.py will pick up either LuaJIT2 or Lua automatically, with a preference for LuaJIT2 if it is found. Pass the --no-luajit option to the setup.py script if you have both installed but do not want to use LuaJIT2.

On other systems, you may have to supply the build parameters externally, e.g. using environment variables or by changing the setup.py script manually. Pass the --no-luajit option to the setup.py script in order to ignore the failure you get when neither LuaJIT2 nor Lua are found automatically.

For further information, read this mailing list post:

https://www.freelists.org/post/lupa-dev/Lupa-with-normal-Lua-interpreter-Lua-51,2

Installing lupa from packages

Debian/Ubuntu + Lua 5.2

  1. Install Lua 5.2 development package:

    $ apt-get install liblua5.2-dev
  2. Install lupa:

    $ pip install lupa

Debian/Ubuntu + LuaJIT2

  1. Install LuaJIT2 development package:

    $ apt-get install libluajit-5.1-dev
  2. Install lupa:

    $ pip install lupa

Depending on OS version, you might get an older LuaJIT2 version.

OS X + Lua 5.2 + Homebrew

  1. Install Lua:

    $ brew install lua
  2. Install pkg-config:

    $ brew install pkg-config
  3. Install lupa:

    $ pip install lupa

Lupa change log

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.

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.

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.

2.2 (2024-06-02)

  • 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.

2.1 (2024-03-24)

  • 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.

2.0 (2023-04-03)

  • 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.

1.14.1 (2022-11-16)

  • Rebuild with Cython 0.29.32 to support Python 3.11.

1.13 (2022-03-01)

  • Bundled Lua source files were missing in the source distribution.

1.12 (2022-02-24)

  • 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.

1.11 (2022-02-23)

  • Use Lua 5.4.4 in binary wheels and as bundled Lua.

  • Built with Cython 0.29.28 to support Python 3.10/11.

1.10 (2021-09-02)

  • 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.

1.9 (2019-12-21)

  • 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.

1.8 (2019-02-01)

  • GH#107: Fix a deprecated import in Py3.

  • Built with Cython 0.29.3 for better Py3.7 compatibility.

1.7 (2018-08-06)

  • GH#103: Provide wheels for MS Windows and fix MSVC build on Py2.7.

1.6 (2017-12-15)

  • GH#95: Improved compatibility with Lua 5.3. (patch by TitanSnow)

1.5 (2017-09-16)

  • 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.

1.4 (2016-12-10)

  • 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

1.3 (2016-04-12)

  • 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

1.2 (2015-10-10)

  • 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

1.1 (2014-11-21)

  • 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

1.0.1 (2014-10-11)

  • 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

1.0 (2014-09-28)

  • 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)

0.21 (2014-02-12)

  • 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

0.20 (2011-05-22)

  • 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

0.19 (2011-03-06)

  • fix serious resource leak when creating multiple LuaRuntime instances

  • portability fix for binary module importing

0.18 (2010-11-06)

  • 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

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.

  • 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.

0.16 (2010-09-03)

  • 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

0.15 (2010-09-02)

  • support for loading binary Lua modules on systems that support it

0.14 (2010-08-31)

  • relicensed to the MIT license used by LuaJIT2 to simplify licensing considerations

0.13.1 (2010-08-30)

  • fix Cython generated C file using Cython 0.13

0.13 (2010-08-29)

  • 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

0.12 (2010-08-16)

  • fix Lua stack leak during table iteration

  • fix lost Lua object reference after iteration

0.11 (2010-08-07)

  • 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

0.10 (2010-07-27)

0.9 (2010-07-23)

  • 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.

0.8 (2010-07-21)

  • 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)

0.7 (2010-07-18)

  • 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

0.6 (2010-07-18)

  • Python iteration support for Lua objects (e.g. tables)

  • threading fixes

  • fix compile warnings

0.5 (2010-07-14)

  • explicit encoding options per LuaRuntime instance to decode/encode strings and Lua code

0.4 (2010-07-14)

  • 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

0.3 (2010-07-13)

  • fix several threading issues

  • safely free the GIL when calling into Lua

0.2 (2010-07-13)

  • propagate Python exceptions through Lua calls

0.1 (2010-07-12)

  • first public release

License

Lupa

Copyright (c) 2010-2017 Stefan Behnel. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Lua

(See https://www.lua.org/license.html)

Copyright © 1994–2017 Lua.org, PUC-Rio.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lupa-2.5.tar.gz (7.2 MB view details)

Uploaded Source

Built Distributions

lupa-2.5-cp313-cp313-win_amd64.whl (1.7 MB view details)

Uploaded CPython 3.13Windows x86-64

lupa-2.5-cp313-cp313-win32.whl (1.4 MB view details)

Uploaded CPython 3.13Windows x86

lupa-2.5-cp313-cp313-musllinux_1_2_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

lupa-2.5-cp313-cp313-musllinux_1_2_i686.whl (1.2 MB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ i686

lupa-2.5-cp313-cp313-musllinux_1_2_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ ARM64

lupa-2.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (2.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

lupa-2.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (1.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

lupa-2.5-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl (1.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.12+ i686manylinux: glibc 2.17+ i686

lupa-2.5-cp313-cp313-macosx_11_0_x86_64.whl (965.2 kB view details)

Uploaded CPython 3.13macOS 11.0+ x86-64

lupa-2.5-cp313-cp313-macosx_11_0_universal2.whl (1.8 MB view details)

Uploaded CPython 3.13macOS 11.0+ universal2 (ARM64, x86-64)

lupa-2.5-cp313-cp313-macosx_11_0_arm64.whl (897.9 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

lupa-2.5-cp312-cp312-win_amd64.whl (1.7 MB view details)

Uploaded CPython 3.12Windows x86-64

lupa-2.5-cp312-cp312-win32.whl (1.4 MB view details)

Uploaded CPython 3.12Windows x86

lupa-2.5-cp312-cp312-musllinux_1_2_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

lupa-2.5-cp312-cp312-musllinux_1_2_i686.whl (1.2 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ i686

lupa-2.5-cp312-cp312-musllinux_1_2_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ ARM64

lupa-2.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (2.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

lupa-2.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (1.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

lupa-2.5-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl (1.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.12+ i686manylinux: glibc 2.17+ i686

lupa-2.5-cp312-cp312-macosx_11_0_x86_64.whl (970.6 kB view details)

Uploaded CPython 3.12macOS 11.0+ x86-64

lupa-2.5-cp312-cp312-macosx_11_0_universal2.whl (1.9 MB view details)

Uploaded CPython 3.12macOS 11.0+ universal2 (ARM64, x86-64)

lupa-2.5-cp312-cp312-macosx_11_0_arm64.whl (902.0 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

lupa-2.5-cp311-cp311-win_amd64.whl (1.7 MB view details)

Uploaded CPython 3.11Windows x86-64

lupa-2.5-cp311-cp311-win32.whl (1.4 MB view details)

Uploaded CPython 3.11Windows x86

lupa-2.5-cp311-cp311-musllinux_1_2_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

lupa-2.5-cp311-cp311-musllinux_1_2_i686.whl (1.2 MB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ i686

lupa-2.5-cp311-cp311-musllinux_1_2_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ ARM64

lupa-2.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (2.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

lupa-2.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

lupa-2.5-cp311-cp311-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl (1.2 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.12+ i686manylinux: glibc 2.17+ i686

lupa-2.5-cp311-cp311-macosx_11_0_x86_64.whl (973.4 kB view details)

Uploaded CPython 3.11macOS 11.0+ x86-64

lupa-2.5-cp311-cp311-macosx_11_0_universal2.whl (1.9 MB view details)

Uploaded CPython 3.11macOS 11.0+ universal2 (ARM64, x86-64)

lupa-2.5-cp311-cp311-macosx_11_0_arm64.whl (919.6 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

lupa-2.5-cp310-cp310-win_amd64.whl (1.7 MB view details)

Uploaded CPython 3.10Windows x86-64

lupa-2.5-cp310-cp310-win32.whl (1.4 MB view details)

Uploaded CPython 3.10Windows x86

lupa-2.5-cp310-cp310-musllinux_1_2_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ x86-64

lupa-2.5-cp310-cp310-musllinux_1_2_i686.whl (1.2 MB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ i686

lupa-2.5-cp310-cp310-musllinux_1_2_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ ARM64

lupa-2.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (2.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

lupa-2.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

lupa-2.5-cp310-cp310-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl (1.2 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.12+ i686manylinux: glibc 2.17+ i686

lupa-2.5-cp310-cp310-macosx_11_0_x86_64.whl (964.3 kB view details)

Uploaded CPython 3.10macOS 11.0+ x86-64

lupa-2.5-cp310-cp310-macosx_11_0_universal2.whl (1.9 MB view details)

Uploaded CPython 3.10macOS 11.0+ universal2 (ARM64, x86-64)

lupa-2.5-cp310-cp310-macosx_11_0_arm64.whl (909.2 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

lupa-2.5-cp39-cp39-win_amd64.whl (1.7 MB view details)

Uploaded CPython 3.9Windows x86-64

lupa-2.5-cp39-cp39-win32.whl (1.4 MB view details)

Uploaded CPython 3.9Windows x86

lupa-2.5-cp39-cp39-musllinux_1_2_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.9musllinux: musl 1.2+ x86-64

lupa-2.5-cp39-cp39-musllinux_1_2_i686.whl (1.2 MB view details)

Uploaded CPython 3.9musllinux: musl 1.2+ i686

lupa-2.5-cp39-cp39-musllinux_1_2_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.9musllinux: musl 1.2+ ARM64

lupa-2.5-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (2.1 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

lupa-2.5-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

lupa-2.5-cp39-cp39-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl (1.2 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.12+ i686manylinux: glibc 2.17+ i686

lupa-2.5-cp39-cp39-macosx_11_0_x86_64.whl (965.0 kB view details)

Uploaded CPython 3.9macOS 11.0+ x86-64

lupa-2.5-cp39-cp39-macosx_11_0_universal2.whl (1.9 MB view details)

Uploaded CPython 3.9macOS 11.0+ universal2 (ARM64, x86-64)

lupa-2.5-cp39-cp39-macosx_11_0_arm64.whl (910.6 kB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

lupa-2.5-cp38-cp38-win_amd64.whl (1.7 MB view details)

Uploaded CPython 3.8Windows x86-64

lupa-2.5-cp38-cp38-win32.whl (1.4 MB view details)

Uploaded CPython 3.8Windows x86

lupa-2.5-cp38-cp38-musllinux_1_2_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.8musllinux: musl 1.2+ x86-64

lupa-2.5-cp38-cp38-musllinux_1_2_i686.whl (1.2 MB view details)

Uploaded CPython 3.8musllinux: musl 1.2+ i686

lupa-2.5-cp38-cp38-musllinux_1_2_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.8musllinux: musl 1.2+ ARM64

lupa-2.5-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (2.1 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

lupa-2.5-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (1.0 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

lupa-2.5-cp38-cp38-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl (1.1 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.12+ i686manylinux: glibc 2.17+ i686

lupa-2.5-cp38-cp38-macosx_11_0_x86_64.whl (970.3 kB view details)

Uploaded CPython 3.8macOS 11.0+ x86-64

lupa-2.5-cp38-cp38-macosx_11_0_arm64.whl (917.5 kB view details)

Uploaded CPython 3.8macOS 11.0+ ARM64

File details

Details for the file lupa-2.5.tar.gz.

File metadata

  • Download URL: lupa-2.5.tar.gz
  • Upload date:
  • Size: 7.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5.tar.gz
Algorithm Hash digest
SHA256 69c6a89f2b7b08a3040d7ed2a1eeccba37a31ddc92fa199339c53a2ae3c48c34
MD5 8f526b7d1757424803599fa5f040a085
BLAKE2b-256 d5514e20b597795b58f840289042d87d65f0e33cdc73653a4c1c7026346e1725

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: lupa-2.5-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 e8d52999947d3d09c1dd2cf572cfb90a0ced3185f702e75f4b1a3ba4276b3c97
MD5 916e166e5e21c667af7c251ad7f3a68e
BLAKE2b-256 5d389572b19463ee5aebcb4a503dee7d9f908179ee1b80e6dfc21300b156ee04

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp313-cp313-win32.whl.

File metadata

  • Download URL: lupa-2.5-cp313-cp313-win32.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.13, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp313-cp313-win32.whl
Algorithm Hash digest
SHA256 1ea65fb8046bf2c7cf39dfb3677ce5e25d5ea1330e7f9bce9b274fcdf55db29b
MD5 02991e2c5ec64f53bcd59b3f5759f47b
BLAKE2b-256 6c8afedac88be2af4bdf7e981d9eecfb2defe612004a22fb745978f68d9ddbee

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp313-cp313-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp313-cp313-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 2.2 MB
  • Tags: CPython 3.13, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 2a848ed378fbfcf735780116265bd2e68600691efefb4f7ff326a4ac089189d5
MD5 f5f57a10fb9e3af3a077263ef1aa53c1
BLAKE2b-256 d33aadebc756f088416c276359978a982a00b755aa3f23def7f7f6ec1d023105

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp313-cp313-musllinux_1_2_i686.whl.

File metadata

  • Download URL: lupa-2.5-cp313-cp313-musllinux_1_2_i686.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.13, musllinux: musl 1.2+ i686
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp313-cp313-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 5a9c12e74faaea60ae50a6d2670eb7e7cfc0b036045912bb37a15753a702fc28
MD5 8026ee0a1232caf5108419a88b7a3dc9
BLAKE2b-256 37f49f5fb25df939408bac4b088c1ca42c96fb1606ac40aa1c6c28cc9f43e585

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp313-cp313-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp313-cp313-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 78308d2ea41e2fae47659fe671725d5346d61d9d894d22b36e427f259b5a0cf1
MD5 aab600a3618f3516fa97c9fdda25999f
BLAKE2b-256 379b6440cde2f09b83c42ed3c6f121d0b8b9cf39f539960226600c8f72e2556f

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4326c120ae18de3fed09ea37be792a568a8433c7f3e01e0c7e32f883d98fc5a5
MD5 ca6769e28a61a48153e2cf9c02a83f35
BLAKE2b-256 7f3196305ed6e702f9b22859c4422aa258d33f005546b8198b954bcb6c2294c9

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 867430dde43c8cf463cd72d03b07a9158f2bee79bbdae08b0fb1e6e32982853e
MD5 4440ebcc69d88b49f8f09f552fa5828d
BLAKE2b-256 947231e52086abcc34e1787ecbf7b913c039551dd42f8fa9610ae0f64bc36fb0

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl
Algorithm Hash digest
SHA256 5cfbbec4cb74ad70b5d1747de1537095e21cb57ca70d2a6186738322d82cf917
MD5 d00048d7fc730852e47d2b97bcfcf74e
BLAKE2b-256 fea754df82f921088ba125a48d1cb74778200013ec3814f5d45a63e92832405c

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp313-cp313-macosx_11_0_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp313-cp313-macosx_11_0_x86_64.whl
  • Upload date:
  • Size: 965.2 kB
  • Tags: CPython 3.13, macOS 11.0+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp313-cp313-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 671c7c38197a2d11040bb0e05593063ee62b29a67c982dda688bb2ef30b81670
MD5 3dbc173b877f00d6b460dba64ff6ef8c
BLAKE2b-256 1934c0219eaf75e60777973a1bc317483f6569b7e662e8c0295cf667dfa39ef1

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp313-cp313-macosx_11_0_universal2.whl.

File metadata

  • Download URL: lupa-2.5-cp313-cp313-macosx_11_0_universal2.whl
  • Upload date:
  • Size: 1.8 MB
  • Tags: CPython 3.13, macOS 11.0+ universal2 (ARM64, x86-64)
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp313-cp313-macosx_11_0_universal2.whl
Algorithm Hash digest
SHA256 e372577ac3b54a4d13d43e43de2111ad48b6fabb8f7545f40bcd989e6c13b128
MD5 5713f2d2c803db91cb590175c16ebaca
BLAKE2b-256 179f2b16dfd4bea0effa256e51b446a543c1d95b059bd7217a671c8b3c0adec5

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

  • Download URL: lupa-2.5-cp313-cp313-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 897.9 kB
  • Tags: CPython 3.13, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 61f09dbb8af779d78f90d71811798710a29b455c6948ea51365eefc0ab142a0d
MD5 5c739a7f14231534a79a368c213522f7
BLAKE2b-256 6282e535e181d751cbd0cc8465c0c3f8f162d8cd69ba075c9916912b6a7c5830

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: lupa-2.5-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e51b0d1dee87a95f54b35f376a6eaa1143147ce3c5d89ba027772fb327555db6
MD5 9ea55f3155bb0f3e2f5a6b94b4800426
BLAKE2b-256 89d798c42bf67692ce59fb8e5b32d6479042a8b4fd031579ea2969aeddf30621

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp312-cp312-win32.whl.

File metadata

  • Download URL: lupa-2.5-cp312-cp312-win32.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.12, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 56e7e29980635a34422b9bc074015c3fc0a1ed354df6866ed27092b385b06839
MD5 0652a65be74c581f84f50bf3b429fde3
BLAKE2b-256 7e19cb4d6bb92cf10a0f3824883a1382128198d7fd92b61665b9833af8d59fab

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp312-cp312-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 2.2 MB
  • Tags: CPython 3.12, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b4ed0d6dfb7246bc5c85f998c3507b0bd1b16553924eaf0834c4d896a60ee0cd
MD5 a2dd6bb14ae3e4d69e79d9eae9e51de0
BLAKE2b-256 2e0e2cd499ac942aed285fc5be3ec7e2372a314cb83e7d17b596a9f855db98f2

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp312-cp312-musllinux_1_2_i686.whl.

File metadata

  • Download URL: lupa-2.5-cp312-cp312-musllinux_1_2_i686.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.12, musllinux: musl 1.2+ i686
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 953aa2bb0649ed08df911a001d845626d72b31e108da38701ed1116c22b3768f
MD5 68edddb0fdd19e9100eb942ad4bc034d
BLAKE2b-256 5c4438970fd1ff2069e3f3b87fa4817d5ce99272c3be49d31ca089603250cd79

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp312-cp312-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 e8bfdc69ebbc12271d9dfdb821bf6d5943887f8ec48acc4b19516c0a21bf98cf
MD5 a65795b3af608cdb2cab96034f8eb4e2
BLAKE2b-256 53352455e8fa0ad4f5a65003eb7e1efbdeada5c16ac13ce8fb31d95a2c1f4f1e

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2478053c6d30b6c46a969a5ffb02181f35a5b299fc5481e99ba5ae63f0f0a63f
MD5 8f82ed7e58eae7a81e0720593ddb7644
BLAKE2b-256 e66b338c68c7df3b5ee03f79da32dc33bdd75c25ccc57e9204d31bd62515b271

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 1d969ee4eed04788e7a5fa24613dcbc2fff6ef4e978a8ced4746f752092d70a9
MD5 86a2c0ad39800c7c168fddf39e08bc0d
BLAKE2b-256 a557c88b8c99c552d025a28484cd91e3bd8e2132af64f62f543b98b3107fe35b

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl
Algorithm Hash digest
SHA256 07d91df9994c8a17e16d9923684ea810dfc2ecd290503e100a1525ed3aa48bc8
MD5 1240d90cfa553201efa6a843beb0c0cf
BLAKE2b-256 75eda62788e22fc2896f68bc3df9939ba505d94096acf337336aee8ce0fea3f4

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp312-cp312-macosx_11_0_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp312-cp312-macosx_11_0_x86_64.whl
  • Upload date:
  • Size: 970.6 kB
  • Tags: CPython 3.12, macOS 11.0+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp312-cp312-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 7b3e258528a89f973a5e4a1b7d268a84bb1ae6e39912cfe5373c5a81ac8b82b6
MD5 2d2bf6baaccb795448ddf9939a5f0ecf
BLAKE2b-256 7eda815b6d7986d07f4ea1d992a31ba6bba8732dd5c1142311f24933aacc685b

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp312-cp312-macosx_11_0_universal2.whl.

File metadata

  • Download URL: lupa-2.5-cp312-cp312-macosx_11_0_universal2.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: CPython 3.12, macOS 11.0+ universal2 (ARM64, x86-64)
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp312-cp312-macosx_11_0_universal2.whl
Algorithm Hash digest
SHA256 ec223da758c920f2e2b20e934a7761e233ad24121e6bba4708b7d3aafff9a513
MD5 1d83c81ac2772fd86d65fad873f19db9
BLAKE2b-256 81962ff21f67532c3a2b4e15e6c108a589af26a111d9f58bee192b5cead3ad22

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

  • Download URL: lupa-2.5-cp312-cp312-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 902.0 kB
  • Tags: CPython 3.12, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 85635865409320efa9e6b95f64176317a2409a3f4e261e032094c48f783eb5f5
MD5 b37e857b8d53a8cc27782356c61498d2
BLAKE2b-256 a544db0fa42b126ea416efd9ea031b5490c37d3ce1575c7253f5b91d47faede4

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: lupa-2.5-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 0148bd1a1391d9fa3d14e0e4a07118f4091bdde7eb49cad98d417b4e5368ab77
MD5 55c9e173ab6cff309eed010d6bbf35cd
BLAKE2b-256 22065e19b6e323339bb5092f782aaadaf6f5e1c876939756fec5900a99e77a1f

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp311-cp311-win32.whl.

File metadata

  • Download URL: lupa-2.5-cp311-cp311-win32.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.11, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 a35c8fce1e71dd9b57486407f783de32fba938a62b806d1ebe747a5e0475958a
MD5 703c450effde56f7180bb9edc38972a2
BLAKE2b-256 e19244d959d1d097fb58e87a2d4a069aa90a4ef496b2be6be6a13cea6b8b80d4

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp311-cp311-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp311-cp311-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 2.2 MB
  • Tags: CPython 3.11, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 e6bc86dd2cc2e4751e7f44fd925a6a88da822136dc9d20b37a2aac858850acf0
MD5 cc97f135376bcd254c0ed818ae8d91a3
BLAKE2b-256 b95c2d9594b603ba08e52a2eaf25e051157430b6e7dcd7d7f65811406d8c176e

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp311-cp311-musllinux_1_2_i686.whl.

File metadata

  • Download URL: lupa-2.5-cp311-cp311-musllinux_1_2_i686.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.11, musllinux: musl 1.2+ i686
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 fa8cd11211c965d4fd1a79897d407d2614e60910936b2c2522303488331a712e
MD5 4e83734950f06a2ca3af030e02790b4e
BLAKE2b-256 928665472ff813e46afa40d36533f6ea478cd6a8f88132ae66148338b79f54de

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp311-cp311-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 3e7a9ae6f39015b07c44c32fe76fe8c3997451c7fd30a6fc12da3a78de502480
MD5 dcc03cb94021dd4680c7bdf222defc10
BLAKE2b-256 0743590d17a39f78e2da4a51734af21c16bd237eff674392acce51a010a702c0

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 29688640ebb88c317a76e41111de360b0dd38e833949928d76792dba2ba5cb0a
MD5 61e52514b7fcf7551445de9dc310e192
BLAKE2b-256 a20f77d1908a099c19c8aec23c095c398bb1f23f1fe3ef03801a7769066b6cf0

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 d126bea5b69778eeb15277b0f3c362604a5509bdab1fc768d8d4e4f97ec5a922
MD5 89df4876d911ba5a9fc50dd8ab019c10
BLAKE2b-256 418113aac83263bd62860db8bb3db313beb008a8bc33eb0c498b2bb5dce6d827

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp311-cp311-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp311-cp311-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl
Algorithm Hash digest
SHA256 858e40d67292e524416da37993ec08290f29ad804608457803d8c570970623a7
MD5 dadb0cf596d2a584634385f59ab0b4f6
BLAKE2b-256 285b1a9ffcc53ff3bb59d096eae95db462056a22ab253ede8678119d3f72eb76

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp311-cp311-macosx_11_0_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp311-cp311-macosx_11_0_x86_64.whl
  • Upload date:
  • Size: 973.4 kB
  • Tags: CPython 3.11, macOS 11.0+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp311-cp311-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 789acf7f98e1328a2744e19dd7cb92c08e2d6397d5b9e8810954d5192499d2ae
MD5 3491e292c0226c3ca6cc2c71b784ddfd
BLAKE2b-256 576bec6ae84ba9fb6c9ac8768e1eab9a403fffb5b348ed0eab6a7a0a8cc694c3

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp311-cp311-macosx_11_0_universal2.whl.

File metadata

  • Download URL: lupa-2.5-cp311-cp311-macosx_11_0_universal2.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: CPython 3.11, macOS 11.0+ universal2 (ARM64, x86-64)
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp311-cp311-macosx_11_0_universal2.whl
Algorithm Hash digest
SHA256 5249ac3eb11aeba0e25dbc20d53352cd04d2e48299a412d187200d492fd0fd63
MD5 29e8036546a5e43113afb22b1b508b64
BLAKE2b-256 d7d87510b877d2bd02e3b0aae70b9d771ac9ed6a9ac842b6d1b2dcebaff3557c

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

  • Download URL: lupa-2.5-cp311-cp311-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 919.6 kB
  • Tags: CPython 3.11, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0014935935862d3acf0f96dfa9ce6657720ece6918feaf76eb7c63948ba03a58
MD5 d0a95715f34dd568fa3c6fdcd7dc23ab
BLAKE2b-256 d8d86f648335b66adde88651ff65afa96fcf5db26b957e30886b9860ca680799

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: lupa-2.5-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 58bb044c788ad72b6b017e1f1513f7c2ef2a92f0d76f1b11bb0344f6bc82c623
MD5 06047987bfb726e71b04832704eee6be
BLAKE2b-256 b16ef44ba7d13c53bfd99af3b03f22ac01620e3ec3eb81ac059edd56ae314641

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp310-cp310-win32.whl.

File metadata

  • Download URL: lupa-2.5-cp310-cp310-win32.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.10, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 9f6b2d6e2b909e8ca1a746286881e718864d44d862596e4aae769dd9f63efcda
MD5 4d70e0a5bc8e9d4be19b92843f6d6a83
BLAKE2b-256 14c3e3e686f7b55292ad192c9cf7307fe1370c8969e348ecb987b0b314d9af75

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp310-cp310-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp310-cp310-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 2.2 MB
  • Tags: CPython 3.10, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 4b4a4a030e6a075e940a36311d44b4e2609778253ea10f933cf61786182cffed
MD5 e06d25dbaff286d0694c0e99ac311424
BLAKE2b-256 1dcbb77966f2229c29cbbdfa06f7b7cf59865cfe68fff8c4aa24ecea6cb5e0a1

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp310-cp310-musllinux_1_2_i686.whl.

File metadata

  • Download URL: lupa-2.5-cp310-cp310-musllinux_1_2_i686.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.10, musllinux: musl 1.2+ i686
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 c6133fa7d193e590f52266afedbeb55ae6dbb8c6def6f3a2074b10edfdb44727
MD5 b82673ad851fda9aed34eab3d202df2a
BLAKE2b-256 d8fe697f8846209230ca2948a9a78d65870e45e51772862313ad61dbfea23bbd

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp310-cp310-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 366e98069d20164632d66cd8c0820fcb4d8fea1214364e1614d19bf69086e29f
MD5 04286e681d550c1f41734177a43cd1d7
BLAKE2b-256 7d2d6c42afdf3eb2f4d8467cb70912df0db83d490584772db51f176475f831ca

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 82a845a5d93766fde05fc4094a27382f5253af97b699a36d496ca3cdf6afe769
MD5 64dd755037fb1591ec543eda1e2f660c
BLAKE2b-256 cc8ca13bcec44aed28b0c05daddaa713e85a16386300f62fd10312e4e51baac2

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7d28842fcd98ef1f0b825ae1e0b9568710eb4c522fb5dffa53255024c7816b84
MD5 b0c8a660117875ea167656bf38ee5813
BLAKE2b-256 bb361e62c7f6da39b765742d3f104c0a0cb78fb562914d9a59c061194caf8f6b

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp310-cp310-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp310-cp310-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl
Algorithm Hash digest
SHA256 62a810cb5270dd3f983db49f65518c1c060e7575beb464b80feafbb6b54baba1
MD5 6418f5b5b7482787123494af22024c45
BLAKE2b-256 86e118459bafaea54384305f1c0633d922197de7a349628fef5f5c83bad0a332

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp310-cp310-macosx_11_0_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp310-cp310-macosx_11_0_x86_64.whl
  • Upload date:
  • Size: 964.3 kB
  • Tags: CPython 3.10, macOS 11.0+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp310-cp310-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 05f7c091d59ef267e2572a7580c23093ce89894ed2755b68159a5a271b0b48eb
MD5 bf0d5f1045d9f7e15aad9a0181b649cf
BLAKE2b-256 f7cf2628b11289fafb8856f3b5a29f186e415978cf9a26b676931f6cb037ce32

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp310-cp310-macosx_11_0_universal2.whl.

File metadata

  • Download URL: lupa-2.5-cp310-cp310-macosx_11_0_universal2.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: CPython 3.10, macOS 11.0+ universal2 (ARM64, x86-64)
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp310-cp310-macosx_11_0_universal2.whl
Algorithm Hash digest
SHA256 d5235bf6880544f6b357513ba508f70a2d0363ae8bd94d696ba564b458435dbf
MD5 0e93576f180251a0d7b8da1784bb6de8
BLAKE2b-256 54e33ad6a3aae96dfd8fe15d696c824772fc14740ccd677907ac07872a9f5e72

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

  • Download URL: lupa-2.5-cp310-cp310-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 909.2 kB
  • Tags: CPython 3.10, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 102538780e8a6164944fff6bf93737d7cb8bf9e6f7146baa56184755fadb96d5
MD5 2eb63348efa280cb47f7f909662691dd
BLAKE2b-256 22cb3c82773eb581b8a95fae98eb5f0b7aa535c9fab04ac91da6ccab2bf2b6eb

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: lupa-2.5-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 5f3ca676d9c0de54529392c9d3303d42d16f736e651ec51170bd7f3aaff9325a
MD5 e2d6b4eb25e53e530025d965781446e0
BLAKE2b-256 4f0df2a311d122f15facf091e0381cd6a17ed5ee1ed68dfdafcd280d7c80c20c

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp39-cp39-win32.whl.

File metadata

  • Download URL: lupa-2.5-cp39-cp39-win32.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.9, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 c240a9a77990ff2a7f7269330beec824a7b0a825abbb8bba3100d767799b86d1
MD5 400f19cd9e03545bb83284fcea73c307
BLAKE2b-256 6daef52eb83ce12180072fb561865db56559cdaf7a3354cc8f7080f637d40daf

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp39-cp39-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp39-cp39-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 2.2 MB
  • Tags: CPython 3.9, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 4d468e6d9612fdfb43f44f2d077d7a389aa6bdf0b8ec57b4da2f96748cd99af6
MD5 557e82049a3c6a8823792677a42d1c07
BLAKE2b-256 893c0e62792b52247b9190f73cb88feb8ff2f1af662a54867f309660ce06ab96

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp39-cp39-musllinux_1_2_i686.whl.

File metadata

  • Download URL: lupa-2.5-cp39-cp39-musllinux_1_2_i686.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.9, musllinux: musl 1.2+ i686
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 91e45661a8871d3b2d73cefebb4793e1e461697836479f1969a2e7cbd5486b85
MD5 bbd6314358ff694020dea94a952ca86f
BLAKE2b-256 9df2ad5041b9557bb6ece3c32aa1d5505f810fe7d39a1160b2f77cb6c1fc96c4

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp39-cp39-musllinux_1_2_aarch64.whl.

File metadata

  • Download URL: lupa-2.5-cp39-cp39-musllinux_1_2_aarch64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.9, musllinux: musl 1.2+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 2acb20dd5b0b345389ac0ac714def772eb5ebdbc9500fcabedd42f206747be42
MD5 4dcf0c459d2df16bf7c9aa637f8db5a9
BLAKE2b-256 593b1db05dc2682277cf97075912004e570ec37e1f1af3dcc27bb2fccfae7a24

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0b95f89fcc84601cc04e2a637e9029754ad43487ed50a13d8183db03b273b468
MD5 f4036b6baf0c16e10c03fd4a32be0c5b
BLAKE2b-256 842c0d37b97cbf4b32d4fe202d33b2ff84d01de9bf2d8356d2e44c158cd902d5

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 01433c46562ee9a64779627de34ccef38241a926b5325f03fe7859d73d8d2393
MD5 a90658fa6a7b6bb02dff1b59c13002e3
BLAKE2b-256 2bf1c7eca22130181797764a7dc90270ca2a8c27f366b13ff00e95fd2f6fbbb8

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp39-cp39-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp39-cp39-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl
Algorithm Hash digest
SHA256 d75aa4ad8c4a3bb7f8357cb764fa886cedf13d052a50bf730105d76a72e22833
MD5 4d36d926a7e0f130d1af372e4c1c0776
BLAKE2b-256 035df953fd46876ff4c617a4d3f23c45f4925df3450f77ecf11d67bb834975f4

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp39-cp39-macosx_11_0_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp39-cp39-macosx_11_0_x86_64.whl
  • Upload date:
  • Size: 965.0 kB
  • Tags: CPython 3.9, macOS 11.0+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp39-cp39-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 c843bbb0160052ae9726791bdda919b11ef4a318e5d117a67fa0d7e7a204f4a8
MD5 39e891b6c48efeb442728cebf47f1c72
BLAKE2b-256 d703d7cc6c63775667e0db95e5e8cf69733c4bd1c59dcb46ef2f606c0b75a52c

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp39-cp39-macosx_11_0_universal2.whl.

File metadata

  • Download URL: lupa-2.5-cp39-cp39-macosx_11_0_universal2.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: CPython 3.9, macOS 11.0+ universal2 (ARM64, x86-64)
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp39-cp39-macosx_11_0_universal2.whl
Algorithm Hash digest
SHA256 613714679e0b64f5bb06cd72581f9694735e682c70dbdc5cbefa11ff58da0352
MD5 e08a345fd8e11e1d24f04b4c00d222fa
BLAKE2b-256 5d9a021b8a3c0732743f39abd4f9aa40573f9394fbf19e3e85a52456ccaa94dc

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

  • Download URL: lupa-2.5-cp39-cp39-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 910.6 kB
  • Tags: CPython 3.9, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cb2656da6005eb7eeadb3bb77d471665a95f81ebd5c10e03e0c17c29e2a6d821
MD5 0862aba0eb6c11dcbed1ebd9577e6f10
BLAKE2b-256 dbcd77e29d8d59145cbb8c211ce8c711eb54b404572d74dce7e9959cc57e808a

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: lupa-2.5-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 62af309cea7742c54640e9c94058e4aed783963be9372572212d3d9fa50741cb
MD5 04559c9334b903deddad4a091ed79f4a
BLAKE2b-256 d9ea264c3c8fe1ad60806e3f2a9f07c5c397070471f1058e32db1ea5db3c4bec

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp38-cp38-win32.whl.

File metadata

  • Download URL: lupa-2.5-cp38-cp38-win32.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.8, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 ec8a77bcdecc8842a57dc9509ac04f2694b205fa6de9e69b584b100ed4631668
MD5 15c108389ef0c11755f02317e56e6725
BLAKE2b-256 ee28dfa3791831761970bdad5aa8bb9dd6938ee173b0b9849993040e65e0740d

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp38-cp38-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp38-cp38-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 2.2 MB
  • Tags: CPython 3.8, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 d161fdd6ca5ed5f63e4cf0d2ef671c39092a2c0d886fdbff14f4938238144525
MD5 d7f92c7c4b42bbbd17e419f62687dce1
BLAKE2b-256 883c3f8828a32c930e98bb8edef7638dae1a899ae889b0ebb136b124dec1a319

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp38-cp38-musllinux_1_2_i686.whl.

File metadata

  • Download URL: lupa-2.5-cp38-cp38-musllinux_1_2_i686.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.8, musllinux: musl 1.2+ i686
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 c42b64a17a1cbca3344742ef51add827591f4a710cc7746ef37997fcc2f27409
MD5 cbbb07b729dbd5def0de2cb67f5fbd24
BLAKE2b-256 2e0d291dbff5aff79c5e174a434b0f16e3ec56445b96ae3c7cd5b72c7c11ade9

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp38-cp38-musllinux_1_2_aarch64.whl.

File metadata

  • Download URL: lupa-2.5-cp38-cp38-musllinux_1_2_aarch64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.8, musllinux: musl 1.2+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1e1187cd2e02a567e83ed23c95982c1a610e8eb308216ebe9567487340c4375e
MD5 881495ecc2978dc664d8072576bf9599
BLAKE2b-256 ec82f804645260a6b1ea5d5a088263da78c05e4f292011cb415e3c55d04d80bd

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d070b9a2e8ffae07a0bdfcb6e791755d7be237e07df2d02ea1962e1393c1f0c9
MD5 9eedc30818407878c235d87e3d4c5563
BLAKE2b-256 b54e58eba166a90c5f469fd9f29e3f2303757ad7199e50cbec2f29c092410c82

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7451a5381676f5968ad5eedbc51a7c692d9bb62b0f89e4d26ed56aa6cf342123
MD5 170efb1b03b5ff58dfff8d93bb5e39a0
BLAKE2b-256 c947a7bd20f7950cc671692fc14791b919f125643350e1bd258d8423bda6787a

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp38-cp38-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl.

File metadata

File hashes

Hashes for lupa-2.5-cp38-cp38-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl
Algorithm Hash digest
SHA256 370e8a554eeb404d1aa0c62516e5a8241615735c936a5c87a6e9042146ed0d6e
MD5 d39ec58f38625b400395b2664c22f35c
BLAKE2b-256 a05645229585ad534fad73084942b9cf7b00943a3348d0d751922fb795ba2fd5

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp38-cp38-macosx_11_0_x86_64.whl.

File metadata

  • Download URL: lupa-2.5-cp38-cp38-macosx_11_0_x86_64.whl
  • Upload date:
  • Size: 970.3 kB
  • Tags: CPython 3.8, macOS 11.0+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp38-cp38-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 4c4c2ec16e4f3be2c995a645eec42aebb094522c2d70f41df33bfc71f7a19406
MD5 42b5aa9f35f3264d0c54cc096625e304
BLAKE2b-256 7ad30061c5275e1d030467044a8e6507726c4d75c2ced26577cfee3ca843e7c0

See more details on using hashes here.

File details

Details for the file lupa-2.5-cp38-cp38-macosx_11_0_arm64.whl.

File metadata

  • Download URL: lupa-2.5-cp38-cp38-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 917.5 kB
  • Tags: CPython 3.8, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for lupa-2.5-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1e4451134e094b0a985a9af9cd1ace535f2531a4906274d7675ebb0d790a80a1
MD5 821bb160f09f76a249201ac326c70ae6
BLAKE2b-256 1a1de707feda241bec78595828b8e240f6cdcd6220c319f541604727e85287db

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page