Skip to content

Commit 8c2949b

Browse files
authored
Switch to Ruff formatting (#259)
1 parent 2ea4c28 commit 8c2949b

24 files changed

+225
-273
lines changed

Diff for: .pre-commit-config.yaml

+1-8
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,7 @@ repos:
2323
hooks:
2424
- id: ruff
2525
args: [--fix]
26-
- repo: https://github.com/hhatto/autopep8
27-
rev: v2.3.1 # Must match requirements-dev.txt
28-
hooks:
29-
- id: autopep8
30-
- repo: https://github.com/asottile/add-trailing-comma
31-
rev: v3.1.0 # Must match requirements-dev.txt
32-
hooks:
33-
- id: add-trailing-comma
26+
- id: ruff-format
3427

3528
ci:
3629
autoupdate_branch: dev

Diff for: .vscode/extensions.json

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
// Keep in alphabetical order
22
{
33
"recommendations": [
4+
"charliermarsh.ruff",
45
"davidanson.vscode-markdownlint",
56
"eamodio.gitlens",
6-
"emeraldwalk.runonsave",
77
"github.vscode-github-actions",
8-
"ms-python.autopep8",
98
"ms-python.python",
109
"ms-python.vscode-pylance",
1110
"ms-vscode.powershell",
@@ -32,11 +31,11 @@
3231
// Don't recommend to autoinstall //
3332
//
3433
// Use Ruff instead
34+
"ms-python.autopep8",
35+
"ms-python.black-formatter",
3536
"ms-python.flake8",
3637
"ms-python.isort",
3738
"ms-python.pylint",
38-
// We use autopep8
39-
"ms-python.black-formatter",
4039
// This is a Git project
4140
"johnstoncode.svn-scm",
4241
// Prefer using VSCode itself as a text editor

Diff for: .vscode/settings.json

+4-10
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,6 @@
2525
// Let dedicated linter (Ruff) organize imports
2626
"source.organizeImports": "never"
2727
},
28-
"emeraldwalk.runonsave": {
29-
"commands": [
30-
{
31-
"match": "\\.pyi?",
32-
"cmd": "add-trailing-comma ${file}"
33-
},
34-
]
35-
},
3628
"files.associations": {
3729
".flake8": "properties",
3830
"*.qrc": "xml",
@@ -67,8 +59,7 @@
6759
},
6860
"yaml.format.printWidth": 100,
6961
"[python]": {
70-
// Ruff as a formatter doesn't fully satisfy our needs yet: https://github.com/astral-sh/ruff/discussions/7310
71-
"editor.defaultFormatter": "ms-python.autopep8",
62+
"editor.defaultFormatter": "charliermarsh.ruff",
7263
"editor.tabSize": 4,
7364
"editor.rulers": [
7465
72, // PEP8-17 docstrings
@@ -91,6 +82,9 @@
9182
],
9283
"python.analysis.diagnosticMode": "workspace",
9384
"ruff.importStrategy": "fromEnvironment",
85+
"ruff.enable": true,
86+
"ruff.fixAll": true,
87+
"ruff.organizeImports": true,
9488
// Use the Ruff extension instead
9589
"isort.check": false,
9690
"powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationForFirstPipeline",

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
[![SemVer](https://badgen.net/badge/_/SemVer%20compliant/grey?label)](https://semver.org/)
55
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
6-
[![autopep8](https://badgen.net/badge/code%20style/autopep8/blue)](https://github.com/hhatto/autopep8)
6+
[![Ruff format](https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json)](https://docs.astral.sh/ruff/settings/#format)
77
[![Checked with pyright](https://microsoft.github.io/pyright/img/pyright_badge.svg)](https://microsoft.github.io/pyright/)
88
[![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/)
99

Diff for: pyproject.toml

-24
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,3 @@
1-
# https://github.com/hhatto/autopep8#usage
2-
# https://github.com/hhatto/autopep8#more-advanced-usage
3-
[tool.autopep8]
4-
max_line_length = 100
5-
aggressive = 3
6-
exclude = ".venv/*,src/gen/*"
7-
ignore = [
8-
"E124", # Closing bracket may not match multi-line method invocation style (enforced by add-trailing-comma)
9-
"E70", # Allow ... on same line as def
10-
"E721", # Breaks when needing an exact type
11-
# Autofixed by Ruff
12-
# Check for the "Fix" flag https://docs.astral.sh/ruff/rules/#pycodestyle-e-w
13-
"E2", # Whitespace
14-
"E3", # Blank lines
15-
"E703", # useless-semicolon
16-
"E71", # Statement (comparisons)
17-
"E731", # lambda-assignment
18-
"W29", # Whitespace warning
19-
"W605", # invalid-escape-sequence
20-
# Autofixed by other Ruff rules
21-
"E401", # I001: unsorted-imports
22-
"W690", # UP: pyupgrade
23-
]
24-
251
# https://github.com/microsoft/pyright/blob/main/docs/configuration.md#sample-pyprojecttoml-file
262
[tool.pyright]
273
typeCheckingMode = "strict"

Diff for: ruff.toml

+7-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ target-version = "py310" # Change this to the oldest supported version by your a
1111
line-length = 100
1212
preview = true
1313

14+
[format]
15+
docstring-code-format = true
16+
1417
[lint]
1518
select = ["ALL"]
1619
# https://docs.astral.sh/ruff/rules/
@@ -62,8 +65,9 @@ ignore = [
6265
###
6366
# Conflict with formatter (you can remove this section if you don't use Ruff as a formatter)
6467
###
65-
# "COM812", # missing-trailing-comma
66-
# "ISC001", # single-line-implicit-string-concatenation
68+
"COM812", # missing-trailing-comma
69+
"ISC001", # single-line-implicit-string-concatenation
70+
"RUF028", # invalid-formatter-suppression-comment, Is meant for the formatter, but false-positives
6771

6872
###
6973
# Rules about missing special documentation. Up to you if you wanna enable these, you must also disable D406, D407
@@ -77,7 +81,7 @@ ignore = [
7781
###
7882
# Specific to this project
7983
###
80-
"D205", # Not all docstrings have a short description + desrciption
84+
"D205", # Not all docstrings have a short description + description
8185
# TODO: Consider for more complete doc
8286
"DOC201", # docstring-extraneous-returns
8387
"DOC501", # docstring-missing-exception

Diff for: scripts/lint.ps1

+2-3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ Set-Location "$PSScriptRoot/.."
33
$exitCodes = 0
44

55
Write-Host "`nRunning formatting..."
6-
autopep8 src/ --recursive --in-place
7-
add-trailing-comma $(git ls-files '**.py*')
6+
ruff format
87

98
Write-Host "`nRunning Ruff ..."
10-
ruff check . --fix
9+
ruff check --fix
1110
$exitCodes += $LastExitCode
1211
if ($LastExitCode -gt 0) {
1312
Write-Host "`Ruff failed ($LastExitCode)" -ForegroundColor Red

Diff for: scripts/requirements-dev.txt

-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
-r requirements.txt
1313
#
1414
# Linters & Formatters
15-
add-trailing-comma>=3.1.0 # Must match .pre-commit-config.yaml
16-
autopep8>=2.3.1 # Must match .pre-commit-config.yaml
1715
ruff>=0.6.1 # Pre-commit fix # Must match .pre-commit-config.yaml
1816
#
1917
# Types

Diff for: src/AutoSplit.py

+33-39
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# QT doesn't call those from Python/ctypes, meaning we can stop other programs from setting it.
1212
if sys.platform == "win32":
1313
import ctypes
14+
1415
# pyautogui._pyautogui_win.py
1516
ctypes.windll.user32.SetProcessDPIAware = ( # pyright: ignore[reportAttributeAccessIssue]
1617
lambda: None
@@ -89,6 +90,7 @@
8990

9091
if sys.platform == "win32":
9192
from win32comext.shell import shell as shell32
93+
9294
myappid = f"Toufool.AutoSplit.v{AUTOSPLIT_VERSION}"
9395
shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
9496

@@ -162,8 +164,8 @@ def _show_error_signal_slot(error_message_box: Callable[..., object]):
162164

163165
self.setupUi(self)
164166
self.setWindowTitle(
165-
f"AutoSplit v{AUTOSPLIT_VERSION}" +
166-
(" (externally controlled)" if self.is_auto_controlled else ""),
167+
f"AutoSplit v{AUTOSPLIT_VERSION}"
168+
+ (" (externally controlled)" if self.is_auto_controlled else "")
167169
)
168170

169171
# Hotkeys need to be initialized to be passed as thread arguments in hotkeys.py
@@ -210,16 +212,17 @@ def _show_error_signal_slot(error_message_box: Callable[..., object]):
210212
self.undo_split_button.clicked.connect(self.undo_split)
211213
self.next_image_button.clicked.connect(lambda: self.skip_split(navigate_image_only=True))
212214
self.previous_image_button.clicked.connect(
213-
lambda: self.undo_split(navigate_image_only=True),
215+
lambda: self.undo_split(navigate_image_only=True)
214216
)
215217
self.align_region_button.clicked.connect(lambda: align_region(self))
216218
self.select_window_button.clicked.connect(lambda: select_window(self))
217219
self.reload_start_image_button.clicked.connect(
218-
lambda: self.__reload_start_image(started_by_button=True),
220+
lambda: self.__reload_start_image(started_by_button=True)
219221
)
220222
self.action_check_for_updates_on_open.changed.connect(
221223
lambda: user_profile.set_check_for_updates_on_open(
222-
self, self.action_check_for_updates_on_open.isChecked(),
224+
self,
225+
self.action_check_for_updates_on_open.isChecked(),
223226
),
224227
)
225228

@@ -246,7 +249,7 @@ def _update_checker_widget_signal_slot(latest_version: str, check_on_open: bool)
246249

247250
# live image checkbox
248251
self.timer_live_image.timeout.connect(
249-
lambda: self.__update_live_image_details(None, called_from_timer=True),
252+
lambda: self.__update_live_image_details(None, called_from_timer=True)
250253
)
251254
self.timer_live_image.start(int(ONE_SECOND / self.settings_dict["fps_limit"]))
252255

@@ -288,7 +291,8 @@ def __browse(self):
288291

289292
def __update_live_image_details(
290293
self,
291-
capture: MatLike | None, *,
294+
capture: MatLike | None,
295+
*,
292296
called_from_timer: bool = False,
293297
):
294298
# HACK: Since this is also called in __get_capture_for_comparison,
@@ -393,15 +397,12 @@ def __compare_capture_for_auto_start(self):
393397
if below_flag and not self.split_below_threshold and similarity_diff >= 0:
394398
self.split_below_threshold = True
395399
return
396-
if (
397-
( # noqa: PLR0916 # See above TODO
398-
below_flag
399-
and self.split_below_threshold
400-
and similarity_diff < 0
401-
and is_valid_image(capture)
402-
)
403-
or (not below_flag and similarity_diff >= 0)
404-
):
400+
if ( # noqa: PLR0916 # See above TODO
401+
below_flag
402+
and self.split_below_threshold
403+
and similarity_diff < 0
404+
and is_valid_image(capture)
405+
) or (not below_flag and similarity_diff >= 0):
405406
self.timer_start_image.stop()
406407
self.split_below_threshold = False
407408

@@ -415,7 +416,7 @@ def __compare_capture_for_auto_start(self):
415416
while time_delta < start_delay:
416417
delay_time_left = start_delay - time_delta
417418
self.current_split_image.setText(
418-
f"Delayed Before Starting:\n {seconds_remaining_text(delay_time_left)}",
419+
f"Delayed Before Starting:\n {seconds_remaining_text(delay_time_left)}"
419420
)
420421
# Wait 0.1s. Doesn't need to be shorter as we only show 1 decimal
421422
QTest.qWait(100)
@@ -547,7 +548,7 @@ def skip_split(self, *, navigate_image_only: bool = False):
547548
not self.is_running
548549
or "Delayed Split" in self.current_split_image.text()
549550
or not (
550-
self.skip_split_button.isEnabled()
551+
self.skip_split_button.isEnabled() # fmt: skip
551552
or self.is_auto_controlled
552553
or navigate_image_only
553554
)
@@ -583,7 +584,7 @@ def reset(self):
583584
def start_auto_splitter(self):
584585
# If the auto splitter is already running or the button is disabled,
585586
# don't emit the signal to start it.
586-
if (
587+
if ( # fmt: skip
587588
self.is_running
588589
or (not self.start_auto_splitter_button.isEnabled() and not self.is_auto_controlled)
589590
):
@@ -622,9 +623,8 @@ def __auto_splitter(self): # noqa: C901,PLR0912,PLR0915
622623
self.split_images_and_loop_number = list(
623624
flatten(
624625
((split_image, i + 1) for i in range(split_image.loops))
625-
for split_image
626-
in self.split_images
627-
),
626+
for split_image in self.split_images
627+
)
628628
)
629629

630630
# Construct groups of splits
@@ -726,9 +726,9 @@ def __auto_splitter(self): # noqa: C901,PLR0912,PLR0915
726726
self.gui_changes_on_reset(safe_to_reload_start_image=True)
727727

728728
def __similarity_threshold_loop(
729-
self,
730-
number_of_split_images: int,
731-
dummy_splits_array: list[bool],
729+
self,
730+
number_of_split_images: int,
731+
dummy_splits_array: list[bool],
732732
):
733733
"""
734734
Wait until the similarity threshold is met.
@@ -765,7 +765,7 @@ def __similarity_threshold_loop(
765765
# If its the last non-dummy split image and last loop number,
766766
# disable the skip split button
767767
self.skip_split_button.setEnabled(
768-
dummy_splits_array[self.split_image_number :].count(False) > 1,
768+
dummy_splits_array[self.split_image_number :].count(False) > 1
769769
)
770770
self.undo_split_button.setEnabled(self.split_image_number != 0)
771771
QApplication.processEvents()
@@ -827,7 +827,7 @@ def __pause_loop(self, stop_time: float, message: str):
827827
break
828828

829829
self.current_split_image.setText(
830-
f"{message} {seconds_remaining_text(stop_time - time_delta)}",
830+
f"{message} {seconds_remaining_text(stop_time - time_delta)}"
831831
)
832832

833833
QTest.qWait(1)
@@ -903,7 +903,7 @@ def __get_capture_for_comparison(self):
903903
message += "\n(captured window may be incompatible with BitBlt)"
904904
self.live_image.setText(message)
905905
recovered = self.capture_method.recover_window(
906-
self.settings_dict["captured_window_title"],
906+
self.settings_dict["captured_window_title"]
907907
)
908908
if recovered:
909909
capture = self.capture_method.get_frame()
@@ -929,7 +929,7 @@ def __reset_if_should(self, capture: MatLike | None):
929929
should_reset = similarity >= threshold
930930
self.reset_highest_similarity = max(similarity, self.reset_highest_similarity)
931931
self.table_reset_image_highest_label.setText(
932-
decimal(self.reset_highest_similarity),
932+
decimal(self.reset_highest_similarity)
933933
)
934934
self.table_reset_image_live_label.setText(decimal(similarity))
935935

@@ -960,7 +960,7 @@ def __update_split_image(self, specific_image: AutoSplitImage | None = None):
960960

961961
# Get split image
962962
self.split_image = (
963-
specific_image
963+
specific_image # fmt: skip
964964
or self.split_images_and_loop_number[0 + self.split_image_number][0]
965965
)
966966
if self.split_image.is_ocr:
@@ -972,7 +972,7 @@ def __update_split_image(self, specific_image: AutoSplitImage | None = None):
972972

973973
self.current_image_file_label.setText(self.split_image.filename)
974974
self.table_current_image_threshold_label.setText(
975-
decimal(self.split_image.get_similarity_threshold(self)),
975+
decimal(self.split_image.get_similarity_threshold(self))
976976
)
977977

978978
# Set Image Loop number
@@ -1048,19 +1048,13 @@ def set_preview_image(qlabel: QLabel, image: MatLike | None):
10481048
image_format = QtGui.QImage.Format.Format_BGR888
10491049
capture = image
10501050

1051-
qimage = QtGui.QImage(
1052-
capture.data,
1053-
width,
1054-
height,
1055-
width * channels,
1056-
image_format,
1057-
)
1051+
qimage = QtGui.QImage(capture.data, width, height, width * channels, image_format)
10581052
qlabel.setPixmap(
10591053
QtGui.QPixmap(qimage).scaled(
10601054
qlabel.size(),
10611055
QtCore.Qt.AspectRatioMode.IgnoreAspectRatio,
10621056
QtCore.Qt.TransformationMode.SmoothTransformation,
1063-
),
1057+
)
10641058
)
10651059

10661060

0 commit comments

Comments
 (0)