Skip to content

Commit 273b6c0

Browse files
authored
Make ruff more strict (#383)
2 parents 38d9cea + a4626b2 commit 273b6c0

35 files changed

+267
-369
lines changed

python/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ Our CI server runs three checks in the `selfie-lib` directory.
1313

1414
- `poetry run pytest` - run tests
1515
- `poetry run pyright` - type checking
16-
- `poetry run ruff check` - code formatting
17-
- `poetry run ruff format` to fix any problems that `check` found
16+
- `poetry run ruff format --check && poetry run ruff check` - code lint & formatting
17+
- `poetry run ruff format && poetry run ruff --fix` to fix
1818

1919
The same setup is used for `pytest-selfie` and `example-pytest-selfie`.
2020

Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import random
22

3-
from selfie_lib.Selfie import cache_selfie_string
3+
from selfie_lib import cache_selfie
44

55

66
def test_cache_selfie():
7-
cache_selfie_string(lambda: str(random.random())).to_be("0.6623096709843852")
7+
cache_selfie(lambda: str(random.random())).to_be("0.6623096709843852")
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from selfie_lib.Selfie import expect_selfie
1+
from selfie_lib import expect_selfie
22

33

4-
def test_comment_removal(): # selfieonce
4+
def test_comment_removal():
55
expect_selfie("no op").to_be("no op")

python/example-pytest-selfie/tests/simple_inline_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from selfie_lib.Selfie import expect_selfie
1+
from selfie_lib import expect_selfie
22

33
# def test_read_pass():
44
# expect_selfie("A").to_be("A")
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
from selfie_lib.Selfie import expect_selfie
1+
from selfie_lib import expect_selfie
22

33

44
def test_write():
55
expect_selfie("A").to_match_disk()
66

77

88
def test_read():
9-
expect_selfie("B").to_match_disk_TODO()
9+
expect_selfie("B").to_match_disk()
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
╔═ test_read ═╗
2+
B
3+
╔═ test_write ═╗
4+
A
5+
╔═ [end of file] ═╗

python/pytest-selfie/pyproject.toml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,17 @@ build-backend = "poetry.core.masonry.api"
2424
[tool.poetry.plugins.pytest11]
2525
pytest_selfie = "pytest_selfie.plugin"
2626

27-
[tool.ruff]
28-
lint.extend-select = ["I"]
27+
[tool.ruff.lint]
28+
select = ["ALL"]
29+
ignore = [ "S", "FA", "PYI", "EM", "PLR", "FBT", "COM", "RET", "PTH", "PLW", "PLC",
30+
"TRY", # TODO: exception standards
31+
"ANN", # TODO: require type annotations
32+
"D", # TODO: docstring warnings
33+
"N", # TODO: naming conventions
34+
"E501", # line too long
35+
"C901", # function to complex
36+
"PLC0414", # import alias does not rename original package
37+
"W291", # trailing whitespace, we need it for testing snapshots
38+
"PGH003", # specific rule codes when ignoring type issues
39+
"ISC001"
40+
]

python/pytest-selfie/pytest_selfie/SelfieSettingsAPI.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ def root_folder(self) -> Path:
2828
return self.root_dir
2929

3030
def calc_mode(self) -> Mode:
31-
override = os.getenv("selfie") or os.getenv("SELFIE")
31+
override = os.getenv("selfie") or os.getenv("SELFIE") # noqa: SIM112
3232
if override:
3333
# Convert the mode to lowercase and match it with the Mode enum
3434
try:
3535
return Mode[override.lower()]
3636
except KeyError:
37-
raise ValueError(f"No such mode: {override}")
37+
raise ValueError(f"No such mode: {override}") from None
3838

39-
ci = os.getenv("ci") or os.getenv("CI")
39+
ci = os.getenv("ci") or os.getenv("CI") # noqa: SIM112
4040
if ci and ci.lower() == "true":
4141
return Mode.readonly
4242
else:

python/pytest-selfie/pytest_selfie/plugin.py

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def walk_callback(walk: Iterator[TypedPath]) -> bool:
8383
# look for a file that has a newline somewhere in it
8484
if "\n" in txt:
8585
return "\r" not in txt
86-
except Exception:
86+
except UnicodeDecodeError: # noqa: PERF203
8787
# might be a binary file that throws an encoding exception
8888
pass
8989
return True # if we didn't find any files, assume unix
@@ -105,14 +105,14 @@ def pytest_collection_modifyitems(
105105

106106

107107
@pytest.hookimpl
108-
def pytest_sessionfinish(session: pytest.Session, exitstatus):
108+
def pytest_sessionfinish(session: pytest.Session, exitstatus): # noqa: ARG001
109109
system: PytestSnapshotSystem = session.selfie_system # type: ignore
110110
system.finished_all_tests()
111111
_clearSelfieSystem(system)
112112

113113

114114
@pytest.hookimpl(hookwrapper=True)
115-
def pytest_runtest_protocol(item: pytest.Item, nextitem: Optional[pytest.Item]):
115+
def pytest_runtest_protocol(item: pytest.Item, nextitem: Optional[pytest.Item]): # noqa: ARG001
116116
(file, _, testname) = item.reportinfo()
117117
testfile = TypedPath.of_file(os.path.abspath(file))
118118

@@ -148,7 +148,7 @@ class PytestSnapshotSystem(SnapshotSystem):
148148
def __init__(self, settings: SelfieSettingsAPI):
149149
self.__fs = FSImplementation()
150150
self.__mode = settings.calc_mode()
151-
self._layout = PytestSnapshotFileLayout(self.__fs, settings)
151+
self.layout_pytest = PytestSnapshotFileLayout(self.__fs, settings)
152152
self.__comment_tracker = CommentTracker()
153153
self.__inline_write_tracker = InlineWriteTracker()
154154
self.__toBeFileWriteTracker = ToBeFileWriteTracker()
@@ -163,7 +163,7 @@ def __init__(self, settings: SelfieSettingsAPI):
163163
AtomicReference(ArraySet.empty())
164164
)
165165

166-
def planning_to_run(self, testfile: TypedPath, testname: str):
166+
def planning_to_run(self, testfile: TypedPath, testname: str): # noqa: ARG002
167167
progress = self.__progress_per_file[testfile]
168168
progress.finishes_expected += 1
169169

@@ -228,7 +228,7 @@ def fs(self) -> FS:
228228

229229
@property
230230
def layout(self) -> SnapshotFileLayout:
231-
return self._layout
231+
return self.layout_pytest
232232

233233
def disk_thread_local(self) -> DiskStorage:
234234
if (
@@ -250,15 +250,15 @@ def write_to_be_file(
250250
self, path: TypedPath, data: "ByteString", call: CallStack
251251
) -> None:
252252
# Directly write to disk using ToBeFileWriteTracker
253-
self.__toBeFileWriteTracker.writeToDisk(path, data, call, self._layout)
253+
self.__toBeFileWriteTracker.writeToDisk(path, data, call, self.layout_pytest)
254254

255255

256256
class DiskStoragePytest(DiskStorage):
257257
def __init__(self, progress: "SnapshotFileProgress", testname: str):
258258
self.__progress = progress
259259
self._testname = testname
260260

261-
def read_disk(self, sub: str, call: "CallStack") -> Optional["Snapshot"]:
261+
def read_disk(self, sub: str, call: "CallStack") -> Optional["Snapshot"]: # noqa: ARG002
262262
return self.__progress.read(self._testname, self._suffix(sub))
263263

264264
def write_disk(self, actual: "Snapshot", sub: str, call: "CallStack"):
@@ -349,34 +349,32 @@ def __all_tests_finished(self):
349349
if tests == SnapshotFileProgress.TERMINATED:
350350
raise ValueError(f"Snapshot for {self.test_file} already terminated!")
351351
if self.file is not None:
352-
# TODO: figure out GC
353352
stale_snapshot_indices = []
354-
# stale_snapshot_indices = WithinTestGC.find_stale_snapshots_within(
355-
# self.file.snapshots,
356-
# tests,
357-
# find_test_methods_that_didnt_run(self.test_file, tests),
358-
# )
353+
# TODO: figure out GC # noqa: TD002, FIX002, TD003
354+
# stale_snapshot_indices = WithinTestGC.find_stale_snapshots_within(self.file.snapshots, tests, find_test_methods_that_didnt_run(self.test_file, tests)) # noqa: ERA001
359355
if stale_snapshot_indices or self.file.was_set_at_test_time:
360356
self.file.remove_all_indices(stale_snapshot_indices)
361-
snapshot_path = self.system._layout.snapshotfile_for_testfile(
357+
snapshot_path = self.system.layout_pytest.snapshotfile_for_testfile(
362358
self.test_file
363359
)
364360
if not self.file.snapshots:
365361
delete_file_and_parent_dir_if_empty(snapshot_path)
366362
else:
367363
self.system.mark_path_as_written(
368-
self.system._layout.snapshotfile_for_testfile(self.test_file)
364+
self.system.layout_pytest.snapshotfile_for_testfile(
365+
self.test_file
366+
)
369367
)
370368
os.makedirs(
371369
os.path.dirname(snapshot_path.absolute_path), exist_ok=True
372370
)
373371
with open(
374372
snapshot_path.absolute_path, "w", encoding="utf-8"
375373
) as writer:
376-
list = []
377-
self.file.serialize(list)
378-
for e in list:
379-
writer.write(e)
374+
filecontent = []
375+
self.file.serialize(filecontent)
376+
for line in filecontent:
377+
writer.write(line)
380378
else:
381379
# we never read or wrote to the file
382380
every_test_in_class_ran = not any(
@@ -388,7 +386,7 @@ def __all_tests_finished(self):
388386
and all(it.succeeded_and_used_no_snapshots() for it in tests.values())
389387
)
390388
if is_stale:
391-
snapshot_file = self.system._layout.snapshotfile_for_testfile(
389+
snapshot_file = self.system.layout_pytest.snapshotfile_for_testfile(
392390
self.test_file
393391
)
394392
delete_file_and_parent_dir_if_empty(snapshot_file)
@@ -425,7 +423,7 @@ def read(self, test: str, suffix: str) -> Optional[Snapshot]:
425423

426424
def read_file(self) -> SnapshotFile:
427425
if self.file is None:
428-
snapshot_path = self.system._layout.snapshotfile_for_testfile(
426+
snapshot_path = self.system.layout_pytest.snapshotfile_for_testfile(
429427
self.test_file
430428
)
431429
if os.path.exists(snapshot_path.absolute_path) and os.path.isfile(
@@ -436,7 +434,7 @@ def read_file(self) -> SnapshotFile:
436434
self.file = SnapshotFile.parse(SnapshotValueReader.of_binary(content))
437435
else:
438436
self.file = SnapshotFile.create_empty_with_unix_newlines(
439-
self.system._layout.unix_newlines
437+
self.system.layout_pytest.unix_newlines
440438
)
441439
return self.file
442440

@@ -451,7 +449,8 @@ def delete_file_and_parent_dir_if_empty(snapshot_file: TypedPath):
451449

452450

453451
def find_test_methods_that_didnt_run(
454-
testfile: TypedPath, tests: ArrayMap[str, WithinTestGC]
452+
testfile: TypedPath, # noqa: ARG001
453+
tests: ArrayMap[str, WithinTestGC], # noqa: ARG001
455454
) -> ArrayMap[str, WithinTestGC]:
456455
# Implementation of finding test methods that didn't run
457456
# You can replace this with your own logic based on the class_name and tests dictionary
@@ -471,6 +470,6 @@ def pytest_addoption(parser):
471470
parser.addini("HELLO", "Dummy pytest.ini setting")
472471

473472

474-
@pytest.fixture
473+
@pytest.fixture()
475474
def bar(request):
476475
return request.config.option.dest_foo

0 commit comments

Comments
 (0)