From 296c0168c8e20c6303a2791d673a9e2ad97e5076 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sun, 4 May 2025 18:43:53 +0300 Subject: [PATCH 01/15] Add Python 3.13 support and deploy a compiled wheel to PyPI Add support for Python 3.13 and configure deployment to PyPI. * **CI Configuration**: Update `.github/workflows/ci.yml` to include Python version 3.13 in the `python-version` matrix. * **Setup.py**: Update `setup.py` to list supported Python versions up to 3.13 in the `classifiers` list. * **Tox Configuration**: Update `tox.ini` to include Python 3.13 in the `envlist`. * **Publish Workflow**: Add a new GitHub Actions workflow in `.github/workflows/publish.yml` for publishing the package to PyPI. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/spotify/annoy?shareId=XXXX-XXXX-XXXX-XXXX). --- .github/workflows/ci.yml | 2 +- .github/workflows/publish.yml | 32 ++++++++++++++++++++++++++++++++ setup.py | 4 ++++ tox.ini | 2 +- 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index def770bb..2aec3fc9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] os: ["ubuntu-20.04", "macos-latest", "windows-latest"] steps: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..1f09d0f5 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,32 @@ +name: Publish + +on: + push: + tags: + - 'v*.*.*' + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel twine + + - name: Build package + run: python setup.py sdist bdist_wheel + + - name: Publish package + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/setup.py b/setup.py index ca745870..7e25c25f 100644 --- a/setup.py +++ b/setup.py @@ -102,6 +102,10 @@ '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', ], keywords='nns, approximate nearest neighbor search', setup_requires=['nose>=1.0'], diff --git a/tox.ini b/tox.ini index 5a2e5cae..b127d8a4 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist=py{26,27,33,34,35,36,37}, go, lua +envlist=py{26,27,33,34,35,36,37,38,39,310,311,312,313}, go, lua [testenv] setenv = From 5a0debdaaf124ef5e9c51ec3beba5f271d80395d Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sun, 25 May 2025 14:05:06 +0300 Subject: [PATCH 02/15] Update publish workflow to use cibuildwheel for building and deploying wheels * Install cibuildwheel instead of setuptools, wheel, and twine * Build wheels using cibuildwheel and save them to the `dist` folder * Upload built wheels as artifacts * Remove `sdist` build step --- .github/workflows/publish.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1f09d0f5..675b7f74 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,13 +18,16 @@ jobs: with: python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install setuptools wheel twine + - name: Install cibuildwheel + run: python -m pip install cibuildwheel==3.0.0b1 - - name: Build package - run: python setup.py sdist bdist_wheel + - name: Build wheels + run: python -m cibuildwheel --output-dir dist + + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + path: ./dist/*.whl - name: Publish package uses: pypa/gh-action-pypi-publish@release/v1 From 9d4be61bff829affac6687f3a9ae83cd442a9318 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Wed, 28 May 2025 12:11:59 +0000 Subject: [PATCH 03/15] Fix build error in "Build wheels" --- .github/workflows/publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 675b7f74..0c765112 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -23,6 +23,8 @@ jobs: - name: Build wheels run: python -m cibuildwheel --output-dir dist + env: + CIBW_BEFORE_BUILD: python -m pip install -U pip && rm -rf build - uses: actions/upload-artifact@v4 with: From e6b38b6e6d851c9fb9b3adf006ed0d7922650198 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Thu, 19 Jun 2025 14:28:10 +0300 Subject: [PATCH 04/15] Update `actions/setup-python` stage in job in `.github/workflows/publish.yml` Thank you `mathematicalmichael` for the PR suggestion Co-authored-by: Michael Pilosov <40366263+mathematicalmichael@users.noreply.github.com> --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0c765112..82979a7c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v2 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: '3.x' From 65d8f36d86f0983f282d1a9b4db8281536ac4b4a Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Thu, 19 Jun 2025 19:35:52 +0300 Subject: [PATCH 05/15] Add macOS and Windows OS support in wheel builds Thank you to `mathematicalmichael` for the suggestion Co-authored-by: Michael Pilosov <40366263+mathematicalmichael@users.noreply.github.com> --- .github/workflows/publish.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 82979a7c..4f3d5984 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,7 +7,11 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] steps: - name: Checkout code From fe31617d394c82dd56a91f1b86799fefe2dfa4a1 Mon Sep 17 00:00:00 2001 From: Michael Pilosov Date: Thu, 19 Jun 2025 20:30:41 +0000 Subject: [PATCH 06/15] verified publishing --- .github/workflows/publish.yml | 20 ++++++++++++++++++-- README.rst | 9 ++------- setup.py | 13 +++++++++++-- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4f3d5984..de219541 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,5 +1,9 @@ name: Publish +# pypi trusted publishing via OIDC +permissions: + id-token: write + on: push: tags: @@ -35,7 +39,19 @@ jobs: name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} path: ./dist/*.whl + publish: + needs: build + runs-on: ubuntu-latest + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + pattern: cibw-wheels-* + path: dist + merge-multiple: true + - name: Publish package uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.PYPI_API_TOKEN }} + if: startsWith(github.ref, 'refs/tags/v') && github.event_name == 'push' + # with: + # password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/README.rst b/README.rst index 69f2bb25..31887b77 100644 --- a/README.rst +++ b/README.rst @@ -3,12 +3,12 @@ Annoy -.. figure:: https://raw.github.com/spotify/annoy/master/ann.png +.. image:: https://raw.github.com/spotify/annoy/master/ann.png :alt: Annoy example :align: center .. image:: https://github.com/spotify/annoy/actions/workflows/ci.yml/badge.svg - :target: https://github.com/spotify/annoy/actions + :target: https://github.com/spotify/annoy/actions Annoy (`Approximate Nearest Neighbors `__ Oh Yeah) is a C++ library with Python bindings to search for points in space that are close to a given query point. It also creates large read-only file-based data structures that are `mmapped `__ into memory so that many processes may share the same data. @@ -136,11 +136,6 @@ More info * Annoy is available as a `conda package `__ on Linux, OS X, and Windows. * `ann-benchmarks `__ is a benchmark for several approximate nearest neighbor libraries. Annoy seems to be fairly competitive, especially at higher precisions: -.. figure:: https://github.com/erikbern/ann-benchmarks/raw/master/results/glove-100-angular.png - :alt: ANN benchmarks - :align: center - :target: https://github.com/erikbern/ann-benchmarks - Source code ----------- diff --git a/setup.py b/setup.py index 7e25c25f..789cd05a 100644 --- a/setup.py +++ b/setup.py @@ -19,6 +19,7 @@ import codecs import os import platform +import re import sys readme_note = """\ @@ -33,7 +34,14 @@ """ with codecs.open('README.rst', encoding='utf-8') as fobj: - long_description = readme_note + fobj.read() + content = fobj.read() + # Normalize line endings + content = content.replace('\r\n', '\n').replace('\r', '\n') + # Remove blank lines between directive and options + content = re.sub(r'(\.\. image:: [^\n]+)(\n\s*\n)+(\s+:)', r'\1\n\3', content) + # Remove blank lines between options themselves + content = re.sub(r'(\s+:[^:]+:[^\n]*)(\n\s*\n)+(\s+:)', r'\1\n\3', content) + long_description = readme_note + content # Various platform-dependent extras extra_compile_args = ['-D_CRT_SECURE_NO_WARNINGS', '-fpermissive'] @@ -73,7 +81,7 @@ extra_link_args = manual_linker_args.split(',') setup(name='annoy', - version='1.17.3', + version='1.17.4rc0', description='Approximate Nearest Neighbors in C++/Python optimized for memory usage and loading/saving to disk.', packages=['annoy'], package_data={'annoy': ['__init__.pyi', 'py.typed']}, @@ -86,6 +94,7 @@ ) ], long_description=long_description, + long_description_content_type='text/x-rst', author='Erik Bernhardsson', author_email='mail@erikbern.com', url='https://github.com/spotify/annoy', From 86d949ba34825e23bd8a64e9b15193826ff775aa Mon Sep 17 00:00:00 2001 From: Michael Pilosov Date: Fri, 20 Jun 2025 01:24:22 +0000 Subject: [PATCH 07/15] sdist --- .github/workflows/publish.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index de219541..11160bea 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,11 +34,23 @@ jobs: env: CIBW_BEFORE_BUILD: python -m pip install -U pip && rm -rf build - - uses: actions/upload-artifact@v4 + - name: Upload wheels + uses: actions/upload-artifact@v4 with: - name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + name: built-wheels-${{ matrix.os }}-${{ strategy.job-index }} path: ./dist/*.whl + - name: Build source distribution + if: matrix.os == 'ubuntu-latest' + run: python -m pip install build && python -m build --sdist --outdir dist + + - name: Upload sdist + if: matrix.os == 'ubuntu-latest' + uses: actions/upload-artifact@v4 + with: + name: built-sdist + path: ./dist/*.tar.gz + publish: needs: build runs-on: ubuntu-latest @@ -46,7 +58,7 @@ jobs: - name: Download all artifacts uses: actions/download-artifact@v4 with: - pattern: cibw-wheels-* + pattern: built-* path: dist merge-multiple: true From 8f440e8a2e5192b2709be81838cd0a10cc1e2b12 Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Tue, 24 Jun 2025 13:24:52 -0600 Subject: [PATCH 08/15] Update .github/workflows/publish.yml Co-authored-by: Ben Lewis --- .github/workflows/publish.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 11160bea..e42092a6 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -65,5 +65,3 @@ jobs: - name: Publish package uses: pypa/gh-action-pypi-publish@release/v1 if: startsWith(github.ref, 'refs/tags/v') && github.event_name == 'push' - # with: - # password: ${{ secrets.PYPI_API_TOKEN }} From f552a1e5ec1e2b9cf34dead274ff1c87f793f379 Mon Sep 17 00:00:00 2001 From: Michael Pilosov Date: Tue, 24 Jun 2025 20:01:03 +0000 Subject: [PATCH 09/15] move permissions into publish step --- .github/workflows/publish.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e42092a6..6c36341f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,9 +1,5 @@ name: Publish -# pypi trusted publishing via OIDC -permissions: - id-token: write - on: push: tags: @@ -54,6 +50,9 @@ jobs: publish: needs: build runs-on: ubuntu-latest + # pypi trusted publishing via OIDC + permissions: + id-token: write steps: - name: Download all artifacts uses: actions/download-artifact@v4 From 3373daa8eb57e959f2b0dab6fdc01e3eba4224b0 Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:55:34 -0600 Subject: [PATCH 10/15] version bump back down --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 789cd05a..ad61fb5f 100644 --- a/setup.py +++ b/setup.py @@ -81,7 +81,7 @@ extra_link_args = manual_linker_args.split(',') setup(name='annoy', - version='1.17.4rc0', + version='1.17.3', description='Approximate Nearest Neighbors in C++/Python optimized for memory usage and loading/saving to disk.', packages=['annoy'], package_data={'annoy': ['__init__.pyi', 'py.typed']}, From 6528894fe2a649f8e6f3a364bd4d3658d0346f1d Mon Sep 17 00:00:00 2001 From: Michael Pilosov Date: Mon, 30 Jun 2025 22:32:59 +0000 Subject: [PATCH 11/15] aarch64 wheels on linux - tested --- .github/workflows/publish.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6c36341f..6ff2df5a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -17,6 +17,12 @@ jobs: - name: Checkout code uses: actions/checkout@v2 + - name: Set up QEMU (for Linux aarch64) + if: runner.os == 'Linux' + uses: docker/setup-qemu-action@v3 + with: + platforms: arm64 + - name: Set up Python uses: actions/setup-python@v5 with: @@ -29,6 +35,7 @@ jobs: run: python -m cibuildwheel --output-dir dist env: CIBW_BEFORE_BUILD: python -m pip install -U pip && rm -rf build + CIBW_ARCHS_LINUX: auto aarch64 - name: Upload wheels uses: actions/upload-artifact@v4 From d48b274f42b35b81ef199d4e64e3f1691f67278a Mon Sep 17 00:00:00 2001 From: Michael Pilosov Date: Thu, 3 Jul 2025 17:40:10 +0000 Subject: [PATCH 12/15] address feedback + bump cibuildwheel --- .github/workflows/publish.yml | 2 +- README.rst | 9 +++++++-- setup.py | 13 ++----------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6ff2df5a..77ffba70 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -29,7 +29,7 @@ jobs: python-version: '3.x' - name: Install cibuildwheel - run: python -m pip install cibuildwheel==3.0.0b1 + run: python -m pip install cibuildwheel==3.0.0 - name: Build wheels run: python -m cibuildwheel --output-dir dist diff --git a/README.rst b/README.rst index 31887b77..d2116527 100644 --- a/README.rst +++ b/README.rst @@ -3,11 +3,11 @@ Annoy -.. image:: https://raw.github.com/spotify/annoy/master/ann.png +.. figure:: https://raw.github.com/spotify/annoy/master/ann.png :alt: Annoy example :align: center -.. image:: https://github.com/spotify/annoy/actions/workflows/ci.yml/badge.svg +.. figure:: https://github.com/spotify/annoy/actions/workflows/ci.yml/badge.svg :target: https://github.com/spotify/annoy/actions Annoy (`Approximate Nearest Neighbors `__ Oh Yeah) is a C++ library with Python bindings to search for points in space that are close to a given query point. It also creates large read-only file-based data structures that are `mmapped `__ into memory so that many processes may share the same data. @@ -136,6 +136,11 @@ More info * Annoy is available as a `conda package `__ on Linux, OS X, and Windows. * `ann-benchmarks `__ is a benchmark for several approximate nearest neighbor libraries. Annoy seems to be fairly competitive, especially at higher precisions: +.. figure:: https://raw.githubusercontent.com/erikbern/ann-benchmarks/main/results/glove-100-angular.png + :alt: ANN benchmarks + :align: center + :target: https://github.com/erikbern/ann-benchmarks + Source code ----------- diff --git a/setup.py b/setup.py index ad61fb5f..aa5cbe31 100644 --- a/setup.py +++ b/setup.py @@ -16,10 +16,8 @@ # the License. from setuptools import setup, Extension -import codecs import os import platform -import re import sys readme_note = """\ @@ -33,15 +31,8 @@ """ -with codecs.open('README.rst', encoding='utf-8') as fobj: - content = fobj.read() - # Normalize line endings - content = content.replace('\r\n', '\n').replace('\r', '\n') - # Remove blank lines between directive and options - content = re.sub(r'(\.\. image:: [^\n]+)(\n\s*\n)+(\s+:)', r'\1\n\3', content) - # Remove blank lines between options themselves - content = re.sub(r'(\s+:[^:]+:[^\n]*)(\n\s*\n)+(\s+:)', r'\1\n\3', content) - long_description = readme_note + content +with open('README.rst', encoding='utf-8') as fobj: + long_description = readme_note + fobj.read() # Various platform-dependent extras extra_compile_args = ['-D_CRT_SECURE_NO_WARNINGS', '-fpermissive'] From 3f87e65c8059541446330c80553835d1be883e60 Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Thu, 3 Jul 2025 12:06:50 -0600 Subject: [PATCH 13/15] figure back to image (original) --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index d2116527..9d47ca11 100644 --- a/README.rst +++ b/README.rst @@ -7,7 +7,7 @@ Annoy :alt: Annoy example :align: center -.. figure:: https://github.com/spotify/annoy/actions/workflows/ci.yml/badge.svg +.. image:: https://github.com/spotify/annoy/actions/workflows/ci.yml/badge.svg :target: https://github.com/spotify/annoy/actions Annoy (`Approximate Nearest Neighbors `__ Oh Yeah) is a C++ library with Python bindings to search for points in space that are close to a given query point. It also creates large read-only file-based data structures that are `mmapped `__ into memory so that many processes may share the same data. From 4fb77716a000ef00e36f8ce9bc4b84cce3aae897 Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Thu, 23 Oct 2025 01:19:23 -0600 Subject: [PATCH 14/15] secrets --- .github/workflows/publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 77ffba70..aa031713 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -71,3 +71,5 @@ jobs: - name: Publish package uses: pypa/gh-action-pypi-publish@release/v1 if: startsWith(github.ref, 'refs/tags/v') && github.event_name == 'push' + with: + password: ${{ secrets.PYPI_API_TOKEN }} From ecf3ab74672b41eb4e00ec419f1b2b17a021223d Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Thu, 23 Oct 2025 01:19:51 -0600 Subject: [PATCH 15/15] bump cibuildwheel --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index aa031713..2dfe585a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -29,7 +29,7 @@ jobs: python-version: '3.x' - name: Install cibuildwheel - run: python -m pip install cibuildwheel==3.0.0 + run: python -m pip install cibuildwheel==3.2.1 - name: Build wheels run: python -m cibuildwheel --output-dir dist