Skip to content

Commit 1c5432b

Browse files
authored
Add BLE, C4, ISC, and PERF lints (#3579)
1 parent bf20d70 commit 1c5432b

File tree

13 files changed

+34
-37
lines changed

13 files changed

+34
-37
lines changed

docs/extensions/git_ref.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ def get() -> str | None:
2828
try:
2929
git_ref = git("name-rev", "--name-only", "--no-undefined", "HEAD")
3030
git_ref = re.sub(r"^(remotes/[^/]+|tags)/", "", git_ref)
31-
except Exception:
31+
except Exception: # noqa: BLE001
3232
pass
3333

3434
# (if no name found or relative ref, use commit hash instead)
3535
if not git_ref or re.search(r"[\^~]", git_ref):
3636
try:
3737
git_ref = git("rev-parse", "HEAD")
38-
except Exception:
38+
except Exception: # noqa: BLE001
3939
git_ref = "main"
4040
return git_ref
4141

pyproject.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,13 +227,17 @@ docstring-code-format = true
227227
[tool.ruff.lint]
228228
select = [
229229
"B", # Likely bugs and design issues
230+
"BLE", # Blind exception raised
231+
"C4", # Comprehensions
230232
"D", # Documentation style
231233
"E", # Error detected by Pycodestyle
232234
"EM", # Traceback-friendly error messages
233235
"F", # Errors detected by Pyflakes
234236
"FBT", # No positional boolean parameters
235237
"I", # Import sorting
236238
"ICN", # Follow import conventions
239+
"ISC", # Implicit string concatenation
240+
"PERF", # Performance
237241
"PIE", # Syntax simplifications
238242
"PL", # Pylint
239243
"PT", # Pytest style
@@ -248,6 +252,8 @@ select = [
248252
]
249253
external = [ "PLR0917" ] # preview lint that we use
250254
ignore = [
255+
# dict() syntax is preferrable when creating dicts for kwargs
256+
"C408",
251257
# E266 too many leading '#' for block comment -> Scanpy allows them for comments into sections
252258
"E262",
253259
# module level import not at top of file -> required to circumvent circular imports for Scanpys API

src/scanpy/_settings.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,14 @@
2626

2727
AnnDataFileFormat = Literal["h5ad", "zarr"]
2828

29-
_VERBOSITY_TO_LOGLEVEL = {
29+
_VERBOSITY_TO_LOGLEVEL: dict[int | str, str] = {
3030
"error": "ERROR",
3131
"warning": "WARNING",
3232
"info": "INFO",
3333
"hint": "HINT",
3434
"debug": "DEBUG",
3535
}
36-
# Python 3.7+ ensures iteration order
37-
for v, level in enumerate(list(_VERBOSITY_TO_LOGLEVEL.values())):
38-
_VERBOSITY_TO_LOGLEVEL[v] = level
36+
_VERBOSITY_TO_LOGLEVEL.update(dict(enumerate(list(_VERBOSITY_TO_LOGLEVEL.values()))))
3937

4038

4139
class Verbosity(IntEnum):

src/scanpy/plotting/_tools/paga.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -525,11 +525,11 @@ def is_flat(x):
525525
labels = [labels for _ in range(len(colors))]
526526

527527
if title is None and len(colors) > 1:
528-
title = [c for c in colors]
528+
title = list(colors)
529529
elif isinstance(title, str):
530-
title = [title for c in colors]
530+
title = [title] * len(colors)
531531
elif title is None:
532-
title = [None for c in colors]
532+
title = [None] * len(colors)
533533

534534
if colorbar is None:
535535
var_names = adata.var_names if adata.raw is None else adata.raw.var_names

src/scanpy/plotting/_tools/scatterplots.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,4 @@ def _broadcast_args(*args):
13871387
if not (set(lens) == {1, longest} or set(lens) == {longest}):
13881388
msg = f"Could not broadcast together arguments with shapes: {lens}."
13891389
raise ValueError(msg)
1390-
return list(
1391-
[[arg[0] for _ in range(longest)] if len(arg) == 1 else arg for arg in args]
1392-
)
1390+
return [[arg[0] for _ in range(longest)] if len(arg) == 1 else arg for arg in args]

src/scanpy/preprocessing/_combat.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,8 @@ def combat( # noqa: PLR0915
218218
gamma_hat = (
219219
la.inv(batch_design.T @ batch_design) @ batch_design.T @ s_data.T
220220
).values
221-
delta_hat = []
222-
223221
# first estimate for the multiplicative batch effect
224-
for batch_idxs in batch_info:
225-
delta_hat.append(s_data.iloc[:, batch_idxs].var(axis=1))
222+
delta_hat = [s_data.iloc[:, batch_idxs].var(axis=1) for batch_idxs in batch_info]
226223

227224
# empirically fix the prior hyperparameters
228225
gamma_bar = gamma_hat.mean(axis=1)

src/scanpy/preprocessing/_scrublet/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ def call_doublets(
436436
logg.info(
437437
f"Automatically set threshold at doublet score = {threshold:.2f}"
438438
)
439-
except Exception:
439+
except Exception: # noqa: BLE001
440440
self.predicted_doublets_ = None
441441
if verbose:
442442
logg.warning(

src/scanpy/readwrite.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,8 +1039,7 @@ def get_used_files():
10391039
for proc in loop_over_scanpy_processes:
10401040
try:
10411041
flist = proc.open_files()
1042-
for nt in flist:
1043-
filenames.append(nt.path)
1042+
filenames.extend(nt.path for nt in flist)
10441043
# This catches a race condition where a process ends
10451044
# before we can examine its files
10461045
except psutil.NoSuchProcess:

src/scanpy/tools/_dpt.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -903,19 +903,17 @@ def _detect_branching( # noqa: PLR0915
903903

904904
def _detect_branching_single_haghverdi16(self, Dseg, tips):
905905
"""Detect branching on given segment."""
906-
# compute branchings using different starting points the first index of
907-
# tips is the starting point for the other two, the order does not
908-
# matter
909-
ssegs = []
910906
# permutations of tip cells
911907
ps = [
912908
[0, 1, 2], # start by computing distances from the first tip
913909
[1, 2, 0], # -"- second tip
914910
[2, 0, 1], # -"- third tip
915911
]
916-
for p in ps:
917-
ssegs.append(self.__detect_branching_haghverdi16(Dseg, tips[p]))
918-
return ssegs
912+
913+
# compute branchings using different starting points the first index of
914+
# tips is the starting point for the other two, the order does not
915+
# matter
916+
return [self.__detect_branching_haghverdi16(Dseg, tips[p]) for p in ps]
919917

920918
def _detect_branching_single_wolf17_tri(self, Dseg, tips):
921919
# all pairwise distances

src/scanpy/tools/_sim.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -595,21 +595,22 @@ def read_model(self):
595595
# version of the discrete model)
596596
self.build_boolCoeff()
597597

598-
def set_coupl(self, Coupl=None) -> None: # noqa: PLR0912
598+
def set_coupl(self, Coupl=None) -> None:
599599
"""Construct the coupling matrix (and adjacancy matrix) from predefined models or via sampling."""
600600
self.varNames = {str(i): i for i in range(self.dim)}
601601
if self.model not in self.availModels and Coupl is None:
602602
self.read_model()
603603
elif "var" in self.model.name:
604604
# vector auto regressive process
605605
self.Coupl = Coupl
606-
self.boolRules = {s: "" for s in self.varNames}
606+
self.boolRules = dict.fromkeys(self.varNames, "")
607607
names = list(self.varNames.keys())
608608
for gp in range(self.dim):
609-
pas = []
610-
for g in range(self.dim):
611-
if np.abs(self.Coupl[gp, g] > 1e-10):
612-
pas.append(names[g])
609+
pas = [
610+
names[g]
611+
for g in range(self.dim)
612+
if np.abs(self.Coupl[gp, g] > 1e-10)
613+
]
613614
self.boolRules[names[gp]] = "".join(
614615
pas[:1] + [" or " + pa for pa in pas[1:]]
615616
)
@@ -761,7 +762,7 @@ def branch_init_model1(self, tmax=100):
761762
settings.m(
762763
0,
763764
"... either no fixed point in [0,1]^2! \n"
764-
+ " or fixed point is too close to bounds",
765+
" or fixed point is too close to bounds",
765766
)
766767
return None
767768
XbackUp = self.sim_model_backwards(
@@ -1246,7 +1247,7 @@ def sample_static_data(model, dir, verbosity=0):
12461247
default="",
12471248
help=(
12481249
"specify directory to store data, "
1249-
+ ' must start with "sim/MODEL_...", see possible values for MODEL below '
1250+
' must start with "sim/MODEL_...", see possible values for MODEL below '
12501251
),
12511252
)
12521253
aa("--show", action="store_true", help="show plots")

0 commit comments

Comments
 (0)