From 00faedb0ec6615f7993df152000106dd01237d7f Mon Sep 17 00:00:00 2001 From: Mirko Galimberti Date: Thu, 5 Oct 2023 20:21:35 +0200 Subject: [PATCH] Add support for Cython >=3 and keep support for Cython < 3 --- .github/workflows/python-package.yml | 35 +++++++++++++++------------- pyobjus/pyobjus.pyx | 17 +++++++++----- pyobjus/pyobjus_types.pxi | 2 +- setup.py | 5 +++- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index f1f06ab..380e01b 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -5,27 +5,27 @@ on: [push, pull_request] jobs: build: - name: "build (${{ matrix.runs_on }}, ${{ matrix.python }})" + name: "build (${{ matrix.runs_on }}, ${{ matrix.python }} - Cython ${{ matrix.cython }})" runs-on: ${{ matrix.runs_on }} strategy: matrix: - include: - - runs_on: macos-latest - python: "3.7" - - runs_on: macos-latest - python: "3.8" - - runs_on: macos-latest - python: "3.9" - - runs_on: macos-latest - python: "3.10" - - runs_on: macos-latest - python: "3.11" - - runs_on: apple-silicon-m1 - python: "3.9" + runs_on: + - macos-latest + - apple-silicon-m1 + python: + - "3.7" + - "3.8" + - "3.9" + - "3.10" + - "3.11" + cython: + - "<3" + - ">=3" + exclude: - runs_on: apple-silicon-m1 - python: "3.10" + python: "3.7" - runs_on: apple-silicon-m1 - python: "3.11" + python: "3.8" steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python }} @@ -35,6 +35,9 @@ jobs: with: python-version: ${{ matrix.python }} + - name: Force Cython version + run: sed -i.bak 's/"Cython"/"Cython${{matrix.cython}}"/' pyproject.toml + - name: Install project run: | source .ci/osx_ci.sh diff --git a/pyobjus/pyobjus.pyx b/pyobjus/pyobjus.pyx index 4dfda18..b007a96 100644 --- a/pyobjus/pyobjus.pyx +++ b/pyobjus/pyobjus.pyx @@ -49,6 +49,11 @@ from libcpp cimport bool # library files include "config.pxi" + +# from Cython 3.0, in the MetaJavaClass, this is accessed as _JavaClass__cls_storage +# see https://cython.readthedocs.io/en/latest/src/userguide/migrating_to_cy30.html#class-private-name-mangling +cdef CLS_STORAGE_NAME = '_JavaClass__cls_storage' if PYOBJUS_CYTHON_3 else '__cls_storage' + include "debug.pxi" include "common.pxi" include "type_enc.pxi" @@ -129,7 +134,7 @@ class MetaObjcClass(type): raise ObjcException('Unable to find class {0!r}'.format( __objcclass__)) - classDict['__cls_storage'] = storage + classDict[CLS_STORAGE_NAME] = storage cdef ObjcMethod om for name, value in classDict.iteritems(): @@ -431,7 +436,7 @@ cdef class ObjcMethod(object): raise MemoryError('Unable to allocate res_ptr') if not self.signature_return[0].startswith((b'(', b'{')): - ffi_call(&self.f_cif, objc_msgSend, res_ptr, f_args) + ffi_call(&self.f_cif, objc_msgSend, res_ptr, f_args) else: # TODO FIXME NOTE: Currently this only work on x86_64 architecture and armv7 ios @@ -460,20 +465,20 @@ cdef class ObjcMethod(object): stret = True if stret and MACOS_HAVE_OBJMSGSEND_STRET: - ffi_call(&self.f_cif, objc_msgSend_stret__safe, res_ptr, f_args) + ffi_call(&self.f_cif, objc_msgSend_stret__safe, res_ptr, f_args) fun_name = "objc_msgSend_stret" del_res_ptr = False else: - ffi_call(&self.f_cif, objc_msgSend, res_ptr, f_args) + ffi_call(&self.f_cif, objc_msgSend, res_ptr, f_args) fun_name = "objc_msgSend" dprint("x86_64 architecture {0} call".format(fun_name), of_type='i') ELIF PLATFORM == 'ios': IF ARCH == 'arm64': - ffi_call(&self.f_cif, objc_msgSend, res_ptr, f_args) + ffi_call(&self.f_cif, objc_msgSend, res_ptr, f_args) dprint('ios(arm64) platform objc_msgSend call') ELSE: - ffi_call(&self.f_cif, objc_msgSend_stret, res_ptr, f_args) + ffi_call(&self.f_cif, objc_msgSend_stret, res_ptr, f_args) dprint('ios(armv7) platform objc_msgSend_stret call') ELSE: diff --git a/pyobjus/pyobjus_types.pxi b/pyobjus/pyobjus_types.pxi index 2345782..34c0b0f 100644 --- a/pyobjus/pyobjus_types.pxi +++ b/pyobjus/pyobjus_types.pxi @@ -612,7 +612,7 @@ cdef class ObjcClassInstance: super(ObjcClassInstance, self).__init__() cdef ObjcClassStorage storage if 'getcls' not in kwargs: - storage = self.__cls_storage + storage = getattr(self, CLS_STORAGE_NAME) self.o_cls = storage.o_cls if 'noinstance' not in kwargs: diff --git a/setup.py b/setup.py index 61ae110..d34e39e 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,10 @@ def build_extensions(self): config_pxi_fn = join(dirname(__file__), 'pyobjus', 'config.pxi') config_pxi_need_update = True config_pxi = 'DEF PLATFORM = "{}"\n'.format(dev_platform) - config_pxi += 'DEF ARCH = "{}"'.format(arch) + config_pxi += 'DEF ARCH = "{}"\n'.format(arch) + import Cython + cython3 = Cython.__version__.startswith('3.') + config_pxi += f"DEF PYOBJUS_CYTHON_3 = {cython3}" if exists(config_pxi_fn): with open(config_pxi_fn) as fd: config_pxi_need_update = fd.read() != config_pxi