From 733445d7838781fab90f5b1b37a48b2d1050e232 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 4 Nov 2026 18:34:30 +0100 Subject: [PATCH 1/4] support and test on Python 3.13 Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 3 +++ setup.py | 1 + tox.ini | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 596134f3c4..7bae80298a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,6 +66,9 @@ jobs: - os: ubuntu-24.04 python-version: '3.12' toxenv: py312-fuse3 + - os: ubuntu-24.04 + python-version: '3.13' + toxenv: py313-fuse3 - os: macos-15 python-version: '3.11' toxenv: py311-none # note: no fuse testing, due to #6099, see also #6196. diff --git a/setup.py b/setup.py index 106139eef1..0a191c1e1a 100644 --- a/setup.py +++ b/setup.py @@ -297,6 +297,7 @@ def members_appended(*ds): 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', 'Topic :: Security :: Cryptography', 'Topic :: System :: Archiving :: Backup', ], diff --git a/tox.ini b/tox.ini index 3ae0d53e6e..58b1b98ee5 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ # fakeroot -u tox --recreate [tox] -envlist = py{39,310,311,312}-{none,fuse2,fuse3} +envlist = py{39,310,311,312,313}-{none,fuse2,fuse3} minversion = 3.2 requires = pkgconfig From 0be3fd21ca26662cd79ce3c12255364a6e690a28 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 4 Nov 2026 18:59:45 +0100 Subject: [PATCH 2/4] support and test on Python 3.14 - with-lock: don't return from a finally block. Python 3.14 emits a SyntaxWarning for it, which also polluted the output of "borg serve" subprocesses and broke the remote tests. Also, a return in finally would swallow an uncaught exception. - tests: accept the Python 3.14 ZeroDivisionError message. - allow msgpack 1.1.2, which provides wheels for Python 3.14. - CI: add a py314-fuse3 job, add py314 to tox, add the classifier. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 3 +++ setup.py | 3 ++- src/borg/archiver.py | 2 +- src/borg/helpers/msgpack.py | 2 +- src/borg/testsuite/repository.py | 5 ++++- tox.ini | 2 +- 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7bae80298a..fc38abf01c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,6 +69,9 @@ jobs: - os: ubuntu-24.04 python-version: '3.13' toxenv: py313-fuse3 + - os: ubuntu-24.04 + python-version: '3.14' + toxenv: py314-fuse3 - os: macos-15 python-version: '3.11' toxenv: py311-none # note: no fuse testing, due to #6099, see also #6196. diff --git a/setup.py b/setup.py index 0a191c1e1a..46a4189fb0 100644 --- a/setup.py +++ b/setup.py @@ -75,7 +75,7 @@ # Please note: # using any other msgpack version is not supported by borg development and # any feedback related to issues caused by this will be ignored. - 'msgpack >=0.5.6, <=1.1.1, !=1.0.1', + 'msgpack >=0.5.6, <=1.1.2, !=1.0.1', 'packaging', ] @@ -298,6 +298,7 @@ def members_appended(*ds): 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: 3.13', + 'Programming Language :: Python :: 3.14', 'Topic :: Security :: Cryptography', 'Topic :: System :: Archiving :: Backup', ], diff --git a/src/borg/archiver.py b/src/borg/archiver.py index 971c3e7621..8374080e1d 100644 --- a/src/borg/archiver.py +++ b/src/borg/archiver.py @@ -1908,7 +1908,7 @@ def do_with_lock(self, args, repository): # any other mechanism relying on existing segment data not changing). # see issue #1867. repository.commit(compact=False) - return ret + return ret @with_repository(manifest=False, exclusive=True) def do_compact(self, args, repository): diff --git a/src/borg/helpers/msgpack.py b/src/borg/helpers/msgpack.py index 63561c9f42..d16f8f7fca 100644 --- a/src/borg/helpers/msgpack.py +++ b/src/borg/helpers/msgpack.py @@ -182,7 +182,7 @@ def is_slow_msgpack(): def is_supported_msgpack(): # DO NOT CHANGE OR REMOVE! See also requirements and comments in setup.py. import msgpack - return (0, 5, 6) <= msgpack.version[:3] <= (1, 1, 1) and \ + return (0, 5, 6) <= msgpack.version[:3] <= (1, 1, 2) and \ msgpack.version not in [(1, 0, 1), ] # < add bad releases here to deny list diff --git a/src/borg/testsuite/repository.py b/src/borg/testsuite/repository.py index ca0f9d9c07..70160ace62 100644 --- a/src/borg/testsuite/repository.py +++ b/src/borg/testsuite/repository.py @@ -977,7 +977,10 @@ def test_rpc_exception_transport(self): self.repository.call('inject_exception', {'kind': 'divide'}) except RemoteRepository.RPCError as e: assert e.unpacked - assert e.get_message() == 'ZeroDivisionError: integer division or modulo by zero\n' + assert e.get_message() in ( + 'ZeroDivisionError: integer division or modulo by zero\n', # Python < 3.14 + 'ZeroDivisionError: division by zero\n', # Python >= 3.14 + ) assert e.exception_class == 'ZeroDivisionError' assert len(e.exception_full) > 0 diff --git a/tox.ini b/tox.ini index 58b1b98ee5..b7f4957fbb 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ # fakeroot -u tox --recreate [tox] -envlist = py{39,310,311,312,313}-{none,fuse2,fuse3} +envlist = py{39,310,311,312,313,314}-{none,fuse2,fuse3} minversion = 3.2 requires = pkgconfig From 87b96e2b74073b437e81dc73f95f5da76246ba93 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 4 Nov 2026 19:05:26 +0100 Subject: [PATCH 3/4] setup.py: only cythonize in parallel with the fork start method Python 3.14 changed the default multiprocessing start method on Linux from "fork" to "forkserver". Like "spawn", it re-imports setup.py in the worker processes, so "python setup.py develop" failed while cythonizing. Co-Authored-By: Claude Opus 5.5 --- setup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 46a4189fb0..e80b3f70fb 100644 --- a/setup.py +++ b/setup.py @@ -63,8 +63,10 @@ prefer_system_libxxhash = not bool(os.environ.get('BORG_USE_BUNDLED_XXHASH')) system_prefix_libxxhash = os.environ.get('BORG_LIBXXHASH_PREFIX') -# Number of threads to use for cythonize, not used on windows -cpu_threads = multiprocessing.cpu_count() if multiprocessing and multiprocessing.get_start_method() != 'spawn' else None +# Number of threads to use for cythonize, not used on windows. +# Only with the "fork" start method: "spawn" and "forkserver" (default on Linux since Python 3.14) +# re-import setup.py in the worker processes, which recursively runs setup() there. +cpu_threads = multiprocessing.cpu_count() if multiprocessing and multiprocessing.get_start_method() == 'fork' else None # Are we building on ReadTheDocs? on_rtd = os.environ.get('READTHEDOCS') From 314cfcb9c53a2fa98db53d67ef7267ac048add38 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 4 Nov 2026 20:50:25 +0100 Subject: [PATCH 4/4] support msgpack up to 1.2.4 Same msgpack versions as 1.4-maint allows. Besides wheels for current Python versions, msgpack 1.2.x brings fixes relevant to borg's usage of the C extension (e.g. GHSA-j586-36cw-2gc2, GHSA-j8c6-9vc5-hj6x). Co-Authored-By: Claude Opus 5.5 --- setup.py | 2 +- src/borg/helpers/msgpack.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index e80b3f70fb..32ccb6d73b 100644 --- a/setup.py +++ b/setup.py @@ -77,7 +77,7 @@ # Please note: # using any other msgpack version is not supported by borg development and # any feedback related to issues caused by this will be ignored. - 'msgpack >=0.5.6, <=1.1.2, !=1.0.1', + 'msgpack >=0.5.6, <=1.2.4, !=1.0.1', 'packaging', ] diff --git a/src/borg/helpers/msgpack.py b/src/borg/helpers/msgpack.py index d16f8f7fca..327af646f6 100644 --- a/src/borg/helpers/msgpack.py +++ b/src/borg/helpers/msgpack.py @@ -182,7 +182,7 @@ def is_slow_msgpack(): def is_supported_msgpack(): # DO NOT CHANGE OR REMOVE! See also requirements and comments in setup.py. import msgpack - return (0, 5, 6) <= msgpack.version[:3] <= (1, 1, 2) and \ + return (0, 5, 6) <= msgpack.version[:3] <= (1, 2, 4) and \ msgpack.version not in [(1, 0, 1), ] # < add bad releases here to deny list