From 69cef56b3e2af4f6df7af76a8535350c8b2e5365 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 13:47:52 +0200 Subject: [PATCH 01/14] Enforce ruff/flake8-executable rules (EXE) --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index bb9fa4df85..fd44d7936e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -269,6 +269,7 @@ extend-exclude = [ extend-select = [ "ANN", # flake8-annotations "B", # flake8-bugbear + "EXE", # flake8-executable "C4", # flake8-comprehensions "FLY", # flynt "FURB", # refurb From 0cd688a3d1073186ec28b171e1bfa003b641b873 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 13:48:55 +0200 Subject: [PATCH 02/14] Enforce ruff/flake8-future-annotations rules (FA) --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index fd44d7936e..e1397da631 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -271,6 +271,7 @@ extend-select = [ "B", # flake8-bugbear "EXE", # flake8-executable "C4", # flake8-comprehensions + "FA", # flake8-future-annotations "FLY", # flynt "FURB", # refurb "G", # flake8-logging-format From 35cee547718ab1b8a61fecc53a7b2b0abcb385bd Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 13:49:42 +0200 Subject: [PATCH 03/14] Enforce ruff/flake8-logging rules (LOG) --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index e1397da631..902182a701 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -277,6 +277,7 @@ extend-select = [ "G", # flake8-logging-format "I", # isort "ISC", # flake8-implicit-str-concat + "LOG", # flake8-logging "PERF", # Perflint "PGH", # pygrep-hooks "PT", # flake8-pytest-style From 4973ce020280c8cec4cc79b1c9323d4437117981 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 13:54:19 +0200 Subject: [PATCH 04/14] Apply ruff/flake8-pie rule PIE790 PIE790 Unnecessary `pass` statement PIE790 Unnecessary `...` literal --- src/zarr/abc/codec.py | 1 - src/zarr/abc/metadata.py | 1 - tests/test_codecs/test_codecs.py | 1 - 3 files changed, 3 deletions(-) diff --git a/src/zarr/abc/codec.py b/src/zarr/abc/codec.py index f27152e84c..fabd042dbe 100644 --- a/src/zarr/abc/codec.py +++ b/src/zarr/abc/codec.py @@ -106,7 +106,6 @@ def validate(self, *, shape: ChunkCoords, dtype: np.dtype[Any], chunk_grid: Chun chunk_grid : ChunkGrid The array chunk grid """ - ... async def _decode_single(self, chunk_data: CodecOutput, chunk_spec: ArraySpec) -> CodecInput: raise NotImplementedError diff --git a/src/zarr/abc/metadata.py b/src/zarr/abc/metadata.py index 291ceb459c..a56f986645 100644 --- a/src/zarr/abc/metadata.py +++ b/src/zarr/abc/metadata.py @@ -42,6 +42,5 @@ def from_dict(cls, data: dict[str, JSON]) -> Self: """ Create an instance of the model from a dictionary """ - ... return cls(**data) diff --git a/tests/test_codecs/test_codecs.py b/tests/test_codecs/test_codecs.py index 0f2f892915..dfb8e1c595 100644 --- a/tests/test_codecs/test_codecs.py +++ b/tests/test_codecs/test_codecs.py @@ -56,7 +56,6 @@ def test_sharding_pickle() -> None: """ Test that sharding codecs can be pickled """ - pass @pytest.mark.parametrize("store", ["local", "memory"], indirect=["store"]) From 36906ba5b00653a0c39c6d73d7cd044159c31e42 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 13:56:33 +0200 Subject: [PATCH 05/14] Apply ruff/flake8-pie rule PIE800 PIE800 Unnecessary spread `**` --- tests/test_metadata/test_consolidated.py | 134 +++++++++-------------- 1 file changed, 54 insertions(+), 80 deletions(-) diff --git a/tests/test_metadata/test_consolidated.py b/tests/test_metadata/test_consolidated.py index c0218602f6..d9143d09d6 100644 --- a/tests/test_metadata/test_consolidated.py +++ b/tests/test_metadata/test_consolidated.py @@ -87,31 +87,27 @@ async def test_consolidated(self, memory_store_with_hierarchy: Store) -> None: metadata={ "air": ArrayV3Metadata.from_dict( { - **{ - "shape": (1, 2, 3), - "chunk_grid": { - "configuration": {"chunk_shape": (1, 2, 3)}, - "name": "regular", - }, + "shape": (1, 2, 3), + "chunk_grid": { + "configuration": {"chunk_shape": (1, 2, 3)}, + "name": "regular", }, **array_metadata, } ), "lat": ArrayV3Metadata.from_dict( { - **{ - "shape": (1,), - "chunk_grid": { - "configuration": {"chunk_shape": (1,)}, - "name": "regular", - }, + "shape": (1,), + "chunk_grid": { + "configuration": {"chunk_shape": (1,)}, + "name": "regular", }, **array_metadata, } ), "lon": ArrayV3Metadata.from_dict( { - **{"shape": (2,)}, + "shape": (2,), "chunk_grid": { "configuration": {"chunk_shape": (2,)}, "name": "regular", @@ -121,12 +117,10 @@ async def test_consolidated(self, memory_store_with_hierarchy: Store) -> None: ), "time": ArrayV3Metadata.from_dict( { - **{ - "shape": (3,), - "chunk_grid": { - "configuration": {"chunk_shape": (3,)}, - "name": "regular", - }, + "shape": (3,), + "chunk_grid": { + "configuration": {"chunk_shape": (3,)}, + "name": "regular", }, **array_metadata, } @@ -138,13 +132,11 @@ async def test_consolidated(self, memory_store_with_hierarchy: Store) -> None: "array": ArrayV3Metadata.from_dict( { **array_metadata, - **{ - "attributes": {"key": "child"}, - "shape": (4, 4), - "chunk_grid": { - "configuration": {"chunk_shape": (4, 4)}, - "name": "regular", - }, + "attributes": {"key": "child"}, + "shape": (4, 4), + "chunk_grid": { + "configuration": {"chunk_shape": (4, 4)}, + "name": "regular", }, } ), @@ -162,15 +154,11 @@ async def test_consolidated(self, memory_store_with_hierarchy: Store) -> None: "array": ArrayV3Metadata.from_dict( { **array_metadata, - **{ - "attributes": {"key": "grandchild"}, - "shape": (4, 4), - "chunk_grid": { - "configuration": { - "chunk_shape": (4, 4) - }, - "name": "regular", - }, + "attributes": {"key": "grandchild"}, + "shape": (4, 4), + "chunk_grid": { + "configuration": {"chunk_shape": (4, 4)}, + "name": "regular", }, } ), @@ -243,31 +231,27 @@ def test_consolidated_sync(self, memory_store): metadata={ "air": ArrayV3Metadata.from_dict( { - **{ - "shape": (1, 2, 3), - "chunk_grid": { - "configuration": {"chunk_shape": (1, 2, 3)}, - "name": "regular", - }, + "shape": (1, 2, 3), + "chunk_grid": { + "configuration": {"chunk_shape": (1, 2, 3)}, + "name": "regular", }, **array_metadata, } ), "lat": ArrayV3Metadata.from_dict( { - **{ - "shape": (1,), - "chunk_grid": { - "configuration": {"chunk_shape": (1,)}, - "name": "regular", - }, + "shape": (1,), + "chunk_grid": { + "configuration": {"chunk_shape": (1,)}, + "name": "regular", }, **array_metadata, } ), "lon": ArrayV3Metadata.from_dict( { - **{"shape": (2,)}, + "shape": (2,), "chunk_grid": { "configuration": {"chunk_shape": (2,)}, "name": "regular", @@ -277,12 +261,10 @@ def test_consolidated_sync(self, memory_store): ), "time": ArrayV3Metadata.from_dict( { - **{ - "shape": (3,), - "chunk_grid": { - "configuration": {"chunk_shape": (3,)}, - "name": "regular", - }, + "shape": (3,), + "chunk_grid": { + "configuration": {"chunk_shape": (3,)}, + "name": "regular", }, **array_metadata, } @@ -357,24 +339,20 @@ def test_flatten(self): metadata={ "air": ArrayV3Metadata.from_dict( { - **{ - "shape": (1, 2, 3), - "chunk_grid": { - "configuration": {"chunk_shape": (1, 2, 3)}, - "name": "regular", - }, + "shape": (1, 2, 3), + "chunk_grid": { + "configuration": {"chunk_shape": (1, 2, 3)}, + "name": "regular", }, **array_metadata, } ), "lat": ArrayV3Metadata.from_dict( { - **{ - "shape": (1,), - "chunk_grid": { - "configuration": {"chunk_shape": (1,)}, - "name": "regular", - }, + "shape": (1,), + "chunk_grid": { + "configuration": {"chunk_shape": (1,)}, + "name": "regular", }, **array_metadata, } @@ -386,13 +364,11 @@ def test_flatten(self): "array": ArrayV3Metadata.from_dict( { **array_metadata, - **{ - "attributes": {"key": "child"}, - "shape": (4, 4), - "chunk_grid": { - "configuration": {"chunk_shape": (4, 4)}, - "name": "regular", - }, + "attributes": {"key": "child"}, + "shape": (4, 4), + "chunk_grid": { + "configuration": {"chunk_shape": (4, 4)}, + "name": "regular", }, } ), @@ -403,13 +379,11 @@ def test_flatten(self): "array": ArrayV3Metadata.from_dict( { **array_metadata, - **{ - "attributes": {"key": "grandchild"}, - "shape": (4, 4), - "chunk_grid": { - "configuration": {"chunk_shape": (4, 4)}, - "name": "regular", - }, + "attributes": {"key": "grandchild"}, + "shape": (4, 4), + "chunk_grid": { + "configuration": {"chunk_shape": (4, 4)}, + "name": "regular", }, } ) From 9c05925fb2845c9940ead5c7ffb8c59743fdd064 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 13:57:21 +0200 Subject: [PATCH 06/14] Apply ruff/flake8-pie rule PIE808 PIE808 Unnecessary `start` argument in `range` --- src/zarr/codecs/gzip.py | 2 +- src/zarr/core/chunk_grids.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zarr/codecs/gzip.py b/src/zarr/codecs/gzip.py index c0ad5e1385..b6e693148e 100644 --- a/src/zarr/codecs/gzip.py +++ b/src/zarr/codecs/gzip.py @@ -21,7 +21,7 @@ def parse_gzip_level(data: JSON) -> int: if not isinstance(data, (int)): raise TypeError(f"Expected int, got {type(data)}") - if data not in range(0, 10): + if data not in range(10): raise ValueError( f"Expected an integer from the inclusive range (0, 9). Got {data} instead." ) diff --git a/src/zarr/core/chunk_grids.py b/src/zarr/core/chunk_grids.py index ed7f8a1f45..afecc6824f 100644 --- a/src/zarr/core/chunk_grids.py +++ b/src/zarr/core/chunk_grids.py @@ -182,7 +182,7 @@ def to_dict(self) -> dict[str, JSON]: def all_chunk_coords(self, array_shape: ChunkCoords) -> Iterator[ChunkCoords]: return itertools.product( - *(range(0, ceildiv(s, c)) for s, c in zip(array_shape, self.chunk_shape, strict=False)) + *(range(ceildiv(s, c)) for s, c in zip(array_shape, self.chunk_shape, strict=False)) ) def get_nchunks(self, array_shape: ChunkCoords) -> int: From 87ef16c76944fa042f9bba5e5c54366c8dc33671 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 14:00:36 +0200 Subject: [PATCH 07/14] Enforce ruff/flake8-pie rules (PIE) --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 902182a701..94d0679353 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -279,6 +279,7 @@ extend-select = [ "ISC", # flake8-implicit-str-concat "LOG", # flake8-logging "PERF", # Perflint + "PIE", # flake8-pie "PGH", # pygrep-hooks "PT", # flake8-pytest-style "PYI", # flake8-pyi From 0e621d189d1673fb93e0978abeda031ada4d55ed Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 14:01:03 +0200 Subject: [PATCH 08/14] Apply ruff preview rule RUF022 RUF022 `__all__` is not sorted --- src/zarr/core/metadata/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/zarr/core/metadata/__init__.py b/src/zarr/core/metadata/__init__.py index f4374d9aba..43b5ec98fe 100644 --- a/src/zarr/core/metadata/__init__.py +++ b/src/zarr/core/metadata/__init__.py @@ -8,10 +8,10 @@ T_ArrayMetadata = TypeVar("T_ArrayMetadata", ArrayV2Metadata, ArrayV3Metadata) __all__ = [ - "ArrayV2Metadata", - "ArrayV3Metadata", "ArrayMetadata", "ArrayMetadataDict", - "ArrayV3MetadataDict", + "ArrayV2Metadata", "ArrayV2MetadataDict", + "ArrayV3Metadata", + "ArrayV3MetadataDict", ] From f57484bf42edf2fadee6c23bf47d4b8784e8949a Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 14:01:48 +0200 Subject: [PATCH 09/14] Sort pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 94d0679353..aacb6d7864 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -283,8 +283,8 @@ extend-select = [ "PGH", # pygrep-hooks "PT", # flake8-pytest-style "PYI", # flake8-pyi - "RSE", # flake8-raise "RET", # flake8-return + "RSE", # flake8-raise "RUF", "TCH", # flake8-type-checking "TRY", # tryceratops From ae4e5737fe4185c34bcc91bbd3e3c881e92966aa Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 14:18:00 +0200 Subject: [PATCH 10/14] Apply ruff/flake8-simplify rule SIM102 SIM102 Use a single `if` statement instead of nested `if` statements --- src/zarr/api/asynchronous.py | 5 ++--- src/zarr/core/indexing.py | 11 ++++++----- src/zarr/core/strings.py | 7 +++---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/zarr/api/asynchronous.py b/src/zarr/api/asynchronous.py index 434e9fdc2c..40f9b8d5f4 100644 --- a/src/zarr/api/asynchronous.py +++ b/src/zarr/api/asynchronous.py @@ -878,9 +878,8 @@ async def create( warnings.warn("meta_array is not yet implemented", RuntimeWarning, stacklevel=2) mode = kwargs.pop("mode", None) - if mode is None: - if not isinstance(store, Store | StorePath): - mode = "a" + if mode is None and not isinstance(store, Store | StorePath): + mode = "a" store_path = await make_store_path(store, path=path, mode=mode, storage_options=storage_options) diff --git a/src/zarr/core/indexing.py b/src/zarr/core/indexing.py index eda2444302..723dadfb48 100644 --- a/src/zarr/core/indexing.py +++ b/src/zarr/core/indexing.py @@ -241,12 +241,13 @@ def is_pure_fancy_indexing(selection: Any, ndim: int) -> bool: # is mask selection return True - if ndim == 1: - if is_integer_list(selection) or is_integer_array(selection) or is_bool_list(selection): - return True + if ndim == 1 and ( + is_integer_list(selection) or is_integer_array(selection) or is_bool_list(selection) + ): + return True - # if not, we go through the normal path below, because a 1-tuple - # of integers is also allowed. + # if not, we go through the normal path below, because a 1-tuple + # of integers is also allowed. no_slicing = ( isinstance(selection, tuple) and len(selection) == ndim diff --git a/src/zarr/core/strings.py b/src/zarr/core/strings.py index 9ec391c04a..ffca0c3b0c 100644 --- a/src/zarr/core/strings.py +++ b/src/zarr/core/strings.py @@ -61,10 +61,9 @@ def cast_to_string_dtype( return cast_array(data) # out = data.astype(STRING_DTYPE, copy=False) # return cast(np.ndarray[Any, np.dtypes.StringDType | np.dtypes.ObjectDType], out) - if _NUMPY_SUPPORTS_VLEN_STRING: - if np.issubdtype(data.dtype, _STRING_DTYPE): - # already a valid string variable length string dtype - return cast_array(data) + if _NUMPY_SUPPORTS_VLEN_STRING and np.issubdtype(data.dtype, _STRING_DTYPE): + # already a valid string variable length string dtype + return cast_array(data) if np.issubdtype(data.dtype, np.object_): # object arrays require more careful handling if _NUMPY_SUPPORTS_VLEN_STRING: From 8fc5bde9557d7807e46944cd4afaa0fff0b04764 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 14:20:28 +0200 Subject: [PATCH 11/14] Apply ruff/flake8-simplify rule SIM114 SIM114 Combine `if` branches using logical `or` operator --- src/zarr/core/metadata/v3.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/zarr/core/metadata/v3.py b/src/zarr/core/metadata/v3.py index 7a38e9fd70..6ea9ed69f1 100644 --- a/src/zarr/core/metadata/v3.py +++ b/src/zarr/core/metadata/v3.py @@ -481,9 +481,9 @@ def parse_fill_value( except (ValueError, OverflowError, TypeError) as e: raise ValueError(f"fill value {fill_value!r} is not valid for dtype {data_type}") from e # Check if the value is still representable by the dtype - if fill_value == "NaN" and np.isnan(casted_value): - pass - elif fill_value in ["Infinity", "-Infinity"] and not np.isfinite(casted_value): + if (fill_value == "NaN" and np.isnan(casted_value)) or ( + fill_value in ["Infinity", "-Infinity"] and not np.isfinite(casted_value) + ): pass elif np_dtype.kind == "f": # float comparison is not exact, especially when dtype Date: Sun, 20 Oct 2024 14:22:14 +0200 Subject: [PATCH 12/14] Apply ruff/flake8-simplify rule SIM118 SIM118 Use `key in dict` instead of `key in dict.keys()` --- src/zarr/core/group.py | 2 +- tests/test_api.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zarr/core/group.py b/src/zarr/core/group.py index 86cf191ca2..1054ba980b 100644 --- a/src/zarr/core/group.py +++ b/src/zarr/core/group.py @@ -1225,7 +1225,7 @@ def _members_consolidated( # we kind of just want the top-level keys. if consolidated_metadata is not None: - for key in consolidated_metadata.metadata.keys(): + for key in consolidated_metadata.metadata: obj = self._getitem_consolidated( self.store_path, key, prefix=self.name ) # Metadata -> Group/Array diff --git a/tests/test_api.py b/tests/test_api.py index 6d9eb0e888..7e6ef4ce9b 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -154,7 +154,7 @@ def test_save(store: Store, n_args: int, n_kwargs: int) -> None: assert isinstance(group, Group) for array in group.array_values(): assert_array_equal(array[:], data) - for k in kwargs.keys(): + for k in kwargs: assert k in group assert group.nmembers() == n_args + n_kwargs From a5384aa8f5eb637be65735b5a7e3954dc83eb23d Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 14:22:50 +0200 Subject: [PATCH 13/14] Enforce ruff/flake8-simplify rules (SIM) --- pyproject.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index aacb6d7864..aae16cd597 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -286,6 +286,7 @@ extend-select = [ "RET", # flake8-return "RSE", # flake8-raise "RUF", + "SIM", # flake8-simplify "TCH", # flake8-type-checking "TRY", # tryceratops "UP", # pyupgrade @@ -302,6 +303,7 @@ ignore = [ "RET505", "RET506", "RUF005", + "SIM108", "TRY003", "UP027", # deprecated "UP038", # https://github.com/astral-sh/ruff/issues/7871 @@ -323,7 +325,7 @@ ignore = [ ] [tool.ruff.lint.extend-per-file-ignores] -"tests/**" = ["ANN001", "ANN201"] +"tests/**" = ["ANN001", "ANN201", "RUF029", "SIM117", "SIM300"] [tool.mypy] python_version = "3.11" From 9d53729e27283d59d4f1f8729fb5f353066b22e8 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 20 Oct 2024 14:23:56 +0200 Subject: [PATCH 14/14] Enforce ruff/flake8-slots rules (SLOT) --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index aae16cd597..dc0e4730eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -287,6 +287,7 @@ extend-select = [ "RSE", # flake8-raise "RUF", "SIM", # flake8-simplify + "SLOT", # flake8-slots "TCH", # flake8-type-checking "TRY", # tryceratops "UP", # pyupgrade