Skip to content

Python userdata identity can get mixed up in Lua 5.5 #294

Description

@stelonix

I think I've run into a Python userdata/reference issue with the new lua 5.5 backend.

This reproduces for me with lupa 2.8:

import lupa.lua54 as lua54
import lupa.lua55 as lua55


class Entity:
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return f"Entity({self.name})"


def test(lua):
    runtime = lua.LuaRuntime()
    echo = runtime.eval("function(entity, event) return entity end")

    entities = [Entity("A"), Entity("B"), Entity("C")]

    for i in range(10000):
        expected = entities[i % 3]
        actual = echo(expected, runtime.table(name="update"))

        if actual is not expected:
            print("failed at", i)
            print("expected:", expected, id(expected))
            print("actual:  ", actual, id(actual))
            return

    print("passed")


print("lua54:")
test(lua54)

print("lua55:")
test(lua55)

For me:

lua54:
passed

lua55:
failed at 51
expected: Entity(A)
actual:   Entity(C)

The exact failing call can move around in a larger repro, but lua55 consistently ends up substituting another live Python object for the one that was passed in. lua54 survives 10,000 calls.

I originally found this in a Lua -> Python -> Lua callback path where an entity argument eventually became another Python object associated with that entity (a dict). I reduced it down to the above, which doesn't need the callback/re-entry at all.

Possibly related to #293, although that one reproduces on 5.2/5.3 and not 5.4+, while this one seems specific to 5.5 for me.

Environment:

Lupa 2.8
Python 3.10.12
Ubuntu 22.04 x86_64
Linux 6.8.0-136-generic #136~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul 3 16:29:11 UTC 2026

I also checked the installed extensions: lupa.lua54 and lupa.lua55 are separate binaries and neither dynamically links a system liblua, so this doesn't look like a 5.4/5.5 shared-library ABI mixup.

For now I've fixed it by using the 5.4 backend.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions