From d839d2318f3057bb9a6a3c2bcf10a124cb7d83c5 Mon Sep 17 00:00:00 2001 From: Adi Roiban Date: Wed, 29 Oct 2025 12:54:26 +0000 Subject: [PATCH 01/10] Initial code. --- .github/workflows/github-deploy.yml | 47 +++++++++++++++--------- .gitignore | 1 + CHANGELOG.rst | 7 ++-- README.rst | 57 +++++++++++++++++++++++++++++ pyproject.toml | 5 +++ setup.cfg | 2 +- setup.py | 22 ++++++++++- 7 files changed, 117 insertions(+), 24 deletions(-) diff --git a/.github/workflows/github-deploy.yml b/.github/workflows/github-deploy.yml index 2a92c8f..7794992 100644 --- a/.github/workflows/github-deploy.yml +++ b/.github/workflows/github-deploy.yml @@ -3,8 +3,13 @@ on: push: branches: - default - tags: - - v* + # To simplify the release process, the publishing is triggered on tag. + # We should make sure to only push tags for new releases. + # If we start using tags for non-release purposes, + # this needs to be updated. + # + # We need to explicitly configure an expression that matches anything. + tags: [ "**" ] pull_request: jobs: @@ -13,25 +18,25 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-20.04, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 name: Install Python with: - python-version: '3.9' + python-version: '3.14' - name: Install cibuildwheel run: | - python -m pip install cibuildwheel==2.1.1 + python -m pip install cibuildwheel==3.2.1 - name: Build wheels run: | python -m cibuildwheel --output-dir wheelhouse - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: path: ./wheelhouse/*.whl @@ -39,9 +44,9 @@ jobs: name: Build source distribution runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 name: Install Python with: python-version: '3.9' @@ -53,25 +58,31 @@ jobs: - name: Build sdist run: python -m build --sdist - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: path: dist/*.tar.gz upload_pypi: needs: [build_wheels, build_sdist] runs-on: ubuntu-latest + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write # upload to PyPI on every tag starting with 'v' if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') # alternatively, to publish when a GitHub Release is created, use the following rule: # if: github.event_name == 'release' && github.event.action == 'published' steps: - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4 with: - name: artifact + name: artifact-* + merge-multiple: true path: dist - - uses: pypa/gh-action-pypi-publish@master - with: - user: __token__ - password: ${{ secrets.pypi_password }} - # To test: repository_url: https://test.pypi.org/legacy/ + - name: Check files + run: ls -al dist/ + + - name: Publish to PyPI - on tag + # Skip upload to PyPI if we don't have a tag + if: startsWith(github.ref, 'refs/tags/') + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.gitignore b/.gitignore index ab0828f..b35069f 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ __pycache__/ build/ develop-eggs/ dist/ +wheelhouse/ downloads/ eggs/ .eggs/ diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b0eba74..c92dd3b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,10 +1,11 @@ Changelog ========= -1.0.3 (unreleased) ------------------- -- Nothing changed yet. +2025.10.0 (2025-10-29) +---------------------- + +- Enable wheels for Python 3.14. 1.0.2 (2021-08-10) diff --git a/README.rst b/README.rst index 61db375..79f0e04 100644 --- a/README.rst +++ b/README.rst @@ -1,2 +1,59 @@ +Introduction +============ + A trivial extension that just raises an exception. See L{twisted.test.test_failure.test_failureConstructionWithMungedStackSucceeds}. + +Only used to help test twisted/twisted. + +Report issues at https://github.com/twisted/twisted/issues + +Dev process +=========== + +* We use `cibuildwheel` to generate the wheels. +* You will need access to a Docker server. +* You will need Python 3.11 or newer to run cibuildwheel. + This does not affect the generated wheels, + as they are build inside the container. +* Use `python -m cibuildwheel --output-dir wheelhouse` to generate the wheels. + This is the same command use by GitHub Actions. + You can update the `pyproject.toml` file to adjust the cibuildwheel options. + + +Release process +=============== + + +Pre-release steps +----------------- + +* Make sure that a ticket is created for twisted/twisted that covers + the new release and explain why we need the new release. +* Create a new branch with a name that starts with the twisted/twisted + issue number. Ex: `12528-python-3.14-support` +* Update the version inside setup.cfg. We now use calendar versioning. +* Make the required code changes. +* Create a pull request and make sure all checks pass. + The wheels are generated as part of the PR checks, + but they are not yet published to PyPI. +* Request a review from `twisted-contributors` + + +Release steps +------------- + +* Use GitHub Release to create a new release together with a new tag. +* You don't have to create a GitHub Release, the important part is to + create a new tag. +* The tag value is the version. Without any prefix. +* Once a tag is pushed to the repo, GitHub Action will re-run all the jobs + and will publish to PyPI. + + +Post-release steps +------------------ + +* Update the version inside setup.cfg to the next development version. + Increment the micro version and add a .dev0 suffix. +* Merge the pull request \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 9630098..a054afe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,3 +5,8 @@ requires = [ "cython >= 0.29.21", ] build-backend = "setuptools.build_meta" + +[tool.cibuildwheel] +enable = ["all"] +# Not sure why it was failing on PyPy 3.11. +build = "cp38-* pp310-*" diff --git a/setup.cfg b/setup.cfg index 7c01d09..cf27537 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = cython-test-exception-raiser -version = 1.0.3.dev0 +version = 25.10.0 description = A trivial extension that just raises an exception. long_description = file: README.rst long_description_content_type = text/x-rst diff --git a/setup.py b/setup.py index 496fba8..dea577f 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,23 @@ -from setuptools import setup +from setuptools import Extension, setup from Cython.Build import cythonize +# Py_LIMITED_API values: +# +# 0x03080000 - Python 3.8 - the minimum version that Cython supports. +# 0x030B0000 - Python 3.11 - support typed memoryviews. +# 0x030C0000 - Python 3.12 - support vectorcall (performance improvement). -setup(ext_modules=cythonize("cython_test_exception_raiser/raiser.pyx")) +setup( + ext_modules=cythonize([ + Extension( + name="raiser", + sources=["cython_test_exception_raiser/raiser.pyx"], + define_macros=[ + # For now we are at python 3.8 as we still support 3.10. + ("Py_LIMITED_API", 0x03080000), + ], + py_limited_api=True + ), + ]), + #options={"bdist_wheel": {"py_limited_api": "cp38"}}, +) From 142f0201bef02f062da5f200bc372119bf8bbfb1 Mon Sep 17 00:00:00 2001 From: Adi Roiban Date: Wed, 29 Oct 2025 13:02:38 +0000 Subject: [PATCH 02/10] Add abi audit. --- .github/workflows/github-deploy.yml | 8 ++++++-- setup.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github-deploy.yml b/.github/workflows/github-deploy.yml index 7794992..f8f15e0 100644 --- a/.github/workflows/github-deploy.yml +++ b/.github/workflows/github-deploy.yml @@ -28,14 +28,18 @@ jobs: with: python-version: '3.14' - - name: Install cibuildwheel + - name: Install deps run: | - python -m pip install cibuildwheel==3.2.1 + python -m pip install cibuildwheel==3.2.1 abi3audit 0.0.22 - name: Build wheels run: | python -m cibuildwheel --output-dir wheelhouse + - name: Audit ABI3 wheels + run: | + abi3audit -vsS wheelhouse/*abi3*.whl + - uses: actions/upload-artifact@v4 with: path: ./wheelhouse/*.whl diff --git a/setup.py b/setup.py index dea577f..0b0486f 100644 --- a/setup.py +++ b/setup.py @@ -19,5 +19,5 @@ py_limited_api=True ), ]), - #options={"bdist_wheel": {"py_limited_api": "cp38"}}, + options={"bdist_wheel": {"py_limited_api": "cp38"}}, ) From f38163e31bce137d0016395077e445f862dde220 Mon Sep 17 00:00:00 2001 From: Adi Roiban Date: Wed, 29 Oct 2025 13:36:50 +0000 Subject: [PATCH 03/10] Fix abiaudit version. --- .github/workflows/github-deploy.yml | 3 ++- pyproject.toml | 1 + setup.py | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-deploy.yml b/.github/workflows/github-deploy.yml index f8f15e0..f26d5e5 100644 --- a/.github/workflows/github-deploy.yml +++ b/.github/workflows/github-deploy.yml @@ -17,6 +17,7 @@ jobs: name: Build wheels on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] @@ -30,7 +31,7 @@ jobs: - name: Install deps run: | - python -m pip install cibuildwheel==3.2.1 abi3audit 0.0.22 + python -m pip install cibuildwheel==3.2.1 abi3audit==0.0.22 - name: Build wheels run: | diff --git a/pyproject.toml b/pyproject.toml index a054afe..3e3308f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,5 +8,6 @@ build-backend = "setuptools.build_meta" [tool.cibuildwheel] enable = ["all"] +# See https://cibuildwheel.pypa.io/en/stable/options/#build-skip # Not sure why it was failing on PyPy 3.11. build = "cp38-* pp310-*" diff --git a/setup.py b/setup.py index 0b0486f..2f6614b 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,10 @@ from setuptools import Extension, setup from Cython.Build import cythonize +# ABI3 example from https://github.com/joerick/python-abi3-package-sample +# Cython docs at +# https://docs.cython.org/en/latest/src/userguide/limited_api.html +# # Py_LIMITED_API values: # # 0x03080000 - Python 3.8 - the minimum version that Cython supports. From e2fb692b6c7441233871a5dc6c7ac96f5e4d0c70 Mon Sep 17 00:00:00 2001 From: Adi Roiban Date: Wed, 29 Oct 2025 13:41:28 +0000 Subject: [PATCH 04/10] Fix artifact upload. --- .github/workflows/github-deploy.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/github-deploy.yml b/.github/workflows/github-deploy.yml index f26d5e5..a8cf1d9 100644 --- a/.github/workflows/github-deploy.yml +++ b/.github/workflows/github-deploy.yml @@ -37,12 +37,16 @@ jobs: run: | python -m cibuildwheel --output-dir wheelhouse + - name: Check files + run: ls -al wheelhouse/ + - name: Audit ABI3 wheels run: | abi3audit -vsS wheelhouse/*abi3*.whl - uses: actions/upload-artifact@v4 with: + name: artifact-wheels path: ./wheelhouse/*.whl build_sdist: @@ -65,6 +69,7 @@ jobs: - uses: actions/upload-artifact@v4 with: + name: artifact-sdist path: dist/*.tar.gz upload_pypi: From 33419ef01f73f3330f75a645b21aad980d60df40 Mon Sep 17 00:00:00 2001 From: Adi Roiban Date: Wed, 29 Oct 2025 13:49:30 +0000 Subject: [PATCH 05/10] Fix artifacts conflict. Use bash on Windows. --- .github/workflows/github-deploy.yml | 9 ++++++++- pyproject.toml | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-deploy.yml b/.github/workflows/github-deploy.yml index a8cf1d9..7296c38 100644 --- a/.github/workflows/github-deploy.yml +++ b/.github/workflows/github-deploy.yml @@ -12,6 +12,13 @@ on: tags: [ "**" ] pull_request: + +defaults: + run: + # Use bash on Windows for consistency. + shell: bash + + jobs: build_wheels: name: Build wheels on ${{ matrix.os }} @@ -46,7 +53,7 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: artifact-wheels + name: artifact-wheels-${{ matrix.os }} path: ./wheelhouse/*.whl build_sdist: diff --git a/pyproject.toml b/pyproject.toml index 3e3308f..3769af4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,6 +7,8 @@ requires = [ build-backend = "setuptools.build_meta" [tool.cibuildwheel] +# We enable all builds and then cherry-pick the platforms via the `build` +# configuration below. enable = ["all"] # See https://cibuildwheel.pypa.io/en/stable/options/#build-skip # Not sure why it was failing on PyPy 3.11. From a6000c2a3e58af11dc020512a9bd4c00adc87c5a Mon Sep 17 00:00:00 2001 From: Adi Roiban Date: Wed, 29 Oct 2025 13:55:05 +0000 Subject: [PATCH 06/10] Also run the upload job to check the downloaded files. --- .github/workflows/github-deploy.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/github-deploy.yml b/.github/workflows/github-deploy.yml index 7296c38..a56a9b2 100644 --- a/.github/workflows/github-deploy.yml +++ b/.github/workflows/github-deploy.yml @@ -85,10 +85,6 @@ jobs: permissions: # IMPORTANT: this permission is mandatory for trusted publishing id-token: write - # upload to PyPI on every tag starting with 'v' - if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') - # alternatively, to publish when a GitHub Release is created, use the following rule: - # if: github.event_name == 'release' && github.event.action == 'published' steps: - uses: actions/download-artifact@v4 with: From 7e164d39c248c7121f974784aa60f68680e3f335 Mon Sep 17 00:00:00 2001 From: Adi Roiban Date: Wed, 29 Oct 2025 14:42:11 +0000 Subject: [PATCH 07/10] Fix wheel collection before upload to PyPi --- .github/workflows/github-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-deploy.yml b/.github/workflows/github-deploy.yml index a56a9b2..cc0af6a 100644 --- a/.github/workflows/github-deploy.yml +++ b/.github/workflows/github-deploy.yml @@ -88,7 +88,7 @@ jobs: steps: - uses: actions/download-artifact@v4 with: - name: artifact-* + pattern: artifact-* merge-multiple: true path: dist From 57ae707c67059d31918b765c4afc8e635f4ef85a Mon Sep 17 00:00:00 2001 From: Adi Roiban Date: Thu, 30 Oct 2025 17:53:42 +0000 Subject: [PATCH 08/10] Update minimum python. Update classifiers. --- setup.cfg | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index cf27537..ac80b6b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,15 +10,17 @@ maintainer = Thomas Grainger maintainer_email = cython-test-exception-raiser@graingert.co.uk url = https://github.com/twisted/cython-test-exception-raiser license = MIT -python_requires = >=3.6 +python_requires = >=3.8 classifiers = Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only - 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 :: Python :: 3.13 + Programming Language :: Python :: 3.14 [options] packages = find: From 07893165d703c8aec3f9a741bc3a107103033d61 Mon Sep 17 00:00:00 2001 From: Adi Roiban Date: Sun, 2 Nov 2025 10:33:51 +0000 Subject: [PATCH 09/10] Prepare release --- CHANGELOG.rst | 4 ++-- setup.cfg | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c92dd3b..4bb59b9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,10 +2,10 @@ Changelog ========= -2025.10.0 (2025-10-29) +2025.11.0 (2025-11-02) ---------------------- -- Enable wheels for Python 3.14. +- Enable ABI3 binary wheels for generic Python support. 1.0.2 (2021-08-10) diff --git a/setup.cfg b/setup.cfg index ac80b6b..292b77d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = cython-test-exception-raiser -version = 25.10.0 +version = 25.11.0 description = A trivial extension that just raises an exception. long_description = file: README.rst long_description_content_type = text/x-rst From ed356acc60d60040ce555454c6f63f558161dfc9 Mon Sep 17 00:00:00 2001 From: Adi Roiban Date: Sun, 2 Nov 2025 11:41:21 +0000 Subject: [PATCH 10/10] Updaet dev version --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 292b77d..7144f82 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = cython-test-exception-raiser -version = 25.11.0 +version = 25.11.1.dev0 description = A trivial extension that just raises an exception. long_description = file: README.rst long_description_content_type = text/x-rst