From 230ae84ce860575bd17ad37ff8bb1f728b703337 Mon Sep 17 00:00:00 2001 From: ANSHUL SINGH <72524975+ekanshul@users.noreply.github.com> Date: Wed, 19 Aug 2026 21:31:14 +0530 Subject: [PATCH] [lupa] Bump to 2.8.* and add lupa.lua55 stubs lupa 2.7 started bundling Lua 5.5, so lupa 2.8 ships a new lupa.lua55 extension module and lupa's top-level namespace now re-exports it (LuaRuntime is lupa.lua55.LuaRuntime). Without stubs for it, stubtest fails with "lupa.lua55 failed to find stubs" on the stubsabot bump. The lua55 module exposes exactly the same names and class members as lua54 at runtime, so lua55.pyi is a copy of lua54.pyi, and __init__.pyi now re-exports from lua55 (newest lib) as it did from lua54 before. Co-Authored-By: Claude Fable 5 --- stubs/lupa/METADATA.toml | 2 +- stubs/lupa/lupa/__init__.pyi | 4 +- stubs/lupa/lupa/lua55.pyi | 102 +++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 stubs/lupa/lupa/lua55.pyi diff --git a/stubs/lupa/METADATA.toml b/stubs/lupa/METADATA.toml index 7867a8a93236..9ab84dd92ab1 100644 --- a/stubs/lupa/METADATA.toml +++ b/stubs/lupa/METADATA.toml @@ -1,2 +1,2 @@ -version = "2.6.*" +version = "2.8.*" upstream-repository = "https://github.com/scoder/lupa" diff --git a/stubs/lupa/lupa/__init__.pyi b/stubs/lupa/lupa/__init__.pyi index d14ef918216c..6eb98c022432 100644 --- a/stubs/lupa/lupa/__init__.pyi +++ b/stubs/lupa/lupa/__init__.pyi @@ -1,7 +1,7 @@ -from .lua54 import * +from .lua55 import * __all__ = [ - # from lua54 (newest lib) + # from lua55 (newest lib) "LUA_VERSION", "LUA_MAXINTEGER", "LUA_MININTEGER", diff --git a/stubs/lupa/lupa/lua55.pyi b/stubs/lupa/lupa/lua55.pyi new file mode 100644 index 000000000000..7604148b370b --- /dev/null +++ b/stubs/lupa/lupa/lua55.pyi @@ -0,0 +1,102 @@ +from _typeshed import MaybeNone +from collections.abc import Callable, Iterable +from typing import Any, Final, Generic, TypeAlias, TypeVar, type_check_only +from typing_extensions import Self, disjoint_base + +__all__ = [ + "LUA_VERSION", + "LUA_MAXINTEGER", + "LUA_MININTEGER", + "LuaRuntime", + "LuaError", + "LuaSyntaxError", + "LuaMemoryError", + "as_itemgetter", + "as_attrgetter", + "lua_type", + "unpacks_lua_table", + "unpacks_lua_table_method", +] + +LUA_MAXINTEGER: Final[int] +LUA_MININTEGER: Final[int] +LUA_VERSION: Final[tuple[int, int]] + +# cyfunction object +as_attrgetter: Callable[[object], object] +as_itemgetter: Callable[[object], object] + +# cyfunction object +lua_type: Callable[[object], str | MaybeNone] + +# cyfunction object as decorator +unpacks_lua_table: Callable[[Callable[..., Any]], Callable[..., Any]] +unpacks_lua_table_method: Callable[[Callable[..., Any]], Callable[..., Any]] + +# inner classes + +@type_check_only +class _LuaTable: + def keys(self) -> Iterable[_LuaKey]: ... + def values(self) -> Iterable[_LuaObject]: ... + def items(self) -> Iterable[tuple[_LuaKey, _LuaObject]]: ... + def __getitem__(self, key: _LuaKey) -> _LuaObject: ... + def __setitem__(self, key: _LuaKey, value: _LuaObject) -> None: ... + def __delitem__(self, key: _LuaKey) -> None: ... + +# A Lua object can be a table or a primitive type. Because we have no way of +# knowing the actual type across languages, we simply use an Any for a Lua +# object. + +# A previous version of this code had +# _LuaObject: TypeAlias = _LuaTable | int | str | float | bool | None +# but that causes false type failures when running, e.g., `lua.globals()['foo']['bar']` +# (because `lua.globals()['foo']` is not known to be a nested table +_LuaKey: TypeAlias = str | int +_LuaObject: TypeAlias = Any + +@type_check_only +class _LuaNoGC: ... + +# classes + +_bint = TypeVar("_bint", bool, int) + +@disjoint_base +class FastRLock(Generic[_bint]): + # @classmethod + # def __init__(cls, /, *args: Any, **kwargs: Any) -> None: ... + def acquire(self, blocking: _bint = ...) -> _bint: ... + def release(self) -> None: ... + def __enter__(self) -> _bint: ... + def __exit__(self, t: object, v: object, tb: object) -> None: ... + +class LuaError(Exception): ... +class LuaSyntaxError(LuaError): ... +class LuaMemoryError(LuaError, MemoryError): ... + +@disjoint_base +class LuaRuntime: + lua_implementation: Final[str] + lua_version: Final[tuple[int, int]] + + def __new__(cls, /, unpack_returned_tuples: bool) -> Self: ... + # def add_pending_unref(self, ref: int) -> None: ... + # def clean_up_pending_unrefs(self) -> int: ... + def get_max_memory(self, total: bool = False) -> int | MaybeNone: ... + def get_memory_used(self, total: bool = False) -> int | MaybeNone: ... + # def reraise_on_exceptions(self) -> int: ... + # def store_raised_exception(self, L: object, lua_error_msg: str) -> None: ... # unannotated + def eval(self, lua_code: str, *args: Any, name: str | None = None, mode: str | None = None) -> object: ... + def execute(self, lua_code: str, *args: Any, name: str | None = None, mode: str | None = None) -> object: ... + def compile(self, lua_code: str, name: str | None = None, mode: str | None = None) -> Callable[..., object]: ... + def require(self, modulename: str) -> object: ... + def globals(self) -> _LuaTable: ... + def table(self, *items: Any, **kwargs: Any) -> _LuaTable: ... + def table_from(self, *args: Any, recursive: bool = False) -> _LuaTable: ... + def nogc(self) -> _LuaNoGC: ... + def gccollect(self) -> None: ... + def set_max_memory(self, max_memory: int, total: bool = False) -> None: ... + def set_overflow_handler(self, overflow_handler: Callable[..., None]) -> None: ... + # def register_py_object(self, cname: str, pyname: str, obj: object) -> int: ... + # def init_python_lib(self, register_eval: bool, register_builtins: bool) -> int: ...