Skip to content

Commit 4ea3937

Browse files
Enforce ruff/flake8-comprehensions rules (C4) (#9724)
* Apply ruff/flake8-comprehensions rule C409 C409 Unnecessary `tuple` literal passed to `tuple()` (remove the outer call to `tuple()`) C409 Unnecessary list comprehension passed to `tuple()` (rewrite as a generator) * Apply ruff/flake8-comprehensions rule C414 C414 Unnecessary `tuple` call within `sorted()` * Apply ruff/flake8-comprehensions rule C416 C416 Unnecessary `dict` comprehension (rewrite using `dict()`) C416 Unnecessary `list` comprehension (rewrite using `list()`) * Apply ruff/flake8-comprehensions rule C417 C417 Unnecessary `map` usage (rewrite using a generator expression) * Apply ruff/flake8-comprehensions rule C419 C419 Unnecessary list comprehension * Enforce ruff/flake8-comprehensions rules (C4)
1 parent 5515aec commit 4ea3937

20 files changed

+46
-62
lines changed

properties/test_index_manipulation.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ def rename_vars(self, newname, data):
179179
def drop_dims(self, data):
180180
dims = data.draw(
181181
st.lists(
182-
st.sampled_from(sorted(tuple(self.dataset.dims))),
182+
st.sampled_from(sorted(self.dataset.dims)),
183183
min_size=1,
184184
unique=True,
185185
)

pyproject.toml

+2
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ extend-safe-fixes = [
241241
"TID252", # absolute imports
242242
]
243243
ignore = [
244+
"C40",
244245
"E402",
245246
"E501",
246247
"E731",
@@ -254,6 +255,7 @@ ignore = [
254255
]
255256
extend-select = [
256257
"B", # flake8-bugbear
258+
"C4", # flake8-comprehensions
257259
"F", # Pyflakes
258260
"E", # Pycodestyle
259261
"W",

xarray/backends/zarr.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ def __init__(self, zarr_array):
194194
if (
195195
not _zarr_v3()
196196
and self._array.filters is not None
197-
and any([filt.codec_id == "vlen-utf8" for filt in self._array.filters])
197+
and any(filt.codec_id == "vlen-utf8" for filt in self._array.filters)
198198
):
199199
dtype = coding.strings.create_vlen_dtype(str)
200200
else:
@@ -649,7 +649,7 @@ def open_store(
649649
use_zarr_fill_value_as_mask=use_zarr_fill_value_as_mask,
650650
zarr_format=zarr_format,
651651
)
652-
group_paths = [node for node in _iter_zarr_groups(zarr_group, parent=group)]
652+
group_paths = list(_iter_zarr_groups(zarr_group, parent=group))
653653
return {
654654
group: cls(
655655
zarr_group.get(group),

xarray/core/computation.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2252,7 +2252,7 @@ def unify_chunks(*objects: Dataset | DataArray) -> tuple[Dataset | DataArray, ..
22522252
if not unify_chunks_args:
22532253
return objects
22542254

2255-
chunkmanager = get_chunked_array_type(*[arg for arg in unify_chunks_args])
2255+
chunkmanager = get_chunked_array_type(*list(unify_chunks_args))
22562256
_, chunked_data = chunkmanager.unify_chunks(*unify_chunks_args)
22572257
chunked_data_iter = iter(chunked_data)
22582258
out: list[Dataset | DataArray] = []

xarray/core/dataset.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ def _get_func_args(func, param_names):
370370
else:
371371
params = list(func_args)[1:]
372372
if any(
373-
[(p.kind in [p.VAR_POSITIONAL, p.VAR_KEYWORD]) for p in func_args.values()]
373+
(p.kind in [p.VAR_POSITIONAL, p.VAR_KEYWORD]) for p in func_args.values()
374374
):
375375
raise ValueError(
376376
"`param_names` must be provided because `func` takes variable length arguments."
@@ -1586,7 +1586,7 @@ def __getitem__(
15861586
message = f"No variable named {key!r}. Variables on the dataset include {shorten_list_repr(list(self.variables.keys()), max_items=10)}"
15871587
# If someone attempts `ds['foo' , 'bar']` instead of `ds[['foo', 'bar']]`
15881588
if isinstance(key, tuple):
1589-
message += f"\nHint: use a list to select multiple variables, for example `ds[{[d for d in key]}]`"
1589+
message += f"\nHint: use a list to select multiple variables, for example `ds[{list(key)}]`"
15901590
raise KeyError(message) from e
15911591

15921592
if utils.iterable_of_hashable(key):
@@ -1686,7 +1686,7 @@ def _setitem_check(self, key, value):
16861686
f"Variables {missing_vars} in new values"
16871687
f" not available in original dataset:\n{self}"
16881688
)
1689-
elif not any([isinstance(value, t) for t in [DataArray, Number, str]]):
1689+
elif not any(isinstance(value, t) for t in [DataArray, Number, str]):
16901690
raise TypeError(
16911691
"Dataset assignment only accepts DataArrays, Datasets, and scalars."
16921692
)
@@ -4078,7 +4078,7 @@ def interp(
40784078
)
40794079
indexers.update({d: self.variables[d] for d in sdims})
40804080

4081-
obj = self if assume_sorted else self.sortby([k for k in coords])
4081+
obj = self if assume_sorted else self.sortby(list(coords))
40824082

40834083
def maybe_variable(obj, k):
40844084
# workaround to get variable for dimension without coordinate.

xarray/core/datatree_mapping.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,7 @@ def _check_single_set_return_values(path_to_node: str, obj: Any) -> int | None:
170170
def _check_all_return_values(returned_objects) -> int | None:
171171
"""Walk through all values returned by mapping func over subtrees, raising on any invalid or inconsistent types."""
172172

173-
result_data_objects = [
174-
(path_to_node, r) for path_to_node, r in returned_objects.items()
175-
]
173+
result_data_objects = list(returned_objects.items())
176174

177175
first_path, result = result_data_objects[0]
178176
return_values = _check_single_set_return_values(first_path, result)

xarray/core/indexes.py

+9-12
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ def _check_dim_compat(variables: Mapping[Any, Variable], all_dims: str = "equal"
880880
either share the same (single) dimension or each have a different dimension.
881881
882882
"""
883-
if any([var.ndim != 1 for var in variables.values()]):
883+
if any(var.ndim != 1 for var in variables.values()):
884884
raise ValueError("PandasMultiIndex only accepts 1-dimensional variables")
885885

886886
dims = {var.dims for var in variables.values()}
@@ -1208,7 +1208,7 @@ def sel(self, labels, method=None, tolerance=None) -> IndexSelResult:
12081208
indexer: int | slice | np.ndarray | Variable | DataArray
12091209

12101210
# label(s) given for multi-index level(s)
1211-
if all([lbl in self.index.names for lbl in labels]):
1211+
if all(lbl in self.index.names for lbl in labels):
12121212
label_values = {}
12131213
for k, v in labels.items():
12141214
label_array = normalize_label(v, dtype=self.level_coords_dtype[k])
@@ -1221,7 +1221,7 @@ def sel(self, labels, method=None, tolerance=None) -> IndexSelResult:
12211221
f"available along coordinate {k!r} (multi-index level)"
12221222
) from err
12231223

1224-
has_slice = any([isinstance(v, slice) for v in label_values.values()])
1224+
has_slice = any(isinstance(v, slice) for v in label_values.values())
12251225

12261226
if len(label_values) == self.index.nlevels and not has_slice:
12271227
indexer = self.index.get_loc(
@@ -1268,9 +1268,7 @@ def sel(self, labels, method=None, tolerance=None) -> IndexSelResult:
12681268
else:
12691269
levels = [self.index.names[i] for i in range(len(label))]
12701270
indexer, new_index = self.index.get_loc_level(label, level=levels)
1271-
scalar_coord_values.update(
1272-
{k: v for k, v in zip(levels, label, strict=True)}
1273-
)
1271+
scalar_coord_values.update(dict(zip(levels, label, strict=True)))
12741272

12751273
else:
12761274
label_array = normalize_label(label)
@@ -1371,10 +1369,9 @@ def rename(self, name_dict, dims_dict):
13711369
index = self.index.rename(new_names)
13721370

13731371
new_dim = dims_dict.get(self.dim, self.dim)
1374-
new_level_coords_dtype = {
1375-
k: v
1376-
for k, v in zip(new_names, self.level_coords_dtype.values(), strict=True)
1377-
}
1372+
new_level_coords_dtype = dict(
1373+
zip(new_names, self.level_coords_dtype.values(), strict=True)
1374+
)
13781375
return self._replace(
13791376
index, dim=new_dim, level_coords_dtype=new_level_coords_dtype
13801377
)
@@ -1820,7 +1817,7 @@ def _apply_indexes_fast(indexes: Indexes[Index], args: Mapping[Any, Any], func:
18201817
# multi-index arrays
18211818
indexes_fast, coords = indexes._indexes, indexes._variables
18221819

1823-
new_indexes: dict[Hashable, Index] = {k: v for k, v in indexes_fast.items()}
1820+
new_indexes: dict[Hashable, Index] = dict(indexes_fast.items())
18241821
new_index_variables: dict[Hashable, Variable] = {}
18251822
for name, index in indexes_fast.items():
18261823
coord = coords[name]
@@ -1848,7 +1845,7 @@ def _apply_indexes(
18481845
args: Mapping[Any, Any],
18491846
func: str,
18501847
) -> tuple[dict[Hashable, Index], dict[Hashable, Variable]]:
1851-
new_indexes: dict[Hashable, Index] = {k: v for k, v in indexes.items()}
1848+
new_indexes: dict[Hashable, Index] = dict(indexes.items())
18521849
new_index_variables: dict[Hashable, Variable] = {}
18531850

18541851
for index, index_vars in indexes.group_by_index():

xarray/core/rolling.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ def _counts(self, keep_attrs: bool | None) -> DataArray:
522522
counts = (
523523
self.obj.notnull(keep_attrs=keep_attrs)
524524
.rolling(
525-
{d: w for d, w in zip(self.dim, self.window, strict=True)},
525+
dict(zip(self.dim, self.window, strict=True)),
526526
center={d: self.center[i] for i, d in enumerate(self.dim)},
527527
)
528528
.construct(rolling_dim, fill_value=False, keep_attrs=keep_attrs)

xarray/core/treenode.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ def iter_lineage(self: Tree) -> tuple[Tree, ...]:
317317
DeprecationWarning,
318318
stacklevel=2,
319319
)
320-
return tuple((self, *self.parents))
320+
return (self, *self.parents)
321321

322322
@property
323323
def lineage(self: Tree) -> tuple[Tree, ...]:
@@ -349,7 +349,7 @@ def ancestors(self: Tree) -> tuple[Tree, ...]:
349349
DeprecationWarning,
350350
stacklevel=2,
351351
)
352-
return tuple((*reversed(self.parents), self))
352+
return (*reversed(self.parents), self)
353353

354354
@property
355355
def root(self: Tree) -> Tree:
@@ -380,7 +380,7 @@ def leaves(self: Tree) -> tuple[Tree, ...]:
380380
381381
Leaf nodes are defined as nodes which have no children.
382382
"""
383-
return tuple([node for node in self.subtree if node.is_leaf])
383+
return tuple(node for node in self.subtree if node.is_leaf)
384384

385385
@property
386386
def siblings(self: Tree) -> dict[str, Tree]:

xarray/core/utils.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -1069,11 +1069,9 @@ def contains_only_chunked_or_numpy(obj) -> bool:
10691069
obj = obj._to_temp_dataset()
10701070

10711071
return all(
1072-
[
1073-
isinstance(var._data, ExplicitlyIndexed | np.ndarray)
1074-
or is_chunked_array(var._data)
1075-
for var in obj._variables.values()
1076-
]
1072+
isinstance(var._data, ExplicitlyIndexed | np.ndarray)
1073+
or is_chunked_array(var._data)
1074+
for var in obj._variables.values()
10771075
)
10781076

10791077

xarray/core/variable.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,7 @@ def _unstack_once(
15471547
else:
15481548
sizes = itertools.product(*[range(s) for s in reordered.shape[:-1]])
15491549
tuple_indexes = itertools.product(sizes, codes)
1550-
indexes = map(lambda x: list(itertools.chain(*x)), tuple_indexes) # type: ignore[assignment]
1550+
indexes = (list(itertools.chain(*x)) for x in tuple_indexes) # type: ignore[assignment]
15511551

15521552
data = COO(
15531553
coords=np.array(list(indexes)).T,

xarray/plot/utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ def _assert_valid_xy(
438438
valid_xy = (set(darray.dims) | set(darray.coords)) - multiindex_dims
439439

440440
if (xy is not None) and (xy not in valid_xy):
441-
valid_xy_str = "', '".join(sorted(tuple(str(v) for v in valid_xy)))
441+
valid_xy_str = "', '".join(sorted(str(v) for v in valid_xy))
442442
raise ValueError(
443443
f"{name} must be one of None, '{valid_xy_str}'. Received '{xy}' instead."
444444
)
@@ -1219,7 +1219,7 @@ def _adjust_legend_subtitles(legend):
12191219

12201220
def _infer_meta_data(ds, x, y, hue, hue_style, add_guide, funcname):
12211221
dvars = set(ds.variables.keys())
1222-
error_msg = f" must be one of ({', '.join(sorted(tuple(str(v) for v in dvars)))})"
1222+
error_msg = f" must be one of ({', '.join(sorted(str(v) for v in dvars))})"
12231223

12241224
if x not in dvars:
12251225
raise ValueError(f"Expected 'x' {error_msg}. Received {x} instead.")

xarray/tests/test_coding_times.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -738,15 +738,15 @@ def test_encode_time_bounds() -> None:
738738

739739
# if time_bounds attrs are same as time attrs, it doesn't matter
740740
ds.time_bounds.encoding = {"calendar": "noleap", "units": "days since 2000-01-01"}
741-
encoded, _ = cf_encoder({k: v for k, v in ds.variables.items()}, ds.attrs)
741+
encoded, _ = cf_encoder(dict(ds.variables.items()), ds.attrs)
742742
assert_equal(encoded["time_bounds"], expected["time_bounds"])
743743
assert "calendar" not in encoded["time_bounds"].attrs
744744
assert "units" not in encoded["time_bounds"].attrs
745745

746746
# for CF-noncompliant case of time_bounds attrs being different from
747747
# time attrs; preserve them for faithful roundtrip
748748
ds.time_bounds.encoding = {"calendar": "noleap", "units": "days since 1849-01-01"}
749-
encoded, _ = cf_encoder({k: v for k, v in ds.variables.items()}, ds.attrs)
749+
encoded, _ = cf_encoder(dict(ds.variables.items()), ds.attrs)
750750
with pytest.raises(AssertionError):
751751
assert_equal(encoded["time_bounds"], expected["time_bounds"])
752752
assert "calendar" not in encoded["time_bounds"].attrs

xarray/tests/test_dask.py

+3-12
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,7 @@ def test_chunk(self):
104104
assert rechunked.chunks == expected
105105
self.assertLazyAndIdentical(self.eager_var, rechunked)
106106

107-
expected_chunksizes = {
108-
dim: chunks
109-
for dim, chunks in zip(self.lazy_var.dims, expected, strict=True)
110-
}
107+
expected_chunksizes = dict(zip(self.lazy_var.dims, expected, strict=True))
111108
assert rechunked.chunksizes == expected_chunksizes
112109

113110
def test_indexing(self):
@@ -355,19 +352,13 @@ def test_chunk(self) -> None:
355352
assert rechunked.chunks == expected
356353
self.assertLazyAndIdentical(self.eager_array, rechunked)
357354

358-
expected_chunksizes = {
359-
dim: chunks
360-
for dim, chunks in zip(self.lazy_array.dims, expected, strict=True)
361-
}
355+
expected_chunksizes = dict(zip(self.lazy_array.dims, expected, strict=True))
362356
assert rechunked.chunksizes == expected_chunksizes
363357

364358
# Test Dataset
365359
lazy_dataset = self.lazy_array.to_dataset()
366360
eager_dataset = self.eager_array.to_dataset()
367-
expected_chunksizes = {
368-
dim: chunks
369-
for dim, chunks in zip(lazy_dataset.dims, expected, strict=True)
370-
}
361+
expected_chunksizes = dict(zip(lazy_dataset.dims, expected, strict=True))
371362
rechunked = lazy_dataset.chunk(chunks)
372363

373364
# Dataset.chunks has a different return type to DataArray.chunks - see issue #5843

xarray/tests/test_dataarray.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ def test_indexes(self) -> None:
180180
}
181181
assert array.xindexes.keys() == expected_xindexes.keys()
182182
assert array.indexes.keys() == expected_indexes.keys()
183-
assert all([isinstance(idx, pd.Index) for idx in array.indexes.values()])
184-
assert all([isinstance(idx, Index) for idx in array.xindexes.values()])
183+
assert all(isinstance(idx, pd.Index) for idx in array.indexes.values())
184+
assert all(isinstance(idx, Index) for idx in array.xindexes.values())
185185
for k in expected_indexes:
186186
assert array.xindexes[k].equals(expected_xindexes[k])
187187
assert array.indexes[k].equals(expected_indexes[k])
@@ -6145,7 +6145,7 @@ def test_argmin_dim(
61456145
]:
61466146
if np.array([np.isnan(i) for i in inds.values()]).any():
61476147
with pytest.raises(ValueError):
6148-
ar.argmin(dim=[d for d in inds])
6148+
ar.argmin(dim=list(inds))
61496149
return
61506150

61516151
result0 = ar.argmin(dim=["x"])
@@ -6372,7 +6372,7 @@ def test_argmax_dim(
63726372
]:
63736373
if np.array([np.isnan(i) for i in inds.values()]).any():
63746374
with pytest.raises(ValueError):
6375-
ar.argmax(dim=[d for d in inds])
6375+
ar.argmax(dim=list(inds))
63766376
return
63776377

63786378
result0 = ar.argmax(dim=["x"])
@@ -6562,7 +6562,7 @@ def test_idxminmax_dask(self, op: str, ndim: int) -> None:
65626562

65636563
ar0_raw = xr.DataArray(
65646564
np.random.random_sample(size=[10] * ndim),
6565-
dims=[i for i in "abcdefghij"[: ndim - 1]] + ["x"],
6565+
dims=list("abcdefghij"[: ndim - 1]) + ["x"],
65666566
coords={"x": np.arange(10)},
65676567
attrs=self.attrs,
65686568
)

xarray/tests/test_dataset.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -720,13 +720,13 @@ def test_properties(self) -> None:
720720
assert set(ds.xindexes) == {"dim2", "dim3", "time"}
721721
assert len(ds.xindexes) == 3
722722
assert "dim2" in repr(ds.xindexes)
723-
assert all([isinstance(idx, Index) for idx in ds.xindexes.values()])
723+
assert all(isinstance(idx, Index) for idx in ds.xindexes.values())
724724

725725
# indexes
726726
assert set(ds.indexes) == {"dim2", "dim3", "time"}
727727
assert len(ds.indexes) == 3
728728
assert "dim2" in repr(ds.indexes)
729-
assert all([isinstance(idx, pd.Index) for idx in ds.indexes.values()])
729+
assert all(isinstance(idx, pd.Index) for idx in ds.indexes.values())
730730

731731
# coords
732732
assert list(ds.coords) == ["dim2", "dim3", "time", "numbers"]

xarray/tests/test_groupby.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1791,7 +1791,7 @@ def test_groupby_fastpath_for_monotonic(self, use_flox: bool) -> None:
17911791
rev = array_rev.groupby("idx", squeeze=False)
17921792

17931793
for gb in [fwd, rev]:
1794-
assert all([isinstance(elem, slice) for elem in gb.encoded.group_indices])
1794+
assert all(isinstance(elem, slice) for elem in gb.encoded.group_indices)
17951795

17961796
with xr.set_options(use_flox=use_flox):
17971797
assert_identical(fwd.sum(), array)

xarray/tests/test_indexes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ def test_group_by_index(self, unique_indexes, indexes):
667667
def test_to_pandas_indexes(self, indexes) -> None:
668668
pd_indexes = indexes.to_pandas_indexes()
669669
assert isinstance(pd_indexes, Indexes)
670-
assert all([isinstance(idx, pd.Index) for idx in pd_indexes.values()])
670+
assert all(isinstance(idx, pd.Index) for idx in pd_indexes.values())
671671
assert indexes.variables == pd_indexes.variables
672672

673673
def test_copy_indexes(self, indexes) -> None:

xarray/tests/test_strategies.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,7 @@ def fixed_array_strategy_fn(*, shape=None, dtype=None):
138138
return st.just(arr)
139139

140140
dim_names = data.draw(dimension_names(min_dims=arr.ndim, max_dims=arr.ndim))
141-
dim_sizes = {
142-
name: size for name, size in zip(dim_names, arr.shape, strict=True)
143-
}
141+
dim_sizes = dict(zip(dim_names, arr.shape, strict=True))
144142

145143
var = data.draw(
146144
variables(

xarray/util/deprecation_helpers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def inner(*args, **kwargs):
111111
zip_args = zip(
112112
kwonly_args[:n_extra_args], args[-n_extra_args:], strict=True
113113
)
114-
kwargs.update({name: arg for name, arg in zip_args})
114+
kwargs.update(zip_args)
115115

116116
return func(*args[:-n_extra_args], **kwargs)
117117

0 commit comments

Comments
 (0)