diff --git a/.ci/osx_ci.sh b/.ci/osx_ci.sh deleted file mode 100644 index 8cdd1ac..0000000 --- a/.ci/osx_ci.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -set -e -x - -arm64_set_path_and_python_version(){ - python_version="$1" - if [[ $(/usr/bin/arch) = arm64 ]]; then - export PATH=/opt/homebrew/bin:$PATH - eval "$(pyenv init --path)" - pyenv install $python_version -s - pyenv global $python_version - export PATH=$(pyenv prefix)/bin:$PATH - fi -} \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index cb8b9e3..3a8741f 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -8,20 +8,20 @@ jobs: runs-on: macos-latest env: CIBW_BUILD_VERBOSITY: 3 - CIBW_BUILD: cp3{6,7,8,9,10}-* - CIBW_ARCHS: "x86_64 universal2 arm64" + CIBW_BUILD: "cp37-macosx_x86_64 cp38-macosx_universal2 cp39-macosx_universal2 cp310-macosx_universal2 cp311-macosx_universal2 cp312-macosx_universal2" + CIBW_ARCHS_MACOS: "x86_64 universal2" CIBW_TEST_COMMAND: python -c "from pyobjus import autoclass, objc_str" CIBW_TEST_SKIP: "*arm64*" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install dependencies - run: python -m pip install --upgrade twine cibuildwheel cython + run: python -m pip install --upgrade twine cibuildwheel~=2.16.2 cython setuptools - name: Build sdist run: | @@ -32,14 +32,14 @@ jobs: python -m cibuildwheel --output-dir dist - name: Create artifacts - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: wheels path: dist - name: Upload to GitHub Releases if: startsWith(github.ref, 'refs/tags/') - uses: softprops/action-gh-release@v0.1.14 + uses: softprops/action-gh-release@v2.0.8 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/no-reponse.yml b/.github/workflows/no-reponse.yml new file mode 100644 index 0000000..f34d064 --- /dev/null +++ b/.github/workflows/no-reponse.yml @@ -0,0 +1,30 @@ +name: No Response + +# Both `issue_comment` and `scheduled` event types are required for this Action +# to work properly. +on: + issue_comment: + types: [created] + schedule: + # Schedule for five minutes after the hour, every hour + - cron: '5 * * * *' + +jobs: + noResponse: + runs-on: ubuntu-latest + steps: + - uses: lee-dohm/no-response@9bb0a4b5e6a45046f00353d5de7d90fb8bd773bb + # This commit hash targets release v0.5.0 of lee-dohm/no-response. + # Targeting a commit hash instead of a tag has been done for security reasons. + # Please be aware that the commit hash specifically targets the "Automatic compilation" + # done by `github-actions[bot]` as the `no-response` Action needs to be compiled. + with: + token: ${{ github.token }} + daysUntilClose: 42 + responseRequiredLabel: 'awaiting-reply' + closeComment: > + This issue has been automatically closed because there has been no response + to our request for more information from the original author. With only the + information that is currently in the issue, we don't have the means + to take action. Please reach out if you have or find the answers we need so + that we can investigate further. diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 53a56e6..3026df8 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -5,48 +5,40 @@ on: [push, pull_request] jobs: build: - name: "build (${{ matrix.runs_on }}, ${{ matrix.python }})" - defaults: - run: - shell: ${{ matrix.run_wrapper || 'bash --noprofile --norc -eo pipefail {0}' }} - runs-on: ${{ matrix.runs_on || 'macos-latest' }} + 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: apple-silicon-m1 - run_wrapper: arch -arm64 bash --noprofile --norc -eo pipefail {0} - python: "3.9.11" - - runs_on: apple-silicon-m1 - run_wrapper: arch -arm64 bash --noprofile --norc -eo pipefail {0} - python: "3.10.3" + # macos-latest (ATM macos-14) runs on Apple Silicon, + # macos-13 runs on Intel + runs_on: ['macos-latest', 'macos-13'] + python: + - "3.8" + - "3.9" + - "3.10" + - "3.11" + - "3.12" + cython: + - "<3" + - ">=3" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python }} - # Needs to be skipped on our self-hosted runners tagged as 'apple-silicon-m1' - if: ${{ matrix.runs_on != 'apple-silicon-m1' }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 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 - arm64_set_path_and_python_version ${{ matrix.python }} - pip install cython pytest + pip install cython pytest setuptools pip install . - name: Test with pytest run: | - source .ci/osx_ci.sh - arm64_set_path_and_python_version ${{ matrix.python }} make test_lib make make tests diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..b5f396b --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,16 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3" + +python: + install: + - requirements: docs/requirements.txt + +sphinx: + configuration: docs/source/conf.py diff --git a/README.md b/README.md index d69c71e..676c3dd 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,9 @@ If you need assistance, you can ask for help on our mailing list: * User Group : https://groups.google.com/group/kivy-users * Email : kivy-users@googlegroups.com -We also have an IRC channel: +We also have a Discord server: -* Server : irc.freenode.net -* Port : 6667, 6697 (SSL only) -* Channel : #kivy +[https://chat.kivy.org/](https://chat.kivy.org/) ## Contributing diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..f355c8b --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +Sphinx~=8.0.2 +furo==2024.8.6 \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 594d8aa..0cb9604 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -11,7 +11,9 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import datetime +import os +import re # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -40,17 +42,33 @@ master_doc = 'index' # General information about the project. -project = u'Pyobjus' -copyright = u'2012, Mathieu Virbel, Gabriel Pettier' +project = 'pyobjus' + +_today = datetime.datetime.now() + +copyright = f'{_today.year}, Mathieu Virbel, Gabriel Pettier' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # + +# Lookup the version from the pyobjus module, without installing it +# since readthedocs.org may have issue to install it. +# Read the version from the __init__.py file, without importing it. +def get_version(): + with open( + os.path.join(os.path.abspath("../.."), "pyobjus", "__init__.py") + ) as fp: + for line in fp: + m = re.search(r'^\s*__version__\s*=\s*([\'"])([^\'"]+)\1\s*$', line) + if m: + return m.group(2) + # The short X.Y version. -version = '1.0' +version = get_version() # The full version, including alpha/beta/rc tags. -release = '1.0a1' +release = get_version() # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -91,7 +109,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = 'furo' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/pyobjus/__init__.py b/pyobjus/__init__.py index 713d1fe..98ef21f 100644 --- a/pyobjus/__init__.py +++ b/pyobjus/__init__.py @@ -1,2 +1,2 @@ -__version__ = '1.2.2.dev0' +__version__ = '1.2.4.dev0' from .pyobjus import * diff --git a/pyobjus/pyobjus.pyx b/pyobjus/pyobjus.pyx index 03ea6a6..b7589ea 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(): @@ -430,8 +435,8 @@ cdef class ObjcMethod(object): if res_ptr == NULL: raise MemoryError('Unable to allocate res_ptr') - if not self.signature_return.startswith((b'(', b'{')): - ffi_call(&self.f_cif, objc_msgSend, res_ptr, f_args) + if not self.signature_return[0].startswith((b'(', b'{')): + 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/renovate.json b/renovate.json new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} diff --git a/setup.py b/setup.py index 3800269..9ebd636 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,13 @@ 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) + if dev_platform == 'ios': + cython3 = False # Assume Cython 0.29, which is what we use for kivy-ios (ATM) + else: + 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 @@ -134,10 +140,11 @@ def tree(source, allowed_ext=data_allowed_ext, tree_name='share/pyobjus-'): 'License :: OSI Approved :: MIT License', 'Natural Language :: English', 'Operating System :: MacOS', - 'Programming Language :: Python :: 2.7', - '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', 'Topic :: Software Development :: Libraries :: Application Frameworks' ], )