From cf5cbf5dbd1be140bd3bf0e05d5663fad1aa1e23 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Wed, 21 Feb 2024 23:59:39 +0100 Subject: [PATCH 01/15] paquo get_qupath fix downloading v0.5.0 --- paquo/_utils.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/paquo/_utils.py b/paquo/_utils.py index de749da..ca9085d 100644 --- a/paquo/_utils.py +++ b/paquo/_utils.py @@ -126,12 +126,22 @@ def download_qupath( else: raise ValueError(f"unsupported platform.system() == {system!r}") - if "rc" not in version: + if not version.startswith("v"): + version = f"v{version}" + + if Version(version) > Version("0.4.4"): + if platform.machine() == "arm64": + _sys = "Mac-arm64" + else: + _sys = "Mac-x64" name = f"QuPath-{version}-{_sys}" else: - name = f"QuPath-{version}" + if "rc" not in version: + name = f"QuPath-{version[1:]}-{_sys}" + else: + name = f"QuPath-{version[1:]}" - url = f"https://github.com/qupath/qupath/releases/download/v{version}/{name}.{ext}" + url = f"https://github.com/qupath/qupath/releases/download/{version}/{name}.{ext}" chunk_size = 10 * 1024 * 1024 @@ -149,6 +159,7 @@ def download_qupath( _ctx.verify_mode = ssl.CERT_NONE try: + print("# requesting:", url) with open(out_fn, mode="wb") as tmp, urlopen(url, context=_ctx) as f: # nosec B310 for chunk in callback(iter(lambda: f.read(chunk_size), b""), name=url): tmp.write(chunk) @@ -168,7 +179,7 @@ def extract_qupath(file, destination, system=None): # normalize QuPath App dirname m = re.match( - r"QuPath-(?P[0-9]+[.][0-9]+[.][0-9]+(-rc[0-9]+|-m[0-9]+)?)", + r"QuPath-v?(?P[0-9]+[.][0-9]+[.][0-9]+(-rc[0-9]+|-m[0-9]+)?)", fn, ) From 25f1c89100c226a61429389a452a6cf3528f61fc Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 00:01:01 +0100 Subject: [PATCH 02/15] ci: test against 0.5.0 --- .github/workflows/run_pytests.yaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/run_pytests.yaml b/.github/workflows/run_pytests.yaml index 9ce4442..e6cbd06 100644 --- a/.github/workflows/run_pytests.yaml +++ b/.github/workflows/run_pytests.yaml @@ -8,7 +8,7 @@ on: pull_request: {} env: - QUPATH_VERSION: 0.4.3 + QUPATH_VERSION: 0.5.0 jobs: # RUN PYTEST ON PAQUO SOURCE @@ -16,19 +16,21 @@ jobs: name: pytest ${{ matrix.os }}::py${{ matrix.python-version }} runs-on: ${{ matrix.os }} strategy: - max-parallel: 7 + max-parallel: 8 fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.11"] + python-version: ["3.12"] include: # we'll test the python support on ubuntu - os: ubuntu-latest - python-version: '3.10' + python-version: '3.11' - os: ubuntu-latest - python-version: 3.9 + python-version: '3.12' - os: ubuntu-latest - python-version: 3.8 + python-version: '3.9' + - os: ubuntu-latest + python-version: '3.8' steps: - uses: actions/checkout@v3 with: From 6b56d670ba5d11e0c98cfcdaf9701575a7d8fd8d Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 00:01:53 +0100 Subject: [PATCH 03/15] pre-commit update hooks --- .pre-commit-config.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 04d2c6c..adc9349 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,17 +1,17 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-added-large-files - repo: https://github.com/asottile/pyupgrade - rev: v3.9.0 + rev: v3.15.1 hooks: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/pycqa/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort exclude: ^examples|^extras|^docs|tests.*|setup.py @@ -21,21 +21,21 @@ repos: # - id: black # language_version: python3 - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v1.4.1' + rev: 'v1.8.0' hooks: - id: mypy exclude: ^examples|^extras|^docs|tests.* additional_dependencies: [packaging, ome-types] - repo: https://github.com/PyCQA/flake8 - rev: '6.0.0' + rev: '7.0.0' hooks: - id: flake8 additional_dependencies: - - flake8-typing-imports==1.12.0 + - flake8-typing-imports==1.15.0 language_version: python3 exclude: "^(build|docs|examples|extras|setup.py)|tests[/]" - repo: https://github.com/PyCQA/bandit - rev: '1.7.5' + rev: '1.7.7' hooks: - id: bandit args: ["-lll", "--ini", ".bandit"] From f9ecf8d6f1d35d62a0c2c92f5a4a856e944d117f Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 00:06:05 +0100 Subject: [PATCH 04/15] pre-commit update hooks apply fixes --- paquo/__main__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/paquo/__main__.py b/paquo/__main__.py index 9bee0e9..1fbafb2 100644 --- a/paquo/__main__.py +++ b/paquo/__main__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import argparse import functools import os @@ -8,6 +10,7 @@ from itertools import repeat from logging.config import dictConfig from pathlib import Path +from typing import Callable from paquo._cli import DirectoryType from paquo._cli import argument @@ -270,14 +273,14 @@ def quickview(args, subparser): f_annotations = None if args.annotations: - def f_annotations(name): + def f_annotations(name): # noqa if name != image.name: return [] return list(args.annotations) f_annotations_cmd = None if args.annotations_cmd: - def f_annotations_cmd(name): + def f_annotations_cmd(name): # noqa import shlex _cmd = shlex.split(f"{args.annotations_cmd} {name}") print("annotations", _cmd) @@ -286,7 +289,7 @@ def f_annotations_cmd(name): cmd = None if f_annotations_cmd or f_annotations: - def cmd(name): + def cmd(name): # noqa names = [] if f_annotations: names.extend(f_annotations(name)) From b15843493b7b27aac8a17df91e16b65e71448e22 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 00:09:36 +0100 Subject: [PATCH 05/15] paquo: suppress warning for PathClassFactory --- paquo/java.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/paquo/java.py b/paquo/java.py index 55da01f..c0f3be0 100644 --- a/paquo/java.py +++ b/paquo/java.py @@ -119,7 +119,12 @@ def supports_newer_addobject_and_pathclass(self) -> bool: PathAnnotationObject = JClass("qupath.lib.objects.PathAnnotationObject") PathClass = JClass('qupath.lib.objects.classes.PathClass') -PathClassFactory = JClass('qupath.lib.objects.classes.PathClassFactory') + +if not compatibility.supports_newer_addobject_and_pathclass(): + PathClassFactory = JClass('qupath.lib.objects.classes.PathClassFactory') +else: + PathClassFactory = None + PathDetectionObject = JClass("qupath.lib.objects.PathDetectionObject") PathIO = JClass("qupath.lib.io.PathIO") PathObjectHierarchy = JClass('qupath.lib.objects.hierarchy.PathObjectHierarchy') From 4c80fa6b7d066e7fa1668197c3e832b16e62cee5 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 00:11:38 +0100 Subject: [PATCH 06/15] paquo: redirect logs when getting image_server metadata --- paquo/images.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/paquo/images.py b/paquo/images.py index e86c5ba..32b95d0 100644 --- a/paquo/images.py +++ b/paquo/images.py @@ -548,7 +548,8 @@ def downsample_levels(self) -> List[Dict[str, float]]: The available downsample levels can differ dependent on which image backend is used by QuPath """ - md = self._image_server.getMetadata() + with redirect(stdout=True, stderr=True): + md = self._image_server.getMetadata() levels = [] for level in range(int(md.nLevels())): resolution_level = md.getLevel(level) From 27cb6ff5ec7972847b8d7c3eef6b0cbeb13dacdc Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 00:16:07 +0100 Subject: [PATCH 07/15] update readme --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 37a1e1c..7582559 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ unintuitive, slow or if its documentation is confusing, it's a bug in tracker! Development -[happens on github](https://github.com/bayer-science-for-a-better-life/paquo) +[happens on GitHub](https://github.com/bayer-science-for-a-better-life/paquo) :octocat: ## Documentation @@ -54,18 +54,18 @@ paquo to use that version. Currently, paquo supports every version of QuPath fro `0.2.0` to the most recent. _(We even support older `0.2.0-mX` versions but no guarantees)._ ```shell -> paquo get_qupath --install-path "/some/path/on/your/machine" 0.4.3 -# downloading: https://github.com/qupath/qupath/releases/download/v0.4.3/QuPath-0.4.3-Linux.tar.xz +> paquo get_qupath --install-path "/some/path/on/your/machine" 0.5.0 +# downloading: https://github.com/qupath/qupath/releases/download/v0.5.0/QuPath-0.4.3-Linux.tar.xz # progress ................... OK -# extracting: [...]/QuPath-0.4.3-Linux.tar.xz -# available at: /some/path/on/your/machine/QuPath-0.4.3 +# extracting: [...]/QuPath-0.5.0-Linux.tar.xz +# available at: /some/path/on/your/machine/QuPath-0.5.0 # # use via environment variable: -# $ export PAQUO_QUPATH_DIR=/some/path/on/your/machine/QuPath-0.4.3 +# $ export PAQUO_QUPATH_DIR=/some/path/on/your/machine/QuPath-0.5.0 # # use via .paquo.toml config file: -# qupath_dir="/some/path/on/your/machine/QuPath-0.4.3" -/some/path/on/your/machine/QuPath-0.4.3 +# qupath_dir="/some/path/on/your/machine/QuPath-0.5.0" +/some/path/on/your/machine/QuPath-0.5.0 ``` @@ -88,9 +88,9 @@ so go ahead and hack. - When contributing code, please try to use Pull Requests. - tests go hand in hand with modules on ```tests``` packages at the same level. We use ```pytest```. -You can setup your IDE to help you adhering to these guidelines. +You can set up your IDE to help you to adhere to these guidelines.
-_([Santi](https://github.com/sdvillal) is happy to help you setting up pycharm in 5 minutes)_ +_([Santi](https://github.com/sdvillal) is happy to help you to set up pycharm in 5 minutes)_ ## Acknowledgements From f4b3f8293572793c284635f82a7f2c84fda50421 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 00:20:07 +0100 Subject: [PATCH 08/15] paquo get_quath: better error --- paquo/__main__.py | 17 ++++++++++------- paquo/_utils.py | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/paquo/__main__.py b/paquo/__main__.py index 1fbafb2..d453361 100644 --- a/paquo/__main__.py +++ b/paquo/__main__.py @@ -335,13 +335,16 @@ def _download_cb(it, name): finally: print("") - file = download_qupath( - args.version, - path=args.download_path, - callback=_download_cb, - system=system, - ssl_verify=not args.no_ssl_verify - ) + try: + file = download_qupath( + args.version, + path=args.download_path, + callback=_download_cb, + system=system, + ssl_verify=not args.no_ssl_verify + ) + except Exception: + raise SystemExit(1) print("# extracting:", file) app = extract_qupath(file, args.install_path, system=system) print("# available at:", app) diff --git a/paquo/_utils.py b/paquo/_utils.py index ca9085d..e3ebb8a 100644 --- a/paquo/_utils.py +++ b/paquo/_utils.py @@ -159,11 +159,11 @@ def download_qupath( _ctx.verify_mode = ssl.CERT_NONE try: - print("# requesting:", url) with open(out_fn, mode="wb") as tmp, urlopen(url, context=_ctx) as f: # nosec B310 for chunk in callback(iter(lambda: f.read(chunk_size), b""), name=url): tmp.write(chunk) except Exception: + print("# error requesting:", url, file=sys.stderr) try: os.unlink(out_fn) except OSError: From 4454e2a0462b83b1af52b5cad7ad3110b84521cd Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 00:22:09 +0100 Subject: [PATCH 09/15] paquo get_quath: fix non-mac platforms --- paquo/_utils.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/paquo/_utils.py b/paquo/_utils.py index e3ebb8a..315e079 100644 --- a/paquo/_utils.py +++ b/paquo/_utils.py @@ -130,10 +130,11 @@ def download_qupath( version = f"v{version}" if Version(version) > Version("0.4.4"): - if platform.machine() == "arm64": - _sys = "Mac-arm64" - else: - _sys = "Mac-x64" + if system == "Darwin": + if platform.machine() == "arm64": + _sys = "Mac-arm64" + else: + _sys = "Mac-x64" name = f"QuPath-{version}-{_sys}" else: if "rc" not in version: From ad3bc6073c76061e0529f1cc8342cfcb72a85b1f Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 00:28:28 +0100 Subject: [PATCH 10/15] tests: adjust image_downsample_levels test to match both scenarios --- paquo/tests/test_images.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/paquo/tests/test_images.py b/paquo/tests/test_images.py index acd423a..5ffa40b 100644 --- a/paquo/tests/test_images.py +++ b/paquo/tests/test_images.py @@ -74,10 +74,6 @@ def test_image_properties_from_image_server(image_entry): assert image_entry.num_z_slices == 1 -@pytest.mark.xfail( - platform.uname().machine == "arm64", - reason="QuPath-vendored openslide not working on arm64" -) def test_image_downsample_levels(image_entry): levels = [ {'downsample': 1.0, @@ -85,11 +81,14 @@ def test_image_downsample_levels(image_entry): 'width': 2220}, # todo: when openslide can be used by qupath, this downsample level # in the test image disappears. investigate... - # {'downsample': 3.865438534407666, - # 'height': 768, - # 'width': 574}, + {'downsample': 3.865438534407666, + 'height': 768, + 'width': 574}, ] - assert image_entry.downsample_levels == levels + assert ( + image_entry.downsample_levels == levels + or image_entry.downsample_levels == levels[:1] + ) def test_metadata_interface(image_entry): From 392e663147604d950edf52eb595ee9dcfb1e4318 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 00:49:17 +0100 Subject: [PATCH 11/15] paquo: fix windows zip extraction for newer QuPaths --- paquo/_utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/paquo/_utils.py b/paquo/_utils.py index 315e079..171ab68 100644 --- a/paquo/_utils.py +++ b/paquo/_utils.py @@ -248,9 +248,12 @@ def extract_qupath(file, destination, system=None): pth = os.path.join(tmp_dir, name) if name.startswith("QuPath") and os.path.isdir(pth): break + if name.startswith("QuPath") and name.endswith(".exe") and os.path.isfile(pth): + pth = tmp_dir + break else: raise RuntimeError("no qupath extracted?") - shutil.move(os.path.join(tmp_dir, name), qp_dst) + shutil.move(pth, qp_dst) return qp_dst else: From 09d58b2b7de54c99454381d8a50adf904e86973d Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 01:03:23 +0100 Subject: [PATCH 12/15] tests: fix windows edge cases --- paquo/tests/test_images.py | 4 +++- paquo/tests/test_projects.py | 14 ++++++++++++-- setup.cfg | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/paquo/tests/test_images.py b/paquo/tests/test_images.py index 5ffa40b..4cd3ebd 100644 --- a/paquo/tests/test_images.py +++ b/paquo/tests/test_images.py @@ -45,8 +45,10 @@ def project_with_removed_image_without_image_data(removable_svs_small): qp = QuPathProject(tmpdir, mode='x') _ = qp.add_image(removable_svs_small) qp.save() + path = qp.path + del qp removable_svs_small.unlink() - yield qp.path + yield path def test_image_entry_return_hierarchy(image_entry): diff --git a/paquo/tests/test_projects.py b/paquo/tests/test_projects.py index 31841c2..f5d5b68 100644 --- a/paquo/tests/test_projects.py +++ b/paquo/tests/test_projects.py @@ -8,6 +8,7 @@ import pytest +from paquo._utils import QuPathVersion from paquo.images import ImageProvider, QuPathProjectImageEntry, QuPathImageType from paquo.projects import QuPathProject @@ -284,7 +285,7 @@ def test_project_save_image_data(new_project, svs_small): assert (entry.entry_path / "data.qpdata").is_file() -def test_project_delete_image_file_when_opened(new_project, svs_small): +def test_project_delete_image_file_when_opened(new_project, svs_small, qupath_version): # prepare new image to be deleted new_svs_small = new_project.path.parent / f"image_be_gone{svs_small.suffix}" shutil.copy(svs_small, new_svs_small) @@ -314,7 +315,16 @@ def test_project_delete_image_file_when_opened(new_project, svs_small): elif qupath_uses == "OPENSLIDE": - os.unlink(new_svs_small) + if ( + qupath_version >= QuPathVersion("0.5.0") + and platform.system() == "Windows" + ): + cm = pytest.raises(PermissionError) + else: + cm = nullcontext() + + with cm: + os.unlink(new_svs_small) else: # pragma: no cover raise ValueError('...') diff --git a/setup.cfg b/setup.cfg index 8611f09..85e7026 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,6 +20,7 @@ classifiers = Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 + Programming Language :: Python :: 3.12 Topic :: Scientific/Engineering Topic :: Scientific/Engineering :: Visualization Topic :: Scientific/Engineering :: Information Analysis From c03193d7402c821bfa67e1972132a8fb4eefb4a1 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 01:09:59 +0100 Subject: [PATCH 13/15] tests: adjust remove image fixture --- paquo/tests/test_images.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/paquo/tests/test_images.py b/paquo/tests/test_images.py index 4cd3ebd..abaf9e4 100644 --- a/paquo/tests/test_images.py +++ b/paquo/tests/test_images.py @@ -32,21 +32,21 @@ def removable_svs_small(svs_small): @pytest.fixture(scope='function') def project_with_removed_image(removable_svs_small): with tempfile.TemporaryDirectory(prefix='paquo-') as tmpdir: - qp = QuPathProject(tmpdir, mode='x') - _ = qp.add_image(removable_svs_small, image_type=QuPathImageType.BRIGHTFIELD_H_E) - qp.save() + with QuPathProject(tmpdir, mode='x') as qp: + _ = qp.add_image(removable_svs_small, image_type=QuPathImageType.BRIGHTFIELD_H_E) + qp.save() + path = qp.path removable_svs_small.unlink() - yield qp.path + yield path @pytest.fixture(scope='function') def project_with_removed_image_without_image_data(removable_svs_small): with tempfile.TemporaryDirectory(prefix='paquo-') as tmpdir: - qp = QuPathProject(tmpdir, mode='x') - _ = qp.add_image(removable_svs_small) - qp.save() - path = qp.path - del qp + with QuPathProject(tmpdir, mode='x') as qp: + _ = qp.add_image(removable_svs_small) + qp.save() + path = qp.path removable_svs_small.unlink() yield path From 5ceac3c389e1f92977a96f07999aa6a52d1b2d7f Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 01:17:53 +0100 Subject: [PATCH 14/15] tests: xfail windows permission errors for remove tests --- paquo/tests/test_images.py | 16 ++++++++++++++-- paquo/tests/test_projects.py | 8 +++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/paquo/tests/test_images.py b/paquo/tests/test_images.py index abaf9e4..f07489a 100644 --- a/paquo/tests/test_images.py +++ b/paquo/tests/test_images.py @@ -36,7 +36,13 @@ def project_with_removed_image(removable_svs_small): _ = qp.add_image(removable_svs_small, image_type=QuPathImageType.BRIGHTFIELD_H_E) qp.save() path = qp.path - removable_svs_small.unlink() + try: + removable_svs_small.unlink() + except PermissionError: + if platform.system() == "Windows": + pytest.xfail("Windows QuPath==0.5.0 permission issue") + else: + raise yield path @@ -47,7 +53,13 @@ def project_with_removed_image_without_image_data(removable_svs_small): _ = qp.add_image(removable_svs_small) qp.save() path = qp.path - removable_svs_small.unlink() + try: + removable_svs_small.unlink() + except PermissionError: + if platform.system() == "Windows": + pytest.xfail("Windows QuPath==0.5.0 permission issue") + else: + raise yield path diff --git a/paquo/tests/test_projects.py b/paquo/tests/test_projects.py index f5d5b68..0d3b6f0 100644 --- a/paquo/tests/test_projects.py +++ b/paquo/tests/test_projects.py @@ -399,7 +399,13 @@ def test_project_image_uri_update_try_relative(tmp_path, svs_small): # NOW move the location location_1 = tmp_path / "location_1" - shutil.move(location_0, location_1) + try: + shutil.move(location_0, location_1) + except PermissionError: + if platform.system() == "Windows": + pytest.xfail("Windows QuPath==0.5.0 quirk with permissions") + else: + raise with QuPathProject(location_1 / "project", mode='r') as qp: entry, = qp.images From 48d1acae18255d70a6abbd58e54e976dcb368544 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 22 Feb 2024 01:25:42 +0100 Subject: [PATCH 15/15] test: more windows permission errors --- paquo/tests/test_images.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/paquo/tests/test_images.py b/paquo/tests/test_images.py index f07489a..f7f1a9e 100644 --- a/paquo/tests/test_images.py +++ b/paquo/tests/test_images.py @@ -1,5 +1,6 @@ import platform import shutil +import sys import tempfile from contextlib import nullcontext from operator import itemgetter @@ -23,7 +24,11 @@ def image_entry(svs_small): @pytest.fixture(scope='function') def removable_svs_small(svs_small): - with tempfile.TemporaryDirectory(prefix='paquo-') as tmpdir: + kw = {} if sys.version_info < (3, 10) else {"ignore_cleanup_errors": True} + with tempfile.TemporaryDirectory( + prefix='paquo-', + **kw + ) as tmpdir: new_path = Path(tmpdir) / svs_small.name shutil.copy(svs_small, new_path) yield new_path