From 384f17cd403f91852443105ee161bfb2ab9f65c6 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:17:56 +0200 Subject: [PATCH 1/5] Apply ruff/refurb rule FURB110 FURB110 Replace ternary `if` expression with `or` operator --- src/zarr/core/indexing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zarr/core/indexing.py b/src/zarr/core/indexing.py index d2e29b3b55..a132d3cc31 100644 --- a/src/zarr/core/indexing.py +++ b/src/zarr/core/indexing.py @@ -1129,7 +1129,7 @@ def __init__( chunks_multi_index_broadcast = np.broadcast_arrays(*chunks_multi_index) # remember shape of selection, because we will flatten indices for processing - sel_shape = selection_broadcast[0].shape if selection_broadcast[0].shape else (1,) + sel_shape = selection_broadcast[0].shape or (1,) # flatten selection selection_broadcast = tuple(dim_sel.reshape(-1) for dim_sel in selection_broadcast) @@ -1150,7 +1150,7 @@ def __init__( else: sel_sort = None - shape = selection_broadcast[0].shape if selection_broadcast[0].shape else (1,) + shape = selection_broadcast[0].shape or (1,) # precompute number of selected items for each chunk chunk_nitems = np.bincount(chunks_raveled_indices, minlength=nchunks) From 6174d08f5eb62c92ae453c9b7ed584c2e40b13d9 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:52:25 +0200 Subject: [PATCH 2/5] Apply ruff/refurb rule FURB118 FURB118 Use `operator.itemgetter(0)` instead of defining a lambda --- tests/test_group.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/test_group.py b/tests/test_group.py index 2530f64ff4..f4063f6ef9 100644 --- a/tests/test_group.py +++ b/tests/test_group.py @@ -1,6 +1,7 @@ from __future__ import annotations import contextlib +import operator import pickle import warnings from typing import TYPE_CHECKING, Any, Literal @@ -533,14 +534,14 @@ def test_group_child_iterators(store: Store, zarr_format: ZarrFormat, consolidat ConsolidatedMetadata(metadata={}), ) - result = sorted(group.groups(), key=lambda x: x[0]) + result = sorted(group.groups(), key=operator.itemgetter(0)) assert result == expected_groups - assert sorted(group.groups(), key=lambda x: x[0]) == expected_groups + assert sorted(group.groups(), key=operator.itemgetter(0)) == expected_groups assert sorted(group.group_keys()) == expected_group_keys assert sorted(group.group_values(), key=lambda x: x.name) == expected_group_values - assert sorted(group.arrays(), key=lambda x: x[0]) == expected_arrays + assert sorted(group.arrays(), key=operator.itemgetter(0)) == expected_arrays assert sorted(group.array_keys()) == expected_array_keys assert sorted(group.array_values(), key=lambda x: x.name) == expected_array_values @@ -1000,7 +1001,7 @@ async def test_group_members_async(store: Store, consolidated_metadata: bool) -> g2 = await g1.create_group("g2") # immediate children - children = sorted([x async for x in group.members()], key=lambda x: x[0]) + children = sorted([x async for x in group.members()], key=operator.itemgetter(0)) assert children == [ ("a0", a0), ("g0", g0), @@ -1010,7 +1011,7 @@ async def test_group_members_async(store: Store, consolidated_metadata: bool) -> assert nmembers == 2 # partial - children = sorted([x async for x in group.members(max_depth=1)], key=lambda x: x[0]) + children = sorted([x async for x in group.members(max_depth=1)], key=operator.itemgetter(0)) expected = [ ("a0", a0), ("g0", g0), @@ -1022,7 +1023,9 @@ async def test_group_members_async(store: Store, consolidated_metadata: bool) -> assert nmembers == 4 # all children - all_children = sorted([x async for x in group.members(max_depth=None)], key=lambda x: x[0]) + all_children = sorted( + [x async for x in group.members(max_depth=None)], key=operator.itemgetter(0) + ) expected = [ ("a0", a0), ("g0", g0), @@ -1053,7 +1056,9 @@ async def test_group_members_async(store: Store, consolidated_metadata: bool) -> "consolidated_metadata", None, ) - all_children = sorted([x async for x in group.members(max_depth=None)], key=lambda x: x[0]) + all_children = sorted( + [x async for x in group.members(max_depth=None)], key=operator.itemgetter(0) + ) assert len(all_children) == 4 nmembers = await group.nmembers(max_depth=None) assert nmembers == 4 From 412b2dc45c14c882fe98a5f73e8541d5462e39b7 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:53:34 +0200 Subject: [PATCH 3/5] Apply ruff/refurb rule FURB140 FURB140 Use `itertools.starmap` instead of the generator --- src/zarr/abc/store.py | 3 ++- src/zarr/core/array.py | 5 +++-- src/zarr/core/chunk_grids.py | 2 +- src/zarr/core/common.py | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/zarr/abc/store.py b/src/zarr/abc/store.py index 40c8129afe..bf61a5908a 100644 --- a/src/zarr/abc/store.py +++ b/src/zarr/abc/store.py @@ -2,6 +2,7 @@ from abc import ABC, abstractmethod from asyncio import gather +from itertools import starmap from typing import TYPE_CHECKING, NamedTuple, Protocol, runtime_checkable if TYPE_CHECKING: @@ -282,7 +283,7 @@ async def _set_many(self, values: Iterable[tuple[str, Buffer]]) -> None: """ Insert multiple (key, value) pairs into storage. """ - await gather(*(self.set(key, value) for key, value in values)) + await gather(*starmap(self.set, values)) return @property diff --git a/src/zarr/core/array.py b/src/zarr/core/array.py index da477056ee..91daf7ed81 100644 --- a/src/zarr/core/array.py +++ b/src/zarr/core/array.py @@ -3,6 +3,7 @@ import json from asyncio import gather from dataclasses import dataclass, field, replace +from itertools import starmap from logging import getLogger from typing import TYPE_CHECKING, Any, Generic, Literal, cast, overload @@ -818,7 +819,7 @@ def cdata_shape(self) -> ChunkCoords: Tuple[int] The shape of the chunk grid for this array. """ - return tuple(ceildiv(s, c) for s, c in zip(self.shape, self.chunks, strict=False)) + return tuple(starmap(ceildiv, zip(self.shape, self.chunks, strict=False))) @property def nchunks(self) -> int: @@ -1397,7 +1398,7 @@ def cdata_shape(self) -> ChunkCoords: """ The shape of the chunk grid for this array. """ - return tuple(ceildiv(s, c) for s, c in zip(self.shape, self.chunks, strict=False)) + return tuple(starmap(ceildiv, zip(self.shape, self.chunks, strict=False))) @property def nchunks(self) -> int: diff --git a/src/zarr/core/chunk_grids.py b/src/zarr/core/chunk_grids.py index 77734056b3..be8a9228bf 100644 --- a/src/zarr/core/chunk_grids.py +++ b/src/zarr/core/chunk_grids.py @@ -188,6 +188,6 @@ def all_chunk_coords(self, array_shape: ChunkCoords) -> Iterator[ChunkCoords]: def get_nchunks(self, array_shape: ChunkCoords) -> int: return reduce( operator.mul, - (ceildiv(s, c) for s, c in zip(array_shape, self.chunk_shape, strict=True)), + itertools.starmap(ceildiv, zip(array_shape, self.chunk_shape, strict=True)), 1, ) diff --git a/src/zarr/core/common.py b/src/zarr/core/common.py index 0bc6245cb5..f3f49b0d5d 100644 --- a/src/zarr/core/common.py +++ b/src/zarr/core/common.py @@ -5,6 +5,7 @@ import operator from collections.abc import Iterable, Mapping from enum import Enum +from itertools import starmap from typing import ( TYPE_CHECKING, Any, @@ -52,7 +53,7 @@ async def concurrent_map( items: Iterable[T], func: Callable[..., Awaitable[V]], limit: int | None = None ) -> list[V]: if limit is None: - return await asyncio.gather(*[func(*item) for item in items]) + return await asyncio.gather(*list(starmap(func, items))) else: sem = asyncio.Semaphore(limit) From 6eeecf3e433c2a7b7fe787a4f52e6d47560ea633 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:18:31 +0200 Subject: [PATCH 4/5] Apply ruff/refurb rule FURB188 FURB188 Prefer `removesuffix` over conditionally replacing with slice. --- src/zarr/storage/memory.py | 3 +-- src/zarr/storage/zip.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/zarr/storage/memory.py b/src/zarr/storage/memory.py index 673c2a75d5..41e41b05ec 100644 --- a/src/zarr/storage/memory.py +++ b/src/zarr/storage/memory.py @@ -156,8 +156,7 @@ async def list_prefix(self, prefix: str) -> AsyncGenerator[str, None]: async def list_dir(self, prefix: str) -> AsyncGenerator[str, None]: # docstring inherited - if prefix.endswith("/"): - prefix = prefix[:-1] + prefix = prefix.rstrip("/") if prefix == "": keys_unique = {k.split("/")[0] for k in self._store_dict} diff --git a/src/zarr/storage/zip.py b/src/zarr/storage/zip.py index c9cb579586..204a381bdb 100644 --- a/src/zarr/storage/zip.py +++ b/src/zarr/storage/zip.py @@ -245,8 +245,7 @@ async def list_prefix(self, prefix: str) -> AsyncGenerator[str, None]: async def list_dir(self, prefix: str) -> AsyncGenerator[str, None]: # docstring inherited - if prefix.endswith("/"): - prefix = prefix[:-1] + prefix = prefix.rstrip("/") keys = self._zf.namelist() seen = set() From b0f2829847be5f2c6dbd0075e1ca3f9321c4b32f Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:21:09 +0200 Subject: [PATCH 5/5] Apply ruff/refurb rules (FURB) --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 574b09b076..c8b7939f31 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -214,6 +214,7 @@ extend-select = [ "B", # flake8-bugbear "C4", # flake8-comprehensions "FLY", # flynt + "FURB", # refurb "G", # flake8-logging-format "I", # isort "ISC", # flake8-implicit-str-concat