Skip to content

Commit 36023c5

Browse files
committed
Avoid non-Limited API usage when building with "Py_LIMITED_API" enabled.
1 parent 507ec94 commit 36023c5

File tree

1 file changed

+33
-11
lines changed

1 file changed

+33
-11
lines changed

lupa/_lupa.pyx

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,23 @@ cdef extern from "stdint.h":
3333
cdef const long LONG_MIN, LONG_MAX
3434
cdef const long long PY_LLONG_MIN, PY_LLONG_MAX
3535

36+
cdef extern from *:
37+
# Adaptations for the Limited API.
38+
"""
39+
#if defined(Py_LIMITED_API)
40+
#define IN_LIMITED_API (1)
41+
#define PyFloat_AS_DOUBLE(value) PyFloat_AsDouble(value)
42+
#define PyTuple_SET_ITEM(tuple, i, value) PyTuple_SetItem(tuple, i, value)
43+
44+
#define PyMethod_Check(obj) (0)
45+
#define PyMethod_GET_SELF(obj) (0)
46+
#define PyMethod_GET_FUNCTION(obj) (0)
47+
#else
48+
#define IN_LIMITED_API (0)
49+
#endif
50+
"""
51+
cdef const bint IN_LIMITED_API
52+
3653
cdef object exc_info
3754
from sys import exc_info
3855

@@ -2088,17 +2105,22 @@ cdef bint call_python(LuaRuntime runtime, lua_State *L, py_object* py_obj) excep
20882105
else:
20892106
args += (arg, )
20902107

2091-
if args and PyMethod_Check(f) and (<PyObject*>args[0]) is PyMethod_GET_SELF(f):
2092-
# Calling a bound method and self is already the first argument.
2093-
# Lua x:m(a, b) => Python as x.m(x, a, b) but should be x.m(a, b)
2094-
#
2095-
# Lua syntax is sensitive to method calls vs function lookups, while
2096-
# Python's syntax is not. In a way, we are leaking Python semantics
2097-
# into Lua by duplicating the first argument from method calls.
2098-
#
2099-
# The method wrapper would only prepend self to the tuple again,
2100-
# so we just call the underlying function directly instead.
2101-
f = <object>PyMethod_GET_FUNCTION(f)
2108+
if args:
2109+
if not IN_LIMITED_API:
2110+
if PyMethod_Check(f) and (<PyObject*>args[0]) is PyMethod_GET_SELF(f):
2111+
# Calling a bound method and self is already the first argument.
2112+
# Lua x:m(a, b) => Python as x.m(x, a, b) but should be x.m(a, b)
2113+
#
2114+
# Lua syntax is sensitive to method calls vs function lookups, while
2115+
# Python's syntax is not. In a way, we are leaking Python semantics
2116+
# into Lua by duplicating the first argument from method calls.
2117+
#
2118+
# The method wrapper would only prepend self to the tuple again,
2119+
# so we just call the underlying function directly instead.
2120+
f = <object>PyMethod_GET_FUNCTION(f)
2121+
elif getattr(f, '__self__', None) is args[0]:
2122+
# The same in slow, for the Limited API.
2123+
f = getattr(f, '__func__', f)
21022124

21032125
lua.lua_settop(L, 0) # FIXME
21042126
result = f(*args, **kwargs)

0 commit comments

Comments
 (0)