From 2b6f951ea58d17f830bd0e4c142aa41742a4dda5 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Mon, 1 Dec 2025 12:19:14 +0000 Subject: [PATCH 1/7] require 3.10; simplify build to always use Cython via isolated builds Remove the 'dev' file mechanism that switched between development mode (Cython) and distribution mode (pre-generated .cpp). With pyproject.toml declaring Cython as a build dependency, modern pip installs it automatically in an isolated build environment. Python 3.9 is EOL so we require >=3.10 --- README.rst | 43 ++++++------------------------------------- dev | 0 setup.py | 50 +++++++++----------------------------------------- 3 files changed, 15 insertions(+), 78 deletions(-) delete mode 100644 dev diff --git a/README.rst b/README.rst index 4ca5f93..8e2cd1d 100644 --- a/README.rst +++ b/README.rst @@ -10,9 +10,6 @@ Pyclipper is a Cython wrapper exposing public functions and classes of the C++ translation of the `Angus Johnson's Clipper library (ver. 6.4.2) `__. -Pyclipper releases were tested with Python 2.7 and 3.4 on Linux (Ubuntu -14.04, x64) and Windows (8.1, x64). - Source code is available on `GitHub `__. The package is published on `PyPI `__. @@ -35,45 +32,17 @@ About Clipper Install ======= -Dependencies ------------- - -Cython dependency is optional. Cpp sources generated with Cython are -available in releases. - -Note on using the ``setup.py``: - -``setup.py`` operates in 2 modes that are based on the presence of the -``dev`` file in the root of the project. - -- When ``dev`` is **present**, Cython will be used to compile the ``.pyx`` - sources. This is the *development mode* (as you get it in the git - repository). -- When ``dev`` is **absent**, C/C++ compiler will be used to compile the - ``.cpp`` sources (that were prepared in in the development mode). - This is the distribution mode (as you get it on PyPI). - -This way the package can be used without or with an incompatible version -of Cython. - -The idea comes from `Matt Shannon's bandmat -library `__. - From PyPI --------- -Cython not required. - :: pip install pyclipper - + From source ----------- -Cython required. - Clone the repository: :: @@ -85,15 +54,13 @@ Install: :: - python setup.py install - + pip install . -After every modification of ``.pyx`` files compile with Cython: +For development, use an editable install: :: - python setup.py build_ext --inplace - + pip install -e . Clippers' preprocessor directives --------------------------------- @@ -196,6 +163,8 @@ License Changelog ========= +For recent versions, see the `GitHub Releases page `__. + 1.1.0 ------- diff --git a/dev b/dev deleted file mode 100644 index e69de29..0000000 diff --git a/setup.py b/setup.py index 899bdd1..db44b83 100755 --- a/setup.py +++ b/setup.py @@ -1,48 +1,10 @@ -from __future__ import print_function import sys -import os from setuptools import setup, find_packages from setuptools.extension import Extension -from io import open +from Cython.Distutils import build_ext -""" -Note on using the setup.py: -setup.py operates in 2 modes that are based on the presence of the 'dev' file in the root of the project. - - When 'dev' is present, Cython will be used to compile the .pyx sources. This is the development mode - (as you get it in the git repository). - - When 'dev' is absent, C/C++ compiler will be used to compile the .cpp sources (that were prepared in - in the development mode). This is the distribution mode (as you get it on PyPI). - -This way the package can be used without or with an incompatible version of Cython. - -The idea comes from: https://github.com/MattShannon/bandmat -""" -dev_mode = os.path.exists('dev') - -if dev_mode: - from Cython.Distutils import build_ext - - print('Development mode: Compiling Cython modules from .pyx sources.') - sources = ["src/pyclipper/_pyclipper.pyx", "src/clipper.cpp"] - - from setuptools.command.sdist import sdist as _sdist - - class sdist(_sdist): - """ Run 'cythonize' on *.pyx sources to ensure the .cpp files included - in the source distribution are up-to-date. - """ - def run(self): - from Cython.Build import cythonize - cythonize(sources, language_level="2") - _sdist.run(self) - - cmdclass = {'sdist': sdist, 'build_ext': build_ext} - -else: - print('Distribution mode: Compiling Cython generated .cpp sources.') - sources = ["src/pyclipper/_pyclipper.cpp", "src/clipper.cpp"] - cmdclass = {} +sources = ["src/pyclipper/_pyclipper.pyx", "src/clipper.cpp"] needs_pytest = {'pytest', 'test'}.intersection(sys.argv) pytest_runner = ['pytest_runner'] if needs_pytest else [] @@ -76,9 +38,15 @@ def run(self): url='https://github.com/greginvm/pyclipper', keywords=[ 'polygon clipping, polygon intersection, polygon union, polygon offsetting, polygon boolean, polygon, clipping, clipper, vatti'], + python_requires=">=3.10", classifiers=[ "Programming Language :: Python", "Programming Language :: Python :: 3", + "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", "Programming Language :: Cython", "Programming Language :: C++", "Environment :: Other Environment", @@ -99,5 +67,5 @@ def run(self): 'setuptools_scm>=1.11.1', ] + pytest_runner, tests_require=['pytest'], - cmdclass=cmdclass, + cmdclass={'build_ext': build_ext}, ) From 8a8fa8bb789054b1c304885a2058f9a12b622440 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Mon, 1 Dec 2025 12:25:46 +0000 Subject: [PATCH 2/7] build Linux arm64 wheels on native runners without qemu --- .github/workflows/ci.yml | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a99e670..23a95e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,31 +92,26 @@ jobs: name: wheels-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.type }} build_arch_wheels: - name: py${{ matrix.python }} on ${{ matrix.arch }} - runs-on: ubuntu-latest - strategy: - matrix: - # aarch64 uses qemu so it's slow, build each py version in parallel jobs - python: [310, 311, 312, 313, 314] - arch: [aarch64] + name: Build wheels on Linux ARM64 + runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: docker/setup-qemu-action@v1.2.0 + - name: Set up Python + uses: actions/setup-python@v5 with: - platforms: all + python-version: "3.x" - name: Install dependencies run: pip install cibuildwheel - name: Build Wheels run: python -m cibuildwheel --output-dir wheelhouse . env: - CIBW_BUILD: cp${{ matrix.python }}-manylinux* - CIBW_ARCHS: ${{ matrix.arch }} + CIBW_BUILD: "cp310-manylinux* cp311-manylinux* cp312-manylinux* cp313-manylinux* cp314-manylinux*" - uses: actions/upload-artifact@v4 with: path: wheelhouse/*.whl - name: wheels-${{ matrix.arch }}-${{ matrix.python }} + name: wheels-linux-arm64 deploy: name: Upload if tagged commit From 1da889bfd923dd52a33ec6f712ff3076b5a4a5d9 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Mon, 1 Dec 2025 12:28:34 +0000 Subject: [PATCH 3/7] Use PyPI trusted publishing to upload wheels --- .github/workflows/ci.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23a95e5..b44c237 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -119,6 +119,9 @@ jobs: # but only if all build jobs completed successfully needs: [build_wheels, build_arch_wheels, build_sdist] runs-on: ubuntu-latest + permissions: + id-token: write + contents: write steps: - uses: actions/checkout@v4 @@ -158,7 +161,5 @@ jobs: draft: false prerelease: ${{ env.IS_PRERELEASE }} - - uses: pypa/gh-action-pypi-publish@v1.4.2 - with: - user: __token__ - password: ${{ secrets.PYPI_PASSWORD }} + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 From cfd01539e8cffc781a37a9675380bc37e29af20f Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Mon, 1 Dec 2025 12:36:31 +0000 Subject: [PATCH 4/7] remove unused MANIFEST.in; setiptools_scm handles version-controlled files automatically --- MANIFEST.in | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index f3b346d..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,14 +0,0 @@ -# By default setuptools_scm will include in the source distribution all the -# files under version control, as resulting from `git ls-files`. - -# Here we only need to include those which are not tracked by git but we do -# want to be included -include src/pyclipper/_pyclipper.cpp - -# and exclude those that are tracked by git but don't want to be in the sdist -exclude dev -exclude .git* -exclude .appveyor.yml .travis.yml -exclude .appveyor/* -exclude multibuild/* -exclude config.sh From ff707f7a3bcfa9a59fb921a807f111bd57ea4dc5 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Mon, 1 Dec 2025 12:37:13 +0000 Subject: [PATCH 5/7] setup.py: fix URL, remove deprecated old cruft --- setup.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/setup.py b/setup.py index db44b83..209dacc 100755 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ -import sys from setuptools import setup, find_packages from setuptools.extension import Extension from Cython.Distutils import build_ext @@ -6,9 +5,6 @@ sources = ["src/pyclipper/_pyclipper.pyx", "src/clipper.cpp"] -needs_pytest = {'pytest', 'test'}.intersection(sys.argv) -pytest_runner = ['pytest_runner'] if needs_pytest else [] - ext = Extension("pyclipper._pyclipper", sources=sources, @@ -35,7 +31,7 @@ maintainer="Cosimo Lupo", maintainer_email="cosimo@anthrotype.com", license='MIT', - url='https://github.com/greginvm/pyclipper', + url='https://github.com/fonttools/pyclipper', keywords=[ 'polygon clipping, polygon intersection, polygon union, polygon offsetting, polygon boolean, polygon, clipping, clipper, vatti'], python_requires=">=3.10", @@ -62,10 +58,5 @@ package_dir={"": "src"}, packages=find_packages(where="src"), ext_modules=[ext], - setup_requires=[ - 'cython>=0.28', - 'setuptools_scm>=1.11.1', - ] + pytest_runner, - tests_require=['pytest'], cmdclass={'build_ext': build_ext}, ) From 4689918f52bc47c7074c9daae8f688e52002600e Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Mon, 1 Dec 2025 12:38:09 +0000 Subject: [PATCH 6/7] remove setup.cfg and move pytest config to pyproject.toml --- pyproject.toml | 5 ++++- setup.cfg | 13 ------------- 2 files changed, 4 insertions(+), 14 deletions(-) delete mode 100644 setup.cfg diff --git a/pyproject.toml b/pyproject.toml index 591a65e..01ad352 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,5 +5,8 @@ requires = [ "setuptools_scm", "cython", ] - build-backend = "setuptools.build_meta" + +[tool.pytest.ini_options] +testpaths = ["tests"] +addopts = "-v -ra" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 3202007..0000000 --- a/setup.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[metadata] -description_file = README.rst - -[aliases] -test = pytest - -[tool:pytest] -testpaths = tests -addopts = - # run py.test in verbose mode - -v - # show extra test summary info - -r a From bb60146f2106d4458195a6ae1585eea75f079a68 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Mon, 1 Dec 2025 12:38:24 +0000 Subject: [PATCH 7/7] ci: use macos-15-intel as macos-13 runner is deprecated --- .github/workflows/ci.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b44c237..30cb771 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,9 +44,8 @@ jobs: strategy: fail-fast: false matrix: - # macos-13 runners are still x86_64, macos-14 (latest) are arm64; we want to build - # the x86_64 wheel on/for x86_64 macs - os: [macos-13, windows-latest] + # macos-15-intel is x86_64; macos-latest is arm64 + os: [macos-15-intel, windows-latest] arch: [auto64] build: ["*"] skip: ["pp*"]