From 7691bbd09f459183611c40a928d44978f3304577 Mon Sep 17 00:00:00 2001 From: Min RK Date: Mon, 2 Dec 2024 16:01:50 +0100 Subject: [PATCH] wip: limited api wheels --- .github/workflows/wheels.yml | 2 +- CMakeLists.txt | 14 ++++++++++++-- pyproject.toml | 15 ++++++++++++--- zmq/backend/cython/_cpython.pxd | 10 ++++++++++ zmq/backend/cython/_zmq.py | 23 +++++++++++++++++------ zmq/utils/mutex.h | 2 ++ 6 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 zmq/backend/cython/_cpython.pxd diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 59fc5a642..ede2fca0d 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -64,7 +64,7 @@ jobs: env: MACOSX_DEPLOYMENT_TARGET: "10.9" CIBW_BUILD: "${{ matrix.cibw.build || '*' }}" - CIBW_SKIP: "${{ matrix.cibw.skip || '' }}" + CIBW_SKIP: "cp38-* cp39-* cp310-* cp311-* cp313-* ${{ matrix.cibw.skip || '' }}" CIBW_ARCHS: "${{ matrix.cibw.arch || 'auto' }}" CIBW_MANYLINUX_X86_64_IMAGE: "${{ matrix.cibw.manylinux_x86_64_image || '' }}" diff --git a/CMakeLists.txt b/CMakeLists.txt index bc02c21b8..595ded455 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,13 +5,13 @@ set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) find_package( Python - COMPONENTS Interpreter Development.Module + COMPONENTS Interpreter Development.Module ${SKBUILD_SABI_COMPONENT} REQUIRED) # Python_SOABI isn't always right when cross-compiling # SKBUILD_SOABI seems to be if (DEFINED SKBUILD_SOABI AND NOT "${SKBUILD_SOABI}" STREQUAL "${Python_SOABI}") - message(WARNING "SKBUILD_SOABI=${SKBUILD_SOABI} != Python_SOABI=${Python_SOABI}; likely cross-compiling, using SOABI=${SKBUILD_SOABI} from scikit-build") + message(WARNING "SKBUILD_SOABI=${SKBUILD_SOABI} != Python_SOABI=${Python_SOABI}; likely cross-compiling or Limited API, using SOABI=${SKBUILD_SOABI} from scikit-build") set(Python_SOABI "${SKBUILD_SOABI}") endif() @@ -404,9 +404,19 @@ endif() file(MAKE_DIRECTORY ${ZMQ_BACKEND_DEST}) +if(NOT "${SKBUILD_SABI_COMPONENT}" STREQUAL "") + # set stable API + # assume we are targeting >= current Python version + # this isn't required, but we can't seem to get `wheel.py-api + message("SKBUILD_LIMITED_API=${SKBUILD_LIMITED_API}") + set(SABI_ARG "USE_SABI;${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}") + message("Building with stable API ${SABI_ARG} for ${Python_SOABI}") +endif() + python_add_library( ${ZMQ_EXT_NAME} MODULE WITH_SOABI + ${SABI_ARG} ${ZMQ_C} ) diff --git a/pyproject.toml b/pyproject.toml index 5bbc5cc91..8b84260d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,9 +2,9 @@ [build-system] requires = [ "cffi; implementation_name == 'pypy'", - "cython>=3.0.0; implementation_name != 'pypy'", + "cython>=3.1.0a1; implementation_name != 'pypy'", "packaging", - "scikit-build-core", + "scikit-build-core>=0.10", ] build-backend = "scikit_build_core.build" @@ -56,7 +56,7 @@ wheel.license-files = ["licenses/LICENSE*"] # 3.15 is required by scikit-build-core cmake.version = ">=3.15" # only build/install the pyzmq component -cmake.targets = ["pyzmq"] +build.targets = ["pyzmq"] install.components = ["pyzmq"] [tool.ruff] @@ -202,6 +202,15 @@ select = "cp3{7,8,9}-* pp3{7,8}-*" manylinux-x86_64-image = "manylinux2010" manylinux-i686-image = "manylinux2010" +# build limited-api wheels for 3.7, 3.12 +[[tool.cibuildwheel.overrides]] +config-settings = { wheel = { py-api = "cp312" } } +select = "cp312-*" + +[[tool.cibuildwheel.overrides]] +config-settings = { wheel = { py-api = "cp37" } } +select = "cp37-*" + # note: manylinux_2_28 builds are added # in .github/workflows/wheels.yml diff --git a/zmq/backend/cython/_cpython.pxd b/zmq/backend/cython/_cpython.pxd new file mode 100644 index 000000000..b37f4645d --- /dev/null +++ b/zmq/backend/cython/_cpython.pxd @@ -0,0 +1,10 @@ +# These should be cimported from cpython.bytes +# but that has a transitive import of cpython.type +# which currently conflicts with limited API +cdef extern from "Python.h": + # cpython.bytes + char* PyBytes_AsString(object string) except NULL + bytes PyBytes_FromStringAndSize(char *v, Py_ssize_t len) + Py_ssize_t PyBytes_Size(object string) except -1 + # cpython.exc + int PyErr_CheckSignals() except -1 diff --git a/zmq/backend/cython/_zmq.py b/zmq/backend/cython/_zmq.py index 8cac83bee..c85ff703b 100644 --- a/zmq/backend/cython/_zmq.py +++ b/zmq/backend/cython/_zmq.py @@ -56,12 +56,15 @@ size_t, sizeof, ) -from cython.cimports.cpython import ( - PyBytes_AsString, - PyBytes_FromStringAndSize, - PyBytes_Size, - PyErr_CheckSignals, -) + +# Cannot cimport these with Limited API yet +# see https://github.com/cython/cython/issues/5634 +# from cython.cimports.cpython.bytes import ( +# PyBytes_AsString, +# PyBytes_FromStringAndSize, +# PyBytes_Size, +# ) +# from cython.cimports.cpython.exc import PyErr_CheckSignals from cython.cimports.libc.errno import EAGAIN, EINTR, ENAMETOOLONG, ENOENT, ENOTSOCK # cimports require Cython 3 @@ -70,6 +73,14 @@ from cython.cimports.libc.stdio import stderr as cstderr from cython.cimports.libc.stdlib import free, malloc from cython.cimports.libc.string import memcpy + +# these should be from cython.cimports.cpython +from cython.cimports.zmq.backend.cython._cpython import ( + PyBytes_AsString, + PyBytes_FromStringAndSize, + PyBytes_Size, + PyErr_CheckSignals, +) from cython.cimports.zmq.backend.cython._externs import ( get_ipc_path_max_len, getpid, diff --git a/zmq/utils/mutex.h b/zmq/utils/mutex.h index 2191d08d1..b6275ea28 100644 --- a/zmq/utils/mutex.h +++ b/zmq/utils/mutex.h @@ -9,6 +9,8 @@ #pragma once +#include + #if defined(_WIN32) # include #else