From de6bfbb444acca44ef1c35846be7f53fdd70de6a Mon Sep 17 00:00:00 2001 From: James Lamb Date: Thu, 22 Aug 2024 15:03:26 -0500 Subject: [PATCH] Drop Python 3.9 support (#766) Contributes to https://github.com/rapidsai/build-planning/issues/88 Finishes the work of dropping Python 3.9 support. This project stopped building / testing against Python 3.9 as of https://github.com/rapidsai/shared-workflows/pull/235. This PR updates configuration and docs to reflect that. ## Notes for Reviewers ### How I tested this Checked that there were no remaining uses like this: ```shell git grep -E '3\.9' git grep '39' git grep 'py39' ``` And similar for variations on Python 3.8 (to catch things that were missed the last time this was done). Authors: - James Lamb (https://github.com/jameslamb) Approvers: - Gregory Lee (https://github.com/grlee77) - https://github.com/jakirkham - Bradley Dice (https://github.com/bdice) - Jake Awe (https://github.com/AyodeAwe) URL: https://github.com/rapidsai/cucim/pull/766 --- .pre-commit-config.yaml | 4 +-- benchmarks/skimage/_image_bench.py | 3 ++- benchmarks/skimage/bench_convolve.py | 3 ++- benchmarks/skimage/cucim_color_bench.py | 7 ++--- benchmarks/skimage/cucim_exposure_bench.py | 7 ++--- benchmarks/skimage/cucim_feature_bench.py | 9 ++++--- benchmarks/skimage/cucim_filters_bench.py | 7 ++--- benchmarks/skimage/cucim_measure_bench.py | 7 ++--- benchmarks/skimage/cucim_metrics_bench.py | 7 ++--- benchmarks/skimage/cucim_morphology_bench.py | 7 ++--- .../skimage/cucim_registration_bench.py | 7 ++--- benchmarks/skimage/cucim_restoration_bench.py | 9 ++++--- .../skimage/cucim_segmentation_bench.py | 5 ++-- benchmarks/skimage/cucim_transform_bench.py | 7 ++--- .../cupyx_scipy_ndimage_filter_bench.py | 2 +- .../cupyx_scipy_ndimage_fourier_bench.py | 2 +- .../cupyx_scipy_ndimage_interp_bench.py | 2 +- .../cupyx_scipy_ndimage_measurements_bench.py | 2 +- .../cupyx_scipy_ndimage_morphology_bench.py | 2 +- .../all_cuda-118_arch-x86_64.yaml | 2 +- .../all_cuda-125_arch-x86_64.yaml | 2 +- .../src/cuslide/jpeg2k/gen_color_table.py | 2 +- dependencies.yaml | 10 +------ docs/source/conf.py | 2 +- .../python/distance_transform_edt_demo.py | 3 ++- .../gds_whole_slide/benchmark_round_trip.py | 5 ++-- .../gds_whole_slide/benchmark_zarr_write.py | 3 ++- .../gds_whole_slide/demo_implementation.py | 3 ++- examples/python/gds_whole_slide/lz4_nvcomp.py | 6 ++--- examples/python/tiff_image/main.py | 3 ++- .../Supporting_Aperio_SVS_Format/benchmark.py | 5 ++-- experiments/Using_Cache/benchmark.py | 5 ++-- python/cucim/pyproject.toml | 27 ++++++++++++------- .../src/cucim/core/operations/color/jitter.py | 18 +++++-------- .../core/operations/color/stain_normalizer.py | 6 ++--- .../cucim/core/operations/intensity/zoom.py | 10 +++---- .../skimage/_shared/version_requirements.py | 14 +++++----- .../cucim/src/cucim/skimage/_vendored/pad.py | 4 +-- .../cucim/src/cucim/skimage/_vendored/time.py | 4 +-- .../skimage/metrics/_structural_similarity.py | 2 +- .../src/cucim/skimage/transform/_geometric.py | 2 +- python/cucim/src/localtest.py | 4 +-- 42 files changed, 125 insertions(+), 116 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9a0afc67e..37a56402d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,11 +16,11 @@ repos: - id: black args: ["--config", "python/cucim/pyproject.toml"] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.3 + rev: v0.6.1 hooks: - id: ruff types_or: [python, pyi] - args: [--fix, --exit-non-zero-on-fix] + args: [--fix, --exit-non-zero-on-fix, --config, "python/cucim/pyproject.toml"] - repo: https://github.com/codespell-project/codespell rev: v2.2.6 hooks: diff --git a/benchmarks/skimage/_image_bench.py b/benchmarks/skimage/_image_bench.py index abb2ffbbb..b04100154 100644 --- a/benchmarks/skimage/_image_bench.py +++ b/benchmarks/skimage/_image_bench.py @@ -12,6 +12,7 @@ import pandas as pd import scipy.ndimage import skimage.data + from cucim.time import repeat @@ -23,7 +24,7 @@ def product_dict(**kwargs): yield dict(zip(keys, instance)) -class ImageBench(object): +class ImageBench: def __init__( self, function_name, diff --git a/benchmarks/skimage/bench_convolve.py b/benchmarks/skimage/bench_convolve.py index a43636931..f44714306 100644 --- a/benchmarks/skimage/bench_convolve.py +++ b/benchmarks/skimage/bench_convolve.py @@ -3,6 +3,8 @@ """ import cupy as cp import cupyx.scipy.ndimage as ndi +from cupyx.profiler import benchmark + from cucim.skimage._vendored.ndimage import ( # noqa: F401 convolve1d, correlate1d, @@ -16,7 +18,6 @@ uniform_filter, uniform_filter1d, ) -from cupyx.profiler import benchmark d = cp.cuda.Device() diff --git a/benchmarks/skimage/cucim_color_bench.py b/benchmarks/skimage/cucim_color_bench.py index 8f394daef..e4fe9fe95 100644 --- a/benchmarks/skimage/cucim_color_bench.py +++ b/benchmarks/skimage/cucim_color_bench.py @@ -2,8 +2,6 @@ import os import pickle -import cucim.skimage -import cucim.skimage.color import cupy import cupy as cp import cupyx.scipy.ndimage @@ -14,6 +12,9 @@ import skimage.color from _image_bench import ImageBench +import cucim.skimage +import cucim.skimage.color + func_name_choices = [ "convert_colorspace", "rgb2hed", @@ -223,7 +224,7 @@ def main(args): try: import tabular # noqa: F401 - with open(fbase + ".md", "wt") as f: + with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) except ImportError: pass diff --git a/benchmarks/skimage/cucim_exposure_bench.py b/benchmarks/skimage/cucim_exposure_bench.py index 558a2282f..bb922d619 100644 --- a/benchmarks/skimage/cucim_exposure_bench.py +++ b/benchmarks/skimage/cucim_exposure_bench.py @@ -2,8 +2,6 @@ import os import pickle -import cucim.skimage -import cucim.skimage.exposure import cupy import cupy as cp import numpy as np @@ -12,6 +10,9 @@ import skimage.exposure from _image_bench import ImageBench +import cucim.skimage +import cucim.skimage.exposure + class ExposureBench(ImageBench): def set_args(self, dtype): @@ -129,7 +130,7 @@ def main(args): fbase = os.path.splitext(pfile)[0] all_results.to_csv(fbase + ".csv") all_results.to_pickle(pfile) - with open(fbase + ".md", "wt") as f: + with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) diff --git a/benchmarks/skimage/cucim_feature_bench.py b/benchmarks/skimage/cucim_feature_bench.py index 4142d7965..9b1d67bca 100644 --- a/benchmarks/skimage/cucim_feature_bench.py +++ b/benchmarks/skimage/cucim_feature_bench.py @@ -3,17 +3,18 @@ import os import pickle -import cucim.skimage -import cucim.skimage.feature import cupy as cp import numpy as np import pandas as pd import skimage import skimage.feature from _image_bench import ImageBench -from cucim.skimage import exposure from skimage import data, draw +import cucim.skimage +import cucim.skimage.feature +from cucim.skimage import exposure + class BlobDetectionBench(ImageBench): def set_args(self, dtype): @@ -218,7 +219,7 @@ def main(args): fbase = os.path.splitext(pfile)[0] all_results.to_csv(fbase + ".csv") all_results.to_pickle(pfile) - with open(fbase + ".md", "wt") as f: + with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) diff --git a/benchmarks/skimage/cucim_filters_bench.py b/benchmarks/skimage/cucim_filters_bench.py index 09a47e346..f78d60904 100644 --- a/benchmarks/skimage/cucim_filters_bench.py +++ b/benchmarks/skimage/cucim_filters_bench.py @@ -2,14 +2,15 @@ import os import pickle -import cucim.skimage -import cucim.skimage.filters import numpy as np import pandas as pd import skimage import skimage.filters from _image_bench import ImageBench +import cucim.skimage +import cucim.skimage.filters + def main(args): pfile = "cucim_filters_results.pickle" @@ -189,7 +190,7 @@ def main(args): fbase = os.path.splitext(pfile)[0] all_results.to_csv(fbase + ".csv") all_results.to_pickle(pfile) - with open(fbase + ".md", "wt") as f: + with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) diff --git a/benchmarks/skimage/cucim_measure_bench.py b/benchmarks/skimage/cucim_measure_bench.py index e7e7b40df..7f8c09f17 100644 --- a/benchmarks/skimage/cucim_measure_bench.py +++ b/benchmarks/skimage/cucim_measure_bench.py @@ -3,8 +3,6 @@ import os import pickle -import cucim.skimage -import cucim.skimage.measure import cupy as cp import numpy as np import pandas as pd @@ -13,6 +11,9 @@ from _image_bench import ImageBench from cucim_metrics_bench import MetricsBench +import cucim.skimage +import cucim.skimage.measure + class LabelBench(ImageBench): def __init__( @@ -328,7 +329,7 @@ def main(args): fbase = os.path.splitext(pfile)[0] all_results.to_csv(fbase + ".csv") all_results.to_pickle(pfile) - with open(fbase + ".md", "wt") as f: + with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) diff --git a/benchmarks/skimage/cucim_metrics_bench.py b/benchmarks/skimage/cucim_metrics_bench.py index 585dd7be8..4dd8aae49 100644 --- a/benchmarks/skimage/cucim_metrics_bench.py +++ b/benchmarks/skimage/cucim_metrics_bench.py @@ -2,14 +2,15 @@ import os import pickle -import cucim.skimage -import cucim.skimage.metrics import cupy as cp import numpy as np import pandas as pd import skimage import skimage.metrics from _image_bench import ImageBench + +import cucim.skimage +import cucim.skimage.metrics from cucim.skimage import data, measure @@ -176,7 +177,7 @@ def main(args): fbase = os.path.splitext(pfile)[0] all_results.to_csv(fbase + ".csv") all_results.to_pickle(pfile) - with open(fbase + ".md", "wt") as f: + with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) diff --git a/benchmarks/skimage/cucim_morphology_bench.py b/benchmarks/skimage/cucim_morphology_bench.py index 68c5aeefc..8056ad507 100644 --- a/benchmarks/skimage/cucim_morphology_bench.py +++ b/benchmarks/skimage/cucim_morphology_bench.py @@ -6,8 +6,6 @@ import os import pickle -import cucim.skimage -import cucim.skimage.morphology import cupy as cp import numpy as np import pandas as pd @@ -17,6 +15,9 @@ import skimage.morphology from _image_bench import ImageBench +import cucim.skimage +import cucim.skimage.morphology + class BinaryMorphologyBench(ImageBench): def __init__( @@ -281,7 +282,7 @@ def main(args): try: import tabular # noqa: F401 - with open(fbase + ".md", "wt") as f: + with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) except ImportError: pass diff --git a/benchmarks/skimage/cucim_registration_bench.py b/benchmarks/skimage/cucim_registration_bench.py index be5b94594..e35eaebf1 100644 --- a/benchmarks/skimage/cucim_registration_bench.py +++ b/benchmarks/skimage/cucim_registration_bench.py @@ -3,8 +3,6 @@ import os import pickle -import cucim.skimage -import cucim.skimage.registration import cupy as cp import numpy as np import pandas as pd @@ -12,6 +10,9 @@ import skimage.registration from _image_bench import ImageBench +import cucim.skimage +import cucim.skimage.registration + class RegistrationBench(ImageBench): def set_args(self, dtype): @@ -145,7 +146,7 @@ def main(args): try: import tabular # noqa: F401 - with open(fbase + ".md", "wt") as f: + with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) except ImportError: pass diff --git a/benchmarks/skimage/cucim_restoration_bench.py b/benchmarks/skimage/cucim_restoration_bench.py index c876cae12..c87eb84f0 100644 --- a/benchmarks/skimage/cucim_restoration_bench.py +++ b/benchmarks/skimage/cucim_restoration_bench.py @@ -3,8 +3,6 @@ import os import pickle -import cucim.skimage -import cucim.skimage.restoration import cupy as cp import cupyx.scipy.ndimage as ndi import numpy as np @@ -12,9 +10,12 @@ import skimage import skimage.restoration from _image_bench import ImageBench -from cucim.skimage.restoration import denoise_tv_chambolle as tv_gpu from skimage.restoration import denoise_tv_chambolle as tv_cpu +import cucim.skimage +import cucim.skimage.restoration +from cucim.skimage.restoration import denoise_tv_chambolle as tv_gpu + class DenoiseBench(ImageBench): def set_args(self, dtype): @@ -180,7 +181,7 @@ def main(args): try: import tabular # noqa: F401 - with open(fbase + ".md", "wt") as f: + with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) except ImportError: pass diff --git a/benchmarks/skimage/cucim_segmentation_bench.py b/benchmarks/skimage/cucim_segmentation_bench.py index 77bbae630..012420173 100644 --- a/benchmarks/skimage/cucim_segmentation_bench.py +++ b/benchmarks/skimage/cucim_segmentation_bench.py @@ -3,13 +3,14 @@ import os import pickle -import cucim.skimage import cupy as cp import numpy as np import pandas as pd import skimage import skimage.segmentation from _image_bench import ImageBench + +import cucim.skimage from cucim.skimage import data, measure @@ -296,7 +297,7 @@ def main(args): try: import tabular # noqa: F401 - with open(fbase + ".md", "wt") as f: + with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) except ImportError: pass diff --git a/benchmarks/skimage/cucim_transform_bench.py b/benchmarks/skimage/cucim_transform_bench.py index 6cc007af9..23b7832f2 100644 --- a/benchmarks/skimage/cucim_transform_bench.py +++ b/benchmarks/skimage/cucim_transform_bench.py @@ -2,14 +2,15 @@ import os import pickle -import cucim.skimage -import cucim.skimage.transform import numpy as np import pandas as pd import skimage import skimage.transform from _image_bench import ImageBench +import cucim.skimage +import cucim.skimage.transform + def main(args): pfile = "cucim_transform_results.pickle" @@ -164,7 +165,7 @@ def main(args): try: import tabular # noqa: F401 - with open(fbase + ".md", "wt") as f: + with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) except ImportError: pass diff --git a/benchmarks/skimage/cupyx_scipy_ndimage_filter_bench.py b/benchmarks/skimage/cupyx_scipy_ndimage_filter_bench.py index a820c699e..451040bf5 100644 --- a/benchmarks/skimage/cupyx_scipy_ndimage_filter_bench.py +++ b/benchmarks/skimage/cupyx_scipy_ndimage_filter_bench.py @@ -129,5 +129,5 @@ def set_args(self, dtype): fbase = os.path.splitext(pfile)[0] all_results.to_csv(fbase + ".csv") all_results.to_pickle(pfile) -with open(fbase + ".md", "wt") as f: +with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) diff --git a/benchmarks/skimage/cupyx_scipy_ndimage_fourier_bench.py b/benchmarks/skimage/cupyx_scipy_ndimage_fourier_bench.py index 92a4795e0..c2e4160e7 100644 --- a/benchmarks/skimage/cupyx_scipy_ndimage_fourier_bench.py +++ b/benchmarks/skimage/cupyx_scipy_ndimage_fourier_bench.py @@ -50,5 +50,5 @@ def set_args(self, dtype): fbase = os.path.splitext(pfile)[0] all_results.to_csv(fbase + ".csv") all_results.to_pickle(pfile) -with open(fbase + ".md", "wt") as f: +with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) diff --git a/benchmarks/skimage/cupyx_scipy_ndimage_interp_bench.py b/benchmarks/skimage/cupyx_scipy_ndimage_interp_bench.py index 63773732c..c6977cef4 100644 --- a/benchmarks/skimage/cupyx_scipy_ndimage_interp_bench.py +++ b/benchmarks/skimage/cupyx_scipy_ndimage_interp_bench.py @@ -153,5 +153,5 @@ def set_args(self, dtype): fbase = os.path.splitext(pfile)[0] all_results.to_csv(fbase + ".csv") all_results.to_pickle(pfile) -with open(fbase + ".md", "wt") as f: +with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) diff --git a/benchmarks/skimage/cupyx_scipy_ndimage_measurements_bench.py b/benchmarks/skimage/cupyx_scipy_ndimage_measurements_bench.py index 61b3de5a4..e3975972b 100644 --- a/benchmarks/skimage/cupyx_scipy_ndimage_measurements_bench.py +++ b/benchmarks/skimage/cupyx_scipy_ndimage_measurements_bench.py @@ -185,5 +185,5 @@ def set_args(self, dtype): fbase = os.path.splitext(pfile)[0] all_results.to_csv(fbase + ".csv") all_results.to_pickle(pfile) -with open(fbase + ".md", "wt") as f: +with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) diff --git a/benchmarks/skimage/cupyx_scipy_ndimage_morphology_bench.py b/benchmarks/skimage/cupyx_scipy_ndimage_morphology_bench.py index a177c99f9..a2e509a72 100644 --- a/benchmarks/skimage/cupyx_scipy_ndimage_morphology_bench.py +++ b/benchmarks/skimage/cupyx_scipy_ndimage_morphology_bench.py @@ -152,5 +152,5 @@ def set_args(self, dtype): fbase = os.path.splitext(pfile)[0] all_results.to_csv(fbase + ".csv") all_results.to_pickle(pfile) -with open(fbase + ".md", "wt") as f: +with open(fbase + ".md", "w") as f: f.write(all_results.to_markdown()) diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 161a787af..81f3200a1 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -40,7 +40,7 @@ dependencies: - pytest-lazy-fixtures>=1.0.0 - pytest-xdist - pytest>=6.2.4,<8.0.0a0 -- python>=3.8,<3.12 +- python>=3.10,<3.12 - pywavelets>=1.0 - recommonmark - scikit-image>=0.19.0,<0.24.0a0 diff --git a/conda/environments/all_cuda-125_arch-x86_64.yaml b/conda/environments/all_cuda-125_arch-x86_64.yaml index 65e94df9e..709f22f18 100644 --- a/conda/environments/all_cuda-125_arch-x86_64.yaml +++ b/conda/environments/all_cuda-125_arch-x86_64.yaml @@ -39,7 +39,7 @@ dependencies: - pytest-lazy-fixtures>=1.0.0 - pytest-xdist - pytest>=6.2.4,<8.0.0a0 -- python>=3.8,<3.12 +- python>=3.10,<3.12 - pywavelets>=1.0 - recommonmark - scikit-image>=0.19.0,<0.24.0a0 diff --git a/cpp/plugins/cucim.kit.cuslide/src/cuslide/jpeg2k/gen_color_table.py b/cpp/plugins/cucim.kit.cuslide/src/cuslide/jpeg2k/gen_color_table.py index 9d9de21f3..2b1d1b366 100644 --- a/cpp/plugins/cucim.kit.cuslide/src/cuslide/jpeg2k/gen_color_table.py +++ b/cpp/plugins/cucim.kit.cuslide/src/cuslide/jpeg2k/gen_color_table.py @@ -138,7 +138,7 @@ def gen_b_cb(): """ b_cb = [0] * 256 for i in range(256): - b_cb[i] = int((1.77204 * (i - 128))) + b_cb[i] = int(1.77204 * (i - 128)) return b_cb diff --git a/dependencies.yaml b/dependencies.yaml index 701aa5f77..4cfc8e8a0 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -232,14 +232,6 @@ dependencies: specific: - output_types: conda matrices: - - matrix: - py: "3.8" - packages: - - python=3.8 - - matrix: - py: "3.9" - packages: - - python=3.9 - matrix: py: "3.10" packages: @@ -250,7 +242,7 @@ dependencies: - python=3.11 - matrix: packages: - - python>=3.8,<3.12 + - python>=3.10,<3.12 rapids_build_setuptools: common: - output_types: [conda, requirements, pyproject] diff --git a/docs/source/conf.py b/docs/source/conf.py index a7d832627..ee7ef06c8 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # # Copyright (c) 2018, NVIDIA CORPORATION. # @@ -21,6 +20,7 @@ # import os import sys + from packaging.version import Version import cucim diff --git a/examples/python/distance_transform_edt_demo.py b/examples/python/distance_transform_edt_demo.py index d9813b2f4..405cd0f23 100644 --- a/examples/python/distance_transform_edt_demo.py +++ b/examples/python/distance_transform_edt_demo.py @@ -10,10 +10,11 @@ print("This demo requires the matplotlib and colorcet packages.") raise (e) +from skimage import data + from cucim.core.operations.morphology import distance_transform_edt from cucim.skimage.color import label2rgb from cucim.skimage.segmentation import relabel_sequential -from skimage import data def coords_to_labels(coords): diff --git a/examples/python/gds_whole_slide/benchmark_round_trip.py b/examples/python/gds_whole_slide/benchmark_round_trip.py index 2335e73a0..21f4ec278 100644 --- a/examples/python/gds_whole_slide/benchmark_round_trip.py +++ b/examples/python/gds_whole_slide/benchmark_round_trip.py @@ -1,15 +1,16 @@ import os from time import time -import cucim.skimage.filters import cupy as cp import kvikio import kvikio.defaults import numpy as np -from cucim.core.operations.color import image_to_absorbance from cupyx.profiler import benchmark from demo_implementation import cupy_to_zarr, read_tiled +import cucim.skimage.filters +from cucim.core.operations.color import image_to_absorbance + data_dir = os.environ.get("WHOLE_SLIDE_DATA_DIR", os.path.dirname("__file__")) fname = os.path.join(data_dir, "resize.tiff") if not os.path.exists(fname): diff --git a/examples/python/gds_whole_slide/benchmark_zarr_write.py b/examples/python/gds_whole_slide/benchmark_zarr_write.py index f1f4a021b..13376f410 100644 --- a/examples/python/gds_whole_slide/benchmark_zarr_write.py +++ b/examples/python/gds_whole_slide/benchmark_zarr_write.py @@ -4,11 +4,12 @@ import cupy as cp import kvikio.defaults import numpy as np -from cucim.core.operations.color import image_to_absorbance from cupyx.profiler import benchmark from demo_implementation import cupy_to_zarr, get_n_tiles, read_tiled from tifffile import TiffFile +from cucim.core.operations.color import image_to_absorbance + data_dir = os.environ.get("WHOLE_SLIDE_DATA_DIR", os.path.dirname("__file__")) fname = os.path.join(data_dir, "resize.tiff") if not os.path.exists(fname): diff --git a/examples/python/gds_whole_slide/demo_implementation.py b/examples/python/gds_whole_slide/demo_implementation.py index 89cb69342..7d02c8407 100644 --- a/examples/python/gds_whole_slide/demo_implementation.py +++ b/examples/python/gds_whole_slide/demo_implementation.py @@ -8,13 +8,14 @@ import numpy as np import openslide import tifffile -from cucim.clara import filesystem from kvikio.cufile import IOFuture from kvikio.zarr import GDSStore from tifffile import TiffFile from zarr import DirectoryStore from zarr.creation import init_array +from cucim.clara import filesystem + """ Developed with Dask 2022.05.2 zarr >= 2.13.2 diff --git a/examples/python/gds_whole_slide/lz4_nvcomp.py b/examples/python/gds_whole_slide/lz4_nvcomp.py index 19fc5f3d9..a02d6c962 100644 --- a/examples/python/gds_whole_slide/lz4_nvcomp.py +++ b/examples/python/gds_whole_slide/lz4_nvcomp.py @@ -66,9 +66,7 @@ def ensure_contiguous_ndarray(buf, max_buffer_size=None, flatten=True): raise ValueError("an array with contiguous memory is required") if max_buffer_size is not None and arr.nbytes > max_buffer_size: - msg = "Codec does not support buffers of > {} bytes".format( - max_buffer_size - ) + msg = f"Codec does not support buffers of > {max_buffer_size} bytes" raise ValueError(msg) return arr @@ -148,7 +146,7 @@ def decode(self, buf, out=None): return ndarray_copy(decompressed, out) def __repr__(self): - r = "%s" % type(self).__name__ + r = f"{type(self).__name__}" return r diff --git a/examples/python/tiff_image/main.py b/examples/python/tiff_image/main.py index 42adf36e0..c36149a9e 100644 --- a/examples/python/tiff_image/main.py +++ b/examples/python/tiff_image/main.py @@ -16,9 +16,10 @@ import json import numpy as np -from cucim import CuImage from PIL import Image +from cucim import CuImage + img = CuImage("image.tif") print(img.is_loaded) # True if image data is loaded & available. diff --git a/experiments/Supporting_Aperio_SVS_Format/benchmark.py b/experiments/Supporting_Aperio_SVS_Format/benchmark.py index db5deac70..24787ed6d 100644 --- a/experiments/Supporting_Aperio_SVS_Format/benchmark.py +++ b/experiments/Supporting_Aperio_SVS_Format/benchmark.py @@ -19,9 +19,10 @@ from itertools import repeat from time import perf_counter +from openslide import OpenSlide + from cucim import CuImage from cucim.clara.filesystem import discard_page_cache # noqa: F401 -from openslide import OpenSlide class Timer(ContextDecorator): @@ -40,7 +41,7 @@ def __enter__(self): def __exit__(self, exc_type, exc, exc_tb): if not self.end: self.elapsed_time() - print("{} : {}".format(self.message, self.end - self.start)) + print(f"{self.message} : {self.end - self.start}") def load_tile_openslide(slide, start_loc, patch_size): diff --git a/experiments/Using_Cache/benchmark.py b/experiments/Using_Cache/benchmark.py index b1f69c5dc..c811b6f9a 100644 --- a/experiments/Using_Cache/benchmark.py +++ b/experiments/Using_Cache/benchmark.py @@ -21,10 +21,11 @@ import numpy as np import rasterio -from cucim import CuImage from openslide import OpenSlide from rasterio.windows import Window +from cucim import CuImage + class Timer(ContextDecorator): def __init__(self, message): @@ -42,7 +43,7 @@ def __enter__(self): def __exit__(self, exc_type, exc, exc_tb): if not self.end: self.elapsed_time() - print("{} : {}".format(self.message, self.end - self.start)) + print(f"{self.message} : {self.end - self.start}") def load_tile_openslide(slide, start_loc, patch_size): diff --git a/python/cucim/pyproject.toml b/python/cucim/pyproject.toml index 2df37c5a7..09ba8d15a 100644 --- a/python/cucim/pyproject.toml +++ b/python/cucim/pyproject.toml @@ -22,7 +22,7 @@ authors = [ { name = "NVIDIA Corporation" }, ] license = { text = "Apache 2.0" } -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = [ "click", "cupy-cuda11x>=12.0.0", @@ -147,9 +147,6 @@ filterwarnings = [ ] [tool.ruff] -# see: https://docs.astral.sh/ruff/rules/ -select = ["E", "F", "W", "I", "UP"] -fixable = ["ALL"] exclude = [ # TODO: Remove this in a follow-up where we fix __all__. ".tox", @@ -159,17 +156,29 @@ exclude = [ "dist", ".git", "__pycache__", - "doc/conf.py", - "doc/sphinxext", + "docs/source/conf.py", + "docs/source/ext", "__init__.py", + "python/cucim/src/cucim/skimage/_vendored", ] line-length = 80 fix = true -[tool.ruff.per-file-ignores] +[tool.ruff.lint] +# see: https://docs.astral.sh/ruff/rules/ +select = ["E", "F", "W", "I", "UP"] +ignore = [ + # (pycodestyle) Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + "E721", + # (pyupgrade) Use `X | Y` in `isinstance` call instead of `(X, Y)` + "UP038", +] +fixable = ["ALL"] + +[tool.ruff.lint.per-file-ignores] # "src/cucim/skimage/util/tests/test_shape.py" = ["E201", "E202"] -[tool.ruff.isort] +[tool.ruff.lint.isort] combine-as-imports = true force-single-line = false known-first-party = ["cucim"] @@ -177,7 +186,7 @@ order-by-type = true [tool.black] line-length = 80 -target-version = ["py39"] +target-version = ["py310"] include = '\.py?$' exclude = ''' /( diff --git a/python/cucim/src/cucim/core/operations/color/jitter.py b/python/cucim/src/cucim/core/operations/color/jitter.py index 67b70dfc2..313b24d99 100755 --- a/python/cucim/src/cucim/core/operations/color/jitter.py +++ b/python/cucim/src/cucim/core/operations/color/jitter.py @@ -13,7 +13,7 @@ # limitations under the License. import numbers -from typing import Any, Optional +from typing import Any import cupy import numpy as np @@ -51,17 +51,11 @@ def _check_input( def _get_params( - brightness: Optional[list[float]], - contrast: Optional[list[float]], - saturation: Optional[list[float]], - hue: Optional[list[float]], -) -> tuple[ - np.ndarray, - Optional[float], - Optional[float], - Optional[float], - Optional[float], -]: + brightness: list[float] | None, + contrast: list[float] | None, + saturation: list[float] | None, + hue: list[float] | None, +) -> tuple[np.ndarray, float | None, float | None, float | None, float | None,]: fn_idx = np.random.permutation(4) b = None diff --git a/python/cucim/src/cucim/core/operations/color/stain_normalizer.py b/python/cucim/src/cucim/core/operations/color/stain_normalizer.py index 84638b4e0..08c0f9129 100644 --- a/python/cucim/src/cucim/core/operations/color/stain_normalizer.py +++ b/python/cucim/src/cucim/core/operations/color/stain_normalizer.py @@ -13,7 +13,6 @@ # limitations under the License. import math -from typing import Union import cupy as cp import numpy as np @@ -446,12 +445,13 @@ def normalize_colors_pca( source_intensity: float = 240.0, alpha: float = 1.0, beta: float = 0.345, - ref_stain_coeff: Union[tuple, cp.ndarray] = ( + ref_stain_coeff: tuple + | cp.ndarray = ( (0.5626, 0.2159), (0.7201, 0.8012), (0.4062, 0.5581), ), - ref_max_conc: Union[tuple, cp.ndarray] = (1.9705, 1.0308), + ref_max_conc: tuple | cp.ndarray = (1.9705, 1.0308), image_type: str = "intensity", channel_axis: int = 0, ): diff --git a/python/cucim/src/cucim/core/operations/intensity/zoom.py b/python/cucim/src/cucim/core/operations/intensity/zoom.py index 3312a0638..b875bc3b6 100644 --- a/python/cucim/src/cucim/core/operations/intensity/zoom.py +++ b/python/cucim/src/cucim/core/operations/intensity/zoom.py @@ -14,7 +14,7 @@ import math from collections.abc import Sequence -from typing import Any, Union +from typing import Any import cupy import numpy as np @@ -224,8 +224,8 @@ def get_block_size(output_size_cu, H, W): def get_zoom_factor( - min_zoom: Union[Sequence[float], float] = 0.9, - max_zoom: Union[Sequence[float], float] = 1.1, + min_zoom: Sequence[float] | float = 0.9, + max_zoom: Sequence[float] | float = 1.1, ): R = np.random.RandomState() try: @@ -243,8 +243,8 @@ def get_zoom_factor( def rand_zoom( img: Any, - min_zoom: Union[Sequence[float], float] = 0.9, - max_zoom: Union[Sequence[float], float] = 1.1, + min_zoom: Sequence[float] | float = 0.9, + max_zoom: Sequence[float] | float = 1.1, prob: float = 0.1, whole_batch: bool = False, ): diff --git a/python/cucim/src/cucim/skimage/_shared/version_requirements.py b/python/cucim/src/cucim/skimage/_shared/version_requirements.py index 17c7afcc5..e5bf41e36 100644 --- a/python/cucim/src/cucim/skimage/_shared/version_requirements.py +++ b/python/cucim/src/cucim/skimage/_shared/version_requirements.py @@ -79,9 +79,12 @@ def is_installed(name, version=None): symb = version[: match.start()] if not symb: symb = "=" - assert symb in (">=", ">", "=", "<"), ( - "Invalid version condition '%s'" % symb - ) + assert symb in ( + ">=", + ">", + "=", + "<", + ), f"Invalid version condition '{symb}'" version = version[match.start() :] return _check_version(actver, version, symb) @@ -115,10 +118,9 @@ def func_wrapped(*args, **kwargs): if is_installed(name, version): return obj(*args, **kwargs) else: - msg = '"%s" in "%s" requires "%s' - msg = msg % (obj, obj.__module__, name) + msg = f'"{obj}" in "{obj.__module__}" requires "{name}"' if version is not None: - msg += " %s" % version + msg += f" {version}" raise ImportError(msg + '"') return func_wrapped diff --git a/python/cucim/src/cucim/skimage/_vendored/pad.py b/python/cucim/src/cucim/skimage/_vendored/pad.py index 249a2c1ed..a3d22a7a0 100644 --- a/python/cucim/src/cucim/skimage/_vendored/pad.py +++ b/python/cucim/src/cucim/skimage/_vendored/pad.py @@ -666,9 +666,7 @@ def pad(array, pad_width, mode="constant", **kwargs): raise ValueError(f"mode '{mode}' is not supported") if unsupported_kwargs: raise ValueError( - "unsupported keyword arguments for mode '{}': {}".format( - mode, unsupported_kwargs - ) + f"unsupported keyword arguments for mode '{mode}': {unsupported_kwargs}" ) if _use_elementwise_kernel(array, mode, kwargs): diff --git a/python/cucim/src/cucim/skimage/_vendored/time.py b/python/cucim/src/cucim/skimage/_vendored/time.py index 5ec1156ce..e55027212 100644 --- a/python/cucim/src/cucim/skimage/_vendored/time.py +++ b/python/cucim/src/cucim/skimage/_vendored/time.py @@ -36,9 +36,7 @@ def _to_str_per_item(device_name, t): s = f" {device_name}:{t_us.mean():9.03f} us" if t.size > 1: - s += " +/-{:6.03f} (min:{:9.03f} / max:{:9.03f}) us".format( - t_us.std(), t_us.min(), t_us.max() - ) + s += f" +/-{t_us.std():6.03f} (min:{t_us.min():9.03f} / max:{t_us.max():9.03f}) us" return s def to_str(self, show_gpu=False): diff --git a/python/cucim/src/cucim/skimage/metrics/_structural_similarity.py b/python/cucim/src/cucim/skimage/metrics/_structural_similarity.py index 04ad88ab2..d89e28c70 100644 --- a/python/cucim/src/cucim/skimage/metrics/_structural_similarity.py +++ b/python/cucim/src/cucim/skimage/metrics/_structural_similarity.py @@ -269,7 +269,7 @@ def structural_similarity( if cp.issubdtype(im1.dtype, cp.integer) and (im1.dtype != cp.uint8): warn( "Setting data_range based on im1.dtype. " - + ("data_range = %.0f. " % data_range) + + f"data_range = {data_range:.0f}. " + "Please specify data_range explicitly to avoid mistakes.", stacklevel=2, ) diff --git a/python/cucim/src/cucim/skimage/transform/_geometric.py b/python/cucim/src/cucim/skimage/transform/_geometric.py index 25347db26..47cc133b8 100644 --- a/python/cucim/src/cucim/skimage/transform/_geometric.py +++ b/python/cucim/src/cucim/skimage/transform/_geometric.py @@ -1936,7 +1936,7 @@ def estimate_transform(ttype, src, dst, *args, **kwargs): ttype = ttype.lower() if ttype not in TRANSFORMS: raise ValueError( - "the transformation type '%s' is not" "implemented" % ttype + f"the transformation type '{ttype}' is not" "implemented" ) tform = TRANSFORMS[ttype](dimensionality=src.shape[1]) diff --git a/python/cucim/src/localtest.py b/python/cucim/src/localtest.py index f5794dd43..c80949f7b 100644 --- a/python/cucim/src/localtest.py +++ b/python/cucim/src/localtest.py @@ -148,7 +148,5 @@ def load_tile_cucim(slide, start_loc, tile_size): print("Total time (OpenSlide):", openslide_tot_time) print("Total time (cuCIM):", cucim_tot_time) print( - "Average performance gain (OpenSlide/cuCIM): {}".format( - openslide_tot_time / cucim_tot_time - ) + f"Average performance gain (OpenSlide/cuCIM): {openslide_tot_time / cucim_tot_time}" # noqa: E501 )