diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f8fc7e0b..4c9e3e8b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,20 +12,16 @@ jobs: matrix: os: - windows-2019 - - ubuntu-20.04 - - macos-12 + - ubuntu-latest - macos-latest python-version: - - "2.7" + - "3.14-dev" + - "3.13" - "3.12" - "3.11" - "3.10" - "3.9" - "3.8" - - "3.7" - - "3.6" - - "pypy-2.7" - - "pypy-3.7" - "pypy-3.8" - "pypy-3.9" - "pypy-3.10" @@ -36,10 +32,6 @@ jobs: - "luajit-5.1" exclude: - - os: windows-2019 - python-version: "2.7" - - os: windows-2019 - python-version: pypy-2.7 - os: windows-2019 lua-version: lua5.2 - os: windows-2019 @@ -49,25 +41,6 @@ jobs: - os: windows-2019 lua-version: luajit-5.1 - - os: macos-12 - python-version: "2.7" - - os: macos-latest - python-version: "2.7" - - os: macos-latest - python-version: "3.6" - - os: macos-latest - python-version: "3.7" - - os: macos-latest - python-version: pypy-3.7 - - - os: macos-12 - lua-version: lua5.2 - - os: macos-12 - lua-version: lua5.3 - - os: macos-12 - lua-version: lua5.4 - - os: macos-12 - lua-version: luajit-5.1 - os: macos-latest lua-version: lua5.2 - os: macos-latest @@ -92,25 +65,13 @@ jobs: run: git submodule update --init --recursive - name: Set up Python ${{ matrix.python-version }} - if: startsWith(matrix.python-version, '3.') || startsWith(matrix.python-version, 'pypy') || !startsWith(matrix.os, 'ubuntu') uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - name: Set up Python2 (Linux) - if: matrix.python-version == '2.7' && startsWith(matrix.os, 'ubuntu') - run: | - sudo ln -fs python2 /usr/bin/python - sudo apt-get update - sudo apt-get install python-setuptools python2.7 python2.7-dev - curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py - sudo python2 get-pip.py - ls -l /usr/bin/pip* /usr/local/bin/pip* - which pip - - name: Set up Python packages run: | - python -m pip install -U ${{ startsWith(matrix.python-version, '2.7') && '"pip<21" "setuptools<45"' || 'pip setuptools' }} + python -m pip install -U pip setuptools python -m pip install -U wheel tox virtualenv -r requirements.txt - name: Set up Lua ${{ matrix.lua-version }} @@ -124,19 +85,17 @@ jobs: arch: x64 - name: Build wheel - run: python setup.py sdist ${{ contains(matrix.python-version, '3.') && 'build_ext -j6' || '' }} bdist_wheel + run: python setup.py sdist build_ext -j6 bdist_wheel env: SETUP_OPTIONS: ${{ !contains(matrix.lua-version, 'luajit') && (contains(matrix.lua-version, 'bundle') && '--use-bundle' || '--no-luajit') || '' }} CFLAGS: ${{ env.CFLAGS }} ${{ env.CFLAGS_LTO }} LDFLAGS: ${{ env.CFLAGS_LTO }} - name: Run tests - run: python setup.py test + run: | + bash -c "python -m pip install dist/lupa-*.whl" + python -m lupa.tests.__main__ continue-on-error: ${{ contains(matrix.python-version, 'pypy') }} - env: - SETUP_OPTIONS: ${{ !contains(matrix.lua-version, 'luajit') && (contains(matrix.lua-version, 'bundle') && '--use-bundle' || '--no-luajit') || '' }} - CFLAGS: ${{ env.CFLAGS }} ${{ env.CFLAGS_LTO }} - LDFLAGS: ${{ env.CFLAGS_LTO }} - name: Upload wheels if: matrix.lua-version == 'bundle' && matrix.os == 'macos-latest' diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index ba15b369..d6ce4535 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -40,7 +40,7 @@ permissions: {} jobs: sdist: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest permissions: contents: write # to create GitHub release (softprops/action-gh-release) @@ -68,12 +68,6 @@ jobs: name: sdist path: dist/*.tar.gz - - name: Release - uses: softprops/action-gh-release@v2 - if: startsWith(github.ref, 'refs/tags/') - with: - files: dist/*.tar.gz - generate-wheels-matrix: # Create a matrix of all architectures & versions to build. # This enables the next step to run cibuildwheel in parallel. @@ -86,7 +80,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Install cibuildwheel # Nb. keep cibuildwheel version pin consistent with job below - run: pipx install cibuildwheel==2.16.5 + run: pipx install cibuildwheel==2.22.0 - id: set-matrix run: | MATRIX=$( @@ -147,7 +141,7 @@ jobs: arch: x86 - name: Build wheels - uses: pypa/cibuildwheel@v2.16.5 + uses: pypa/cibuildwheel@v2.22.0 with: only: ${{ matrix.only }} @@ -158,7 +152,7 @@ jobs: upload_release_assets: name: Upload Release Wheels - needs: [ build_wheels, Linux, non-Linux ] + needs: [ build_wheels, Linux ] runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags') @@ -183,7 +177,9 @@ jobs: - name: Release uses: softprops/action-gh-release@v2 with: - files: ./bdist_downloads/*.whl + files: | + ./bdist_downloads/*.whl + ./bdist_downloads/*.tar.gz Linux: runs-on: ubuntu-latest @@ -211,7 +207,7 @@ jobs: - name: Set up Python uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 with: - python-version: "3.9" + python-version: "3.12" - name: Install dependencies run: python -m pip install -r requirements.txt @@ -226,68 +222,3 @@ jobs: name: wheels-${{ matrix.image }} path: wheelhouse_*/*-m*linux*.whl # manylinux / musllinux if-no-files-found: ignore - - non-Linux: - strategy: - # Allows for matrix sub-jobs to fail without canceling the rest - fail-fast: false - - matrix: - os: - - macos-12 - #- windows-2019 - pyversion: - - "2.7" - - "3.6" - #- "pypy-3.7-v7.3.7" - #- "pypy-3.8-v7.3.7" - #- "pypy-3.9-v7.3.11" - #- "pypy-3.10-v7.3.13" - - exclude: - # outdated compilers and probably not worth supporting anymore - - os: windows-2019 - pyversion: "2.7" - - runs-on: ${{ matrix.os }} - env: - USE_BUNDLE: "true" - MACOSX_DEPLOYMENT_TARGET: "11.0" - LUPA_WITH_LUA_DLOPEN: ${{ startsWith(matrix.os, 'windows') && 'false' || 'true' }} - PYTHON_BIN_DIR: ${{ startsWith(matrix.pyversion, '2.') && '/Library/Frameworks/Python.framework/Versions/2.7/bin' || '' }} - - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - name: Check out recursively - run: git submodule update --init --recursive - - - name: Set up Python - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 - # macOS has Py2.7 installed system wide - if: matrix.pyversion != '2.7' - with: - python-version: ${{ matrix.pyversion }} - - - name: Install MacOS dependencies - if: startsWith(matrix.os, 'mac') - run: | - brew install automake libtool - ln -s /usr/local/bin/glibtoolize /usr/local/bin/libtoolize - - - name: Install dependencies - run: | - export PATH=$PYTHON_BIN_DIR:$PATH - python -m pip install wheel -r requirements.txt - - - name: Build wheels - run: | - export PATH=$PYTHON_BIN_DIR:$PATH - python setup.py --with-cython sdist ${{ contains(matrix.pyversion, '3.') && 'build_ext -j6' || '' }} bdist_wheel - - - name: Upload wheels - uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0 - with: - name: wheels-${{ matrix.pyversion }}-${{ matrix.os }} - path: dist/*.whl - if-no-files-found: ignore diff --git a/CHANGES.rst b/CHANGES.rst index 15b7fbaf..17938c39 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,18 @@ Lupa change log =============== +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) ---------------- diff --git a/appveyor.yml b/appveyor.yml index 695e160d..ae400193 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -48,7 +48,7 @@ build_script: test: off test_script: - - python -u setup.py test + - python -u -m lupa.tests.__main__ artifacts: - path: dist/*.whl diff --git a/lupa/_lupa.pyx b/lupa/_lupa.pyx index 935b9011..8f4f73f5 100644 --- a/lupa/_lupa.pyx +++ b/lupa/_lupa.pyx @@ -24,20 +24,7 @@ from cpython.method cimport ( from cpython.bytes cimport PyBytes_FromFormat #from libc.stdint cimport uintptr_t -cdef extern from *: - """ - #if PY_VERSION_HEX < 0x03040000 && defined(_MSC_VER) - #ifndef _MSC_STDINT_H_ - #ifdef _WIN64 // [ - typedef unsigned __int64 uintptr_t; - #else // _WIN64 ][ - typedef _W64 unsigned int uintptr_t; - #endif // _WIN64 ] - #endif - #else - #include - #endif - """ +cdef extern from "stdint.h": ctypedef size_t uintptr_t cdef const Py_ssize_t PY_SSIZE_T_MAX cdef const char CHAR_MIN, CHAR_MAX @@ -51,10 +38,7 @@ from sys import exc_info cdef object Mapping cdef object Sequence -try: - from collections.abc import Mapping, Sequence -except ImportError: - from collections import Mapping, Sequence # Py2 +from collections.abc import Mapping, Sequence cdef object wraps from functools import wraps @@ -75,12 +59,6 @@ DEF POBJECT = b"POBJECT" # as used by LunaticPython DEF LUPAOFH = b"LUPA_NUMBER_OVERFLOW_CALLBACK_FUNCTION" DEF PYREFST = b"LUPA_PYTHON_REFERENCES_TABLE" -cdef extern from *: - """ - #define IS_PY2 (PY_MAJOR_VERSION == 2) - """ - int IS_PY2 - cdef enum WrappedObjectFlags: # flags that determine the behaviour of a wrapped object: OBJ_AS_INDEX = 1 # prefers the getitem protocol (over getattr) @@ -165,7 +143,7 @@ def lua_type(obj): return 'userdata' else: lua_type_name = lua.lua_typename(L, ltype) - return lua_type_name if IS_PY2 else lua_type_name.decode('ascii') + return lua_type_name.decode('ascii') finally: lua.lua_settop(L, old_top) unlock_runtime(lua_object._runtime) @@ -235,7 +213,7 @@ cdef class LuaRuntime: Normally, it should return the now well-behaved object that can be converted/wrapped to a Lua type. If the object cannot be precisely represented in Lua, it should raise an ``OverflowError``. - + * ``max_memory``: max memory usage this LuaRuntime can use in bytes. If max_memory is None, the default lua allocator is used and calls to ``set_max_memory(limit)`` will fail with a ``LuaMemoryError``. @@ -656,12 +634,12 @@ cdef class LuaRuntime: luaL_openlib(L, "python", py_lib, 0) # lib lua.lua_pushlightuserdata(L, self) # lib udata lua.lua_pushcclosure(L, py_args, 1) # lib function - lua.lua_setfield(L, -2, "args") # lib + lua.lua_setfield(L, -2, "args") # lib # register our own object metatable lua.luaL_newmetatable(L, POBJECT) # lib metatbl luaL_openlib(L, NULL, py_object_lib, 0) - lua.lua_pop(L, 1) # lib + lua.lua_pop(L, 1) # lib # create and store the python references table lua.lua_newtable(L) # lib tbl @@ -669,7 +647,7 @@ cdef class LuaRuntime: lua.lua_pushlstring(L, "v", 1) # lib tbl metatbl "v" lua.lua_setfield(L, -2, "__mode") # lib tbl metatbl lua.lua_setmetatable(L, -2) # lib tbl - lua.lua_setfield(L, lua.LUA_REGISTRYINDEX, PYREFST) # lib + lua.lua_setfield(L, lua.LUA_REGISTRYINDEX, PYREFST) # lib # register global names in the module self.register_py_object(b'Py_None', b'none', None) @@ -818,17 +796,14 @@ cdef tuple unpack_lua_table(LuaRuntime runtime, lua_State* L): while lua.lua_next(L, -2): # key value key = py_from_lua(runtime, L, -2) value = py_from_lua(runtime, L, -1) - if isinstance(key, (int, long)) and not isinstance(key, bool): + if isinstance(key, int) and not isinstance(key, bool): index = key if index < 1 or index > length: raise IndexError("table index out of range") cpython.ref.Py_INCREF(value) cpython.tuple.PyTuple_SET_ITEM(args, index-1, value) elif isinstance(key, bytes): - if IS_PY2: - kwargs[key] = value - else: - kwargs[(key).decode(source_encoding)] = value + kwargs[(key).decode(source_encoding)] = value elif isinstance(key, unicode): kwargs[key] = value else: @@ -1508,21 +1483,14 @@ cdef object py_from_lua(LuaRuntime runtime, lua_State *L, int n): elif lua_type == lua.LUA_TNUMBER: if lua.LUA_VERSION_NUM >= 503: if lua.lua_isinteger(L, n): - integer = lua.lua_tointeger(L, n) - if IS_PY2 and (sizeof(lua.lua_Integer) <= sizeof(long) or LONG_MIN <= integer <= LONG_MAX): - return integer - else: - return integer + return lua.lua_tointeger(L, n) else: return lua.lua_tonumber(L, n) else: number = lua.lua_tonumber(L, n) integer = number if number == integer: - if IS_PY2 and (sizeof(lua.lua_Integer) <= sizeof(long) or LONG_MIN <= integer <= LONG_MAX): - return integer - else: - return integer + return integer else: return number elif lua_type == lua.LUA_TSTRING: @@ -1632,7 +1600,7 @@ cdef int py_to_lua(LuaRuntime runtime, lua_State *L, object o, bint wrap_none=Fa elif type(o) is float: lua.lua_pushnumber(L, cpython.float.PyFloat_AS_DOUBLE(o)) pushed_values_count = 1 - elif isinstance(o, (long, int)): + elif isinstance(o, int): try: lua.lua_pushinteger(L, o) pushed_values_count = 1 @@ -2013,7 +1981,7 @@ cdef void* _lua_alloc_restricted(void* ud, void* ptr, size_t old_size, size_t ne return NULL elif new_size == old_size: return ptr - + if memory_status.limit > 0 and new_size > old_size and memory_status.limit <= memory_status.used + new_size - old_size: # reached the limit # print("REACHED LIMIT") return NULL @@ -2085,7 +2053,7 @@ cdef int py_object_gc_with_gil(py_object *py_obj, lua_State* L) noexcept with gi return 0 finally: py_obj.obj = NULL - + cdef int py_object_gc(lua_State* L) noexcept nogil: if not lua.lua_isuserdata(L, 1): return 0 diff --git a/lupa/lock.pxi b/lupa/lock.pxi index 2dcc47f9..4cdf5d2c 100644 --- a/lupa/lock.pxi +++ b/lupa/lock.pxi @@ -2,19 +2,9 @@ from cpython cimport pythread cdef extern from *: - # Compatibility definitions for Python """ - #if PY_VERSION_HEX >= 0x030700a2 typedef unsigned long pythread_t; - #else - typedef long pythread_t; - #endif """ - - # Just let Cython understand that pythread_t is - # a long type, but be aware that it is actually - # signed for versions of Python prior to 3.7.0a2 and - # unsigned for later versions ctypedef unsigned long pythread_t diff --git a/lupa/tests/__main__.py b/lupa/tests/__main__.py new file mode 100644 index 00000000..51d4245f --- /dev/null +++ b/lupa/tests/__main__.py @@ -0,0 +1,4 @@ +if __name__ == '__main__': + import unittest + from . import suite + unittest.TextTestRunner(verbosity=2).run(suite()) diff --git a/pyproject.toml b/pyproject.toml index 47efe18e..7ebb5b80 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["Cython>=3.0.9", "setuptools!=72.0.0", "wheel"] +requires = ["Cython>=3.0.11,<3.1", "setuptools", "wheel"] [tool.cibuildwheel] build-verbosity = 2 diff --git a/requirements.txt b/requirements.txt index 39f400d3..bfa36e23 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ -Cython>=3.0.9 -setuptools!=72.0.0 +Cython>=3.0.11,<3.1 +setuptools +wheel diff --git a/setup.py b/setup.py index d07f8cbf..9fab3d0d 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ except ImportError: from distutils.core import setup, Extension -VERSION = '2.2' +VERSION = '2.3' extra_setup_args = {} @@ -75,8 +75,6 @@ def cmd_output(command): def decode_path_output(s): - if sys.version_info[0] < 3: - return s # no need to decode, and safer not to do it # we don't really know in which encoding pkgconfig # outputs its results, so we try to guess for encoding in (sys.getfilesystemencoding(), @@ -422,34 +420,6 @@ def prepare_extensions(use_cython=True): if cythonize is not None: ext_modules = cythonize(ext_modules) - # Fix compiler warning due to missing pragma-push in Cython 3.0.9. - for ext in ext_modules: - for source_file in ext.sources: - if not os.path.basename(source_file).startswith('lua') or not source_file.endswith('.c'): - continue - with open(source_file, 'rb') as f: - lines = f.readlines() - if b'Generated by Cython 3.0.9' not in lines[0]: - continue - - modified = False - temp_file = source_file + ".tmp" - with open(temp_file, 'wb') as f: - last_was_push = False - for line in lines: - if b'#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"' in line and not last_was_push: - f.write(b"#pragma GCC diagnostic push\n") - modified = True - last_was_push = b'#pragma GCC diagnostic push' in line - f.write(line) - - if modified: - print("Fixed Cython 3.0.9 generated source file " + source_file) - os.unlink(source_file) - os.rename(temp_file, source_file) - else: - os.unlink(temp_file) - return ext_modules, ext_libraries @@ -509,17 +479,7 @@ def write_file(filename, content): 'Intended Audience :: Information Technology', 'License :: OSI Approved :: MIT License', 'Programming Language :: Cython', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', 'Programming Language :: Lua', 'Programming Language :: Other Scripting Engines', 'Operating System :: OS Independent', diff --git a/third-party/lua54 b/third-party/lua54 index 64431851..1ab3208a 160000 --- a/third-party/lua54 +++ b/third-party/lua54 @@ -1 +1 @@ -Subproject commit 6443185167c77adcc8552a3fee7edab7895db1a9 +Subproject commit 1ab3208a1fceb12fca8f24ba57d6e13c5bff15e3 diff --git a/third-party/luajit20 b/third-party/luajit20 index 4a22050d..e2e0b1dd 160000 --- a/third-party/luajit20 +++ b/third-party/luajit20 @@ -1 +1 @@ -Subproject commit 4a22050df9e76a28ef904382e4b4c69578973cd5 +Subproject commit e2e0b1dd2dcb180f9f4500eac0ad43aeb7ae0a81 diff --git a/third-party/luajit21 b/third-party/luajit21 index 93e87998..f73e649a 160000 --- a/third-party/luajit21 +++ b/third-party/luajit21 @@ -1 +1 @@ -Subproject commit 93e87998b24021b94de8d1c8db244444c46fb6e9 +Subproject commit f73e649a954b599fc184726c376476e7a5c439ca diff --git a/tox.ini b/tox.ini index 2bd84e89..5c6044fa 100644 --- a/tox.ini +++ b/tox.ini @@ -17,5 +17,5 @@ passenv= SETUP_OPTIONS commands= {envpython} setup.py --with-cython {env:SETUP_OPTIONS:} build install - {envpython} setup.py test + {envpython} -m lupa.tests.__main__ sitepackages=False