From 94fd87f8742c60affdd8d3ac23d49ccc55a0adb0 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 12 May 2024 22:35:16 +0200 Subject: [PATCH 1/4] Enable ruff/flake8-implicit-str-concat rules (ISC) --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 1aafb64a2b..c39879b363 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -169,6 +169,7 @@ extend-exclude = [ extend-select = [ "B", # flake8-bugbear "I", # isort + "ISC", "UP", # pyupgrade "RUF", ] From 37f31cad31d2a53981f3130f4fdadc613f604fad Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 12 May 2024 22:37:06 +0200 Subject: [PATCH 2/4] Apply ruff/flake8-implicit-str-concat rule ISC001 ISC001 Implicitly concatenated string literals on one line --- src/zarr/v2/convenience.py | 6 +++--- src/zarr/v2/indexing.py | 8 ++++---- src/zarr/v2/util.py | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/zarr/v2/convenience.py b/src/zarr/v2/convenience.py index 6355a11af9..aa322bfb98 100644 --- a/src/zarr/v2/convenience.py +++ b/src/zarr/v2/convenience.py @@ -470,7 +470,7 @@ def __init__(self, log): self.log_file = log else: raise TypeError( - "log must be a callable function, file path or " "file-like object, found %r" % log + "log must be a callable function, file path or file-like object, found %r" % log ) def __enter__(self): @@ -898,7 +898,7 @@ def _copy(log, source, dest, name, root, shallow, without_attrs, if_exists, dry_ if exists: if if_exists == "raise": raise CopyError( - "an object {!r} already exists in destination " "{!r}".format(name, dest.name) + "an object {!r} already exists in destination {!r}".format(name, dest.name) ) elif if_exists == "skip": do_copy = False @@ -990,7 +990,7 @@ def _copy(log, source, dest, name, root, shallow, without_attrs, if_exists, dry_ if exists_array: if if_exists == "raise": raise CopyError( - "an array {!r} already exists in destination " "{!r}".format(name, dest.name) + "an array {!r} already exists in destination {!r}".format(name, dest.name) ) elif if_exists == "skip": do_copy = False diff --git a/src/zarr/v2/indexing.py b/src/zarr/v2/indexing.py index 1c11409d05..460c02a80b 100644 --- a/src/zarr/v2/indexing.py +++ b/src/zarr/v2/indexing.py @@ -364,13 +364,13 @@ def __init__(self, dim_sel, dim_len, dim_chunk_len): # check number of dimensions if not is_bool_array(dim_sel, 1): raise IndexError( - "Boolean arrays in an orthogonal selection must " "be 1-dimensional only" + "Boolean arrays in an orthogonal selection must be 1-dimensional only" ) # check shape if dim_sel.shape[0] != dim_len: raise IndexError( - "Boolean array has the wrong length for dimension; " "expected {}, got {}".format( + "Boolean array has the wrong length for dimension; expected {}, got {}".format( dim_len, dim_sel.shape[0] ) ) @@ -465,7 +465,7 @@ def __init__( dim_sel = np.asanyarray(dim_sel) if not is_integer_array(dim_sel, 1): raise IndexError( - "integer arrays in an orthogonal selection must be " "1-dimensional only" + "integer arrays in an orthogonal selection must be 1-dimensional only" ) # handle wraparound @@ -920,7 +920,7 @@ def check_fields(fields, dtype): # check type if not isinstance(fields, (str, list, tuple)): raise IndexError( - "'fields' argument must be a string or list of strings; found " "{!r}".format( + "'fields' argument must be a string or list of strings; found {!r}".format( type(fields) ) ) diff --git a/src/zarr/v2/util.py b/src/zarr/v2/util.py index 8751b39cdc..48d7d30d88 100644 --- a/src/zarr/v2/util.py +++ b/src/zarr/v2/util.py @@ -307,7 +307,7 @@ def normalize_fill_value(fill_value, dtype: np.dtype[Any]): if not isinstance(fill_value, str): raise ValueError( - "fill_value {!r} is not valid for dtype {}; must be a " "unicode string".format( + "fill_value {!r} is not valid for dtype {}; must be a unicode string".format( fill_value, dtype ) ) @@ -323,7 +323,7 @@ def normalize_fill_value(fill_value, dtype: np.dtype[Any]): except Exception as e: # re-raise with our own error message to be helpful raise ValueError( - "fill_value {!r} is not valid for dtype {}; nested " "exception: {}".format( + "fill_value {!r} is not valid for dtype {}; nested exception: {}".format( fill_value, dtype, e ) ) From 517a943ff082992c10f2ee2057615a4ccb22b91a Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 12 May 2024 22:37:58 +0200 Subject: [PATCH 3/4] A round of formatting after linting --- src/zarr/v2/indexing.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/zarr/v2/indexing.py b/src/zarr/v2/indexing.py index 460c02a80b..d85f844fc8 100644 --- a/src/zarr/v2/indexing.py +++ b/src/zarr/v2/indexing.py @@ -363,9 +363,7 @@ class BoolArrayDimIndexer: def __init__(self, dim_sel, dim_len, dim_chunk_len): # check number of dimensions if not is_bool_array(dim_sel, 1): - raise IndexError( - "Boolean arrays in an orthogonal selection must be 1-dimensional only" - ) + raise IndexError("Boolean arrays in an orthogonal selection must be 1-dimensional only") # check shape if dim_sel.shape[0] != dim_len: @@ -464,9 +462,7 @@ def __init__( # ensure 1d array dim_sel = np.asanyarray(dim_sel) if not is_integer_array(dim_sel, 1): - raise IndexError( - "integer arrays in an orthogonal selection must be 1-dimensional only" - ) + raise IndexError("integer arrays in an orthogonal selection must be 1-dimensional only") # handle wraparound if wraparound: @@ -920,9 +916,7 @@ def check_fields(fields, dtype): # check type if not isinstance(fields, (str, list, tuple)): raise IndexError( - "'fields' argument must be a string or list of strings; found {!r}".format( - type(fields) - ) + "'fields' argument must be a string or list of strings; found {!r}".format(type(fields)) ) if fields: if dtype.names is None: From 5d0073eabe41d2c2f44a4fe422a319e763e0a555 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 12 May 2024 22:47:54 +0200 Subject: [PATCH 4/4] Aplly ruff/flake8-implicit-str-concat rule ISC003 ISC003 Explicitly concatenated string should be implicitly concatenated --- src/zarr/codecs/crc32c_.py | 3 +-- src/zarr/codecs/pipeline.py | 15 +++++---------- src/zarr/codecs/sharding.py | 6 ++---- src/zarr/codecs/transpose.py | 6 ++---- src/zarr/store/remote.py | 7 +++---- 5 files changed, 13 insertions(+), 24 deletions(-) diff --git a/src/zarr/codecs/crc32c_.py b/src/zarr/codecs/crc32c_.py index 0b9c8c9a96..d4fd80064f 100644 --- a/src/zarr/codecs/crc32c_.py +++ b/src/zarr/codecs/crc32c_.py @@ -42,8 +42,7 @@ async def decode_single( stored_checksum = bytes(crc32_bytes) if computed_checksum != stored_checksum: raise ValueError( - "Stored and computed checksum do not match. " - + f"Stored: {stored_checksum!r}. Computed: {computed_checksum!r}." + f"Stored and computed checksum do not match. Stored: {stored_checksum!r}. Computed: {computed_checksum!r}." ) return Buffer.from_array_like(inner_bytes) diff --git a/src/zarr/codecs/pipeline.py b/src/zarr/codecs/pipeline.py index 57b4fa4668..56e73a4b29 100644 --- a/src/zarr/codecs/pipeline.py +++ b/src/zarr/codecs/pipeline.py @@ -104,31 +104,26 @@ def codecs_from_list( if prev_codec is not None: if isinstance(codec, ArrayBytesCodec) and isinstance(prev_codec, ArrayBytesCodec): raise ValueError( - f"ArrayBytesCodec '{type(codec)}' cannot follow after " - + f"ArrayBytesCodec '{type(prev_codec)}' because exactly " - + "1 ArrayBytesCodec is allowed." + f"ArrayBytesCodec '{type(codec)}' cannot follow after ArrayBytesCodec '{type(prev_codec)}' because exactly 1 ArrayBytesCodec is allowed." ) if isinstance(codec, ArrayBytesCodec) and isinstance(prev_codec, BytesBytesCodec): raise ValueError( - f"ArrayBytesCodec '{type(codec)}' cannot follow after " - + f"BytesBytesCodec '{type(prev_codec)}'." + f"ArrayBytesCodec '{type(codec)}' cannot follow after BytesBytesCodec '{type(prev_codec)}'." ) if isinstance(codec, ArrayArrayCodec) and isinstance(prev_codec, ArrayBytesCodec): raise ValueError( - f"ArrayArrayCodec '{type(codec)}' cannot follow after " - + f"ArrayBytesCodec '{type(prev_codec)}'." + f"ArrayArrayCodec '{type(codec)}' cannot follow after ArrayBytesCodec '{type(prev_codec)}'." ) if isinstance(codec, ArrayArrayCodec) and isinstance(prev_codec, BytesBytesCodec): raise ValueError( - f"ArrayArrayCodec '{type(codec)}' cannot follow after " - + f"BytesBytesCodec '{type(prev_codec)}'." + f"ArrayArrayCodec '{type(codec)}' cannot follow after BytesBytesCodec '{type(prev_codec)}'." ) prev_codec = codec if any(isinstance(codec, ShardingCodec) for codec in codecs) and len(codecs) > 1: warn( "Combining a `sharding_indexed` codec disables partial reads and " - + "writes, which may lead to inefficient performance.", + "writes, which may lead to inefficient performance.", stacklevel=3, ) diff --git a/src/zarr/codecs/sharding.py b/src/zarr/codecs/sharding.py index a6c5bac6a7..819f946089 100644 --- a/src/zarr/codecs/sharding.py +++ b/src/zarr/codecs/sharding.py @@ -360,8 +360,7 @@ def evolve(self, array_spec: ArraySpec) -> Self: def validate(self, array_metadata: ArrayMetadata) -> None: if len(self.chunk_shape) != array_metadata.ndim: raise ValueError( - "The shard's `chunk_shape` and array's `shape` need to have the " - + "same number of dimensions." + "The shard's `chunk_shape` and array's `shape` need to have the same number of dimensions." ) if not isinstance(array_metadata.chunk_grid, RegularChunkGrid): raise ValueError("Sharding is only compatible with regular chunk grids.") @@ -374,8 +373,7 @@ def validate(self, array_metadata: ArrayMetadata) -> None: ) ): raise ValueError( - "The array's `chunk_shape` needs to be divisible by the " - + "shard's inner `chunk_shape`." + "The array's `chunk_shape` needs to be divisible by the shard's inner `chunk_shape`." ) async def decode_single( diff --git a/src/zarr/codecs/transpose.py b/src/zarr/codecs/transpose.py index 774393464c..b20a36fe98 100644 --- a/src/zarr/codecs/transpose.py +++ b/src/zarr/codecs/transpose.py @@ -45,8 +45,7 @@ def to_dict(self) -> dict[str, JSON]: def evolve(self, array_spec: ArraySpec) -> Self: if len(self.order) != array_spec.ndim: raise ValueError( - "The `order` tuple needs have as many entries as " - + f"there are dimensions in the array. Got {self.order}." + f"The `order` tuple needs have as many entries as there are dimensions in the array. Got {self.order}." ) if len(self.order) != len(set(self.order)): raise ValueError( @@ -54,8 +53,7 @@ def evolve(self, array_spec: ArraySpec) -> Self: ) if not all(0 <= x < array_spec.ndim for x in self.order): raise ValueError( - "All entries in the `order` tuple must be between 0 and " - + f"the number of dimensions in the array. Got {self.order}." + f"All entries in the `order` tuple must be between 0 and the number of dimensions in the array. Got {self.order}." ) order = tuple(self.order) diff --git a/src/zarr/store/remote.py b/src/zarr/store/remote.py index 2986133fbd..8058c61035 100644 --- a/src/zarr/store/remote.py +++ b/src/zarr/store/remote.py @@ -25,10 +25,9 @@ def __init__(self, url: UPath | str, **storage_options: dict[str, Any]): if isinstance(url, str): self.root = UPath(url, **storage_options) else: - assert len(storage_options) == 0, ( - "If constructed with a UPath object, no additional " - + "storage_options are allowed." - ) + assert ( + len(storage_options) == 0 + ), "If constructed with a UPath object, no additional storage_options are allowed." self.root = url.rstrip("/") # test instantiate file system fs, _ = fsspec.core.url_to_fs(str(self.root), asynchronous=True, **self.root._kwargs)