Skip to content

Commit 850cf91

Browse files
chore: add ruff PERF (#649)
Signed-off-by: Henry Schreiner <[email protected]> Co-authored-by: Andrzej Novak <[email protected]>
1 parent 1a05bcc commit 850cf91

File tree

5 files changed

+31
-45
lines changed

5 files changed

+31
-45
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ markers = [
147147
extend-select = [
148148
"B", # flake8-bugbear
149149
"I", # isort
150+
"PERF", # perflint
150151
"ARG", # flake8-unused-arguments
151152
"C4", # flake8-comprehensions
152153
"EM", # flake8-errmsg

src/mplhep/_dev.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,7 @@ def _find_files_to_clean(self) -> list[Path]:
163163
for target in cleanup_targets:
164164
if "*" in target:
165165
# Handle glob patterns
166-
for item in self.project_root.glob(target):
167-
items_to_clean.append(item)
166+
items_to_clean.extend(self.project_root.glob(target))
168167
else:
169168
item = self.project_root / target
170169
if item.exists():
@@ -336,7 +335,7 @@ def cmd_precommit(self, extra_args: list[str] | None = None) -> bool:
336335
self._print_success(
337336
f"Removed {item.relative_to(self.project_root)}"
338337
)
339-
except OSError as e:
338+
except OSError as e: # noqa: PERF203
340339
self._print_error(f"Failed to remove {item}: {e}")
341340

342341
if len(items_to_clean) > 10:
@@ -477,7 +476,7 @@ def cmd_clean(self) -> bool:
477476
self._print_success(
478477
f"Removed {item.relative_to(self.project_root)}"
479478
)
480-
except OSError as e:
479+
except OSError as e: # noqa: PERF203
481480
self._print_error(f"Failed to remove {item}: {e}")
482481

483482
if len(items_to_clean) > 10:
@@ -710,10 +709,11 @@ def _get_available_baselines(self) -> list[str]:
710709
if not benchmark_dir.exists():
711710
return []
712711

713-
baselines = []
714-
for item in benchmark_dir.iterdir():
715-
if item.is_dir() and not item.name.startswith("."):
716-
baselines.append(item.name)
712+
baselines = [
713+
item.name
714+
for item in benchmark_dir.iterdir()
715+
if item.is_dir() and not item.name.startswith(".")
716+
]
717717

718718
return sorted(baselines)
719719

@@ -724,12 +724,12 @@ def _get_available_benchmark_files(self) -> list[str]:
724724
if not benchmark_dir.exists():
725725
return []
726726

727-
benchmark_files = []
728-
for subdir in benchmark_dir.iterdir():
729-
if subdir.is_dir() and not subdir.name.startswith("."):
730-
for json_file in subdir.glob("*.json"):
731-
# Use just the filename without extension for comparison
732-
benchmark_files.append(json_file.stem)
727+
benchmark_files = [
728+
json_file.stem
729+
for subdir in benchmark_dir.iterdir()
730+
if subdir.is_dir() and not subdir.name.startswith(".")
731+
for json_file in subdir.glob("*.json")
732+
]
733733

734734
return sorted(benchmark_files)
735735

@@ -838,15 +838,15 @@ def _get_choice(
838838
for i, (label, _) in enumerate(choices, 1):
839839
print(f" {i}. {label}")
840840

841-
while True:
842-
try:
841+
try:
842+
while True:
843843
response = input("Enter choice (number): ").strip()
844844
idx = int(response) - 1
845845
if 0 <= idx < len(choices):
846846
return choices[idx][1]
847847
print(f"Please enter a number between 1 and {len(choices)}")
848-
except (ValueError, KeyboardInterrupt):
849-
return None
848+
except (ValueError, KeyboardInterrupt):
849+
return None
850850

851851
def _check_tool_available(self, tool_name: str, check_cmd: list[str]) -> bool:
852852
"""Check if a tool is available."""

src/mplhep/_utils.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,9 @@ def _get_plottables(
264264
final_bins, _ = _get_plottable_protocol_bins(hists[0].axes[0])
265265

266266
if xoffsets is True:
267-
parsed_offsets = []
268267
widths = np.diff(final_bins)
269268
sub_bin_width = widths / (len(hists) + 1)
270-
for i in range(len(hists)):
271-
parsed_offsets.append(sub_bin_width * (i + 1))
269+
parsed_offsets = [sub_bin_width * (i + 1) for i in range(len(hists))]
272270
xoffsets = parsed_offsets
273271
else:
274272
xoffsets = [None] * len(hists)
@@ -1128,9 +1126,11 @@ def _overlap(ax, bboxes, get_vertices=False, exclude_texts=None):
11281126
lines_display.append(interpolated_display)
11291127

11301128
# Collect bboxes from texts (excluding specified text objects to avoid self-overlap)
1131-
for handle in ax.texts:
1132-
if isinstance(handle, Text) and handle not in exclude_texts:
1133-
bboxes_display.append(handle.get_window_extent())
1129+
bboxes_display.extend(
1130+
handle.get_window_extent()
1131+
for handle in ax.texts
1132+
if isinstance(handle, Text) and handle not in exclude_texts
1133+
)
11341134

11351135
# Concatenate all vertices in display coordinates
11361136
all_vertices_display = (
@@ -1411,8 +1411,6 @@ def _draw_text_bbox(ax):
14111411
return [], []
14121412

14131413
fig.canvas.draw()
1414-
bboxes = []
1415-
for box in textboxes:
1416-
bboxes.append(box.get_tightbbox(fig.canvas.renderer))
1414+
bboxes = [box.get_tightbbox(fig.canvas.renderer) for box in textboxes]
14171415
logger.debug(f"_draw_text_bbox: Returning {len(bboxes)} bboxes")
14181416
return bboxes, textboxes

src/mplhep/plot.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,7 @@ def histplot(
415415
def iterable_not_string(arg):
416416
return isinstance(arg, collections.abc.Iterable) and not isinstance(arg, str)
417417

418-
_chunked_kwargs: list[dict[str, Any]] = []
419-
for _ in range(len(hists)):
420-
_chunked_kwargs.append({})
418+
_chunked_kwargs: list[dict[str, Any]] = [{} for _ in hists]
421419
for kwarg, kwarg_content in kwargs.items():
422420
# Check if iterable
423421
if iterable_not_string(kwarg_content):
@@ -486,9 +484,7 @@ def iterable_not_string(arg):
486484
_labels = _labels[::-1]
487485
if "color" not in kwargs or kwargs.get("color") is None:
488486
# Inverse default color cycle
489-
_colors = []
490-
for _ in range(len(plottables)):
491-
_colors.append(ax._get_lines.get_next_color()) # type: ignore[attr-defined]
487+
_colors = [ax._get_lines.get_next_color() for _ in plottables] # type: ignore[attr-defined]
492488
_colors.reverse()
493489
for i in range(len(plottables)):
494490
_chunked_kwargs[i].update({"color": _colors[i]})

tests/test_basic.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import itertools
34
import os
45
import re
56

@@ -274,12 +275,7 @@ def test_histplot_type_flow():
274275

275276
@pytest.mark.mpl_image_compare(style="default")
276277
def test_hist2dplot_hist_all_flow_show():
277-
flow_opts = []
278-
for ufl1 in [True, False]:
279-
for ofl1 in [True, False]:
280-
for ufl2 in [True, False]:
281-
for ofl2 in [True, False]:
282-
flow_opts.append([ufl1, ofl1, ufl2, ofl2])
278+
flow_opts = [list(p) for p in itertools.product([True, False], repeat=4)]
283279

284280
np.random.seed(0)
285281
_fill = np.random.normal(2.5, 2, 10000).reshape(-1, 2).T
@@ -302,12 +298,7 @@ def test_hist2dplot_hist_all_flow_show():
302298

303299
@pytest.mark.mpl_image_compare(style="default")
304300
def test_hist2dplot_hist_all_flow_hint():
305-
flow_opts = []
306-
for ufl1 in [True, False]:
307-
for ofl1 in [True, False]:
308-
for ufl2 in [True, False]:
309-
for ofl2 in [True, False]:
310-
flow_opts.append([ufl1, ofl1, ufl2, ofl2])
301+
flow_opts = [list(p) for p in itertools.product([True, False], repeat=4)]
311302

312303
np.random.seed(0)
313304
_fill = np.random.normal(2.5, 2, 10000).reshape(-1, 2).T

0 commit comments

Comments
 (0)