Skip to content

Commit f43d978

Browse files
authored
Merge pull request #540 from onekey-sec/ruff
Use ruff instead of flake8 and isort
2 parents 2176281 + 1c20b7d commit f43d978

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+828
-637
lines changed

.github/workflows/build-nix.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jobs:
2929
- name: Setup emulation
3030
if: ${{ matrix.arch == 'aarch64-linux' }}
3131
run: |
32+
sudo apt update
3233
sudo apt install -q -y qemu-system-aarch64 qemu-efi binfmt-support qemu-user-static
3334
mkdir -p ~/.config/nix
3435
echo "system-features = aarch64-linux arm-linux" | sudo tee -a /etc/nix/nix.conf

.pre-commit-config.yaml

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,19 @@ repos:
1313
- id: check-yaml
1414
- id: check-added-large-files
1515

16+
- repo: https://github.com/charliermarsh/ruff-pre-commit
17+
rev: "v0.0.259"
18+
hooks:
19+
- id: ruff
20+
name: Check python (ruff)
21+
args: [--show-source, --fix, --exit-non-zero-on-fix]
22+
1623
- repo: https://github.com/psf/black
1724
rev: 23.1.0
1825
hooks:
1926
- id: black
2027
name: Check black
2128

22-
- repo: https://github.com/PyCQA/flake8
23-
rev: 6.0.0
24-
hooks:
25-
- id: flake8
26-
name: Check flake8
27-
28-
- repo: https://github.com/PyCQA/isort
29-
rev: 5.12.0
30-
hooks:
31-
- id: isort
32-
name: Check isort
33-
3429
- repo: https://github.com/jendrikseipp/vulture
3530
rev: v2.7
3631
hooks:
@@ -46,7 +41,7 @@ repos:
4641
- repo: https://github.com/nix-community/nixpkgs-fmt
4742
rev: v1.3.0
4843
hooks:
49-
- id: nixpkgs-fmt
44+
- id: nixpkgs-fmt
5045

5146
- repo: https://github.com/python-jsonschema/check-jsonschema
5247
rev: 0.21.0

docs/development.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,10 @@ We adhere to PEP8 and enforce proper formatting of source files using
432432
[black](https://github.com/psf/black) so you should not worry about formatting
433433
source code at all, `pre-commit` will take care of it.
434434

435+
For linting we use [ruff](https://ruff.rs). Lint errors can be shown in your
436+
editor of choice by one of the [editor
437+
plugins](https://beta.ruff.rs/docs/editor-integrations/).
438+
435439
### File Format Correctness
436440

437441
We want to strike the right balance between false positive reduction and a

poetry.lock

Lines changed: 28 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pytest = "^6.2.4"
3939
pyright = "^0.0.12"
4040
pre-commit = "^2.15.0"
4141
pytest-cov = "^3.0.0"
42+
ruff = "^0.0.259"
4243
setuptools-rust = "^1.1.2"
4344

4445
[tool.poetry.group.docs]
@@ -51,12 +52,89 @@ pillow = "^9.4.0"
5152
cairosvg = "^2.7.0"
5253
mkdocstrings-python = "^0.8.3"
5354

54-
[tool.isort]
55-
profile = "black"
56-
5755
[tool.poetry.scripts]
5856
unblob = "unblob.cli:main"
5957

58+
[tool.ruff]
59+
target-version = "py38"
60+
61+
select = [
62+
"A", # flake8-builtins
63+
"ARG", # flake8-unused-arguments
64+
"B", # flake8-bugbear
65+
"C90", # mccabe
66+
"C4", # flake8-comprehensions
67+
"COM818", # flake8-commas; trailing-comma-on-bare-tuple
68+
"D", # pydocstyle
69+
"E", # pycodestyle (errors)
70+
"F", # pyflakes
71+
"FBT", # flake8-boolean-trap
72+
"G", # flake8-logging-format
73+
"I", # isort
74+
"ISC", # flake8-implicit-str-concats
75+
"N", # pep8-naming
76+
"PIE", # flake8-pie
77+
"PL", # pylint
78+
"PT", # flake8-pytest-style
79+
"PTH", # flake8-use-pathlib
80+
"RET", # flake8-return
81+
"RUF", # ruff's own lints
82+
"RSE", # flake8-raise
83+
"S", # flake8-bandit
84+
"SIM", # flake8-simplify
85+
"SLF", # flake8-self
86+
"T10", # flake8-debugger
87+
"T20", # flake8-print
88+
"TCH", # flake8-type-checking
89+
"TRY", # tryceratops
90+
"UP", # pyupgrade
91+
"W", # pycodestyle (warnings)
92+
]
93+
94+
ignore = [
95+
"B027", # empty-method-without-abstract-decorator: It is okay to have empty methods in abstract classes
96+
"D1", # undocumented-*: We are not documenting every public symbol
97+
"D203", # one-blank-line-before-class: D211 (no-blank-line-before-class) is used instead
98+
"D213", # multi-line-summary-second-line: D212 (multi-line-summary-first-line) is used instead
99+
"E501", # line-too-long: Let black handle line length violations
100+
"N818", # error-suffix-on-exception-name: Exception names can be meaningful without smurfs
101+
"PLC0414", # useless-import-alias: Enable explicitly re-exporting public symbols
102+
"PLR09", # too-many-{arguments,branches,...}: We do not want to impose hard limits
103+
"S101", # assert: Enable usage of asserts
104+
"TRY003", # raise-vanilla-args: We are adding contextual information in exception messages
105+
"TRY400", # error-instead-of-exception: It is okay to log without backtrace in except blocks
106+
]
107+
108+
# Do not remove unused imports automatically in __init__.py files
109+
ignore-init-module-imports = true
110+
111+
[tool.ruff.per-file-ignores]
112+
"build.py" = [
113+
"T201" # print
114+
]
115+
"tests/*" = [
116+
"FBT001", # boolean-positional-arg-in-function-definition: allowed in `pytest.param()`
117+
"FBT003", # boolean-positional-value-in-function-call: allowed test parameters
118+
]
119+
120+
[tool.ruff.flake8-comprehensions]
121+
allow-dict-calls-with-keyword-arguments = true # code like `dict(a=1, b=2)` is allowed
122+
123+
[tool.ruff.mccabe]
124+
max-complexity = 8
125+
126+
[tool.ruff.pylint]
127+
allow-magic-value-types = [
128+
"bytes",
129+
"int", # bunch of ad-hoc bitmask values
130+
"str",
131+
]
132+
133+
[tool.ruff.flake8-pytest-style]
134+
fixture-parentheses = false
135+
mark-parentheses = false
136+
parametrize-names-type = "csv"
137+
60138
[tool.pytest.ini_options]
61139
addopts = "--cov=unblob --cov=tests --cov-branch --cov-fail-under=90"
62140
norecursedirs = """

setup.cfg

Lines changed: 0 additions & 6 deletions
This file was deleted.

tests/extractors/test_command.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
def test_command_templating():
1313
command = Command("{outdir}", "{inpath},{outdir}")
14-
cmdline = command._make_extract_command(
14+
cmdline = command._make_extract_command( # noqa: SLF001
1515
Path("inputdir") / "input.file", Path("output")
1616
)
1717

@@ -20,16 +20,16 @@ def test_command_templating():
2020

2121
@pytest.mark.parametrize(
2222
"template",
23-
(
23+
[
2424
"{no_such_placeholder}",
2525
"{malformed",
26-
),
26+
],
2727
)
2828
def test_command_templating_with_invalid_substitution(template):
2929
command = Command(template)
3030

3131
with pytest.raises(InvalidCommandTemplate, match=template):
32-
command._make_extract_command(Path("input"), Path("output"))
32+
command._make_extract_command(Path("input"), Path("output")) # noqa: SLF001
3333

3434

3535
def test_command_execution(tmpdir: Path):
@@ -45,30 +45,28 @@ def test_command_execution_failure(tmpdir: Path):
4545
outdir = PosixPath(tmpdir)
4646
command = Command("sh", "-c", ">&1 echo -n stdout; >&2 echo -n stderr; false")
4747

48-
try:
48+
with pytest.raises(ExtractError) as excinfo:
4949
command.extract(Path("input"), outdir)
50-
pytest.fail("ExtractError not raised")
51-
except ExtractError as e:
52-
assert list(e.reports) == [
53-
ExtractCommandFailedReport(
54-
command=mock.ANY,
55-
stdout=b"stdout",
56-
stderr=b"stderr",
57-
exit_code=1,
58-
)
59-
]
50+
51+
assert list(excinfo.value.reports) == [
52+
ExtractCommandFailedReport(
53+
command=mock.ANY,
54+
stdout=b"stdout",
55+
stderr=b"stderr",
56+
exit_code=1,
57+
)
58+
]
6059

6160

6261
def test_command_not_found(tmpdir: Path):
6362
outdir = PosixPath(tmpdir)
6463
command = Command("this-command-should-not-exist-in-any-system")
6564

66-
try:
65+
with pytest.raises(ExtractError) as excinfo:
6766
command.extract(Path("input"), outdir)
68-
pytest.fail("ExtractError not raised")
69-
except ExtractError as e:
70-
assert list(e.reports) == [
71-
ExtractorDependencyNotFoundReport(
72-
dependencies=["this-command-should-not-exist-in-any-system"],
73-
)
74-
]
67+
68+
assert list(excinfo.value.reports) == [
69+
ExtractorDependencyNotFoundReport(
70+
dependencies=["this-command-should-not-exist-in-any-system"],
71+
)
72+
]

tests/handlers/archive/test_arj.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ def test_valid_calculation():
5050

5151
@pytest.mark.parametrize(
5252
"header_size",
53-
(
53+
[
5454
pytest.param(0, id="size-small"),
5555
pytest.param(2700, id="size-large"),
5656
pytest.param(31, id="size-smaller-then-first_hdr_size"),
57-
),
57+
],
5858
)
5959
def test_invalid_block_size(header_size):
6060
contents = bytearray(copy.copy(ARJ_CONTENTS))
@@ -65,7 +65,7 @@ def test_invalid_block_size(header_size):
6565

6666
handler = ARJHandler()
6767
with pytest.raises(InvalidARJSize):
68-
handler._read_arj_main_header(f, 0)
68+
handler._read_arj_main_header(f, 0) # noqa: SLF001
6969

7070

7171
def test_invalid_checksum():
@@ -76,4 +76,4 @@ def test_invalid_checksum():
7676

7777
handler = ARJHandler()
7878
with pytest.raises(ARJChecksumError):
79-
handler._read_arj_main_header(f, 0)
79+
handler._read_arj_main_header(f, 0) # noqa: SLF001

tests/handlers/archive/test_tar.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136

137137
@pytest.mark.parametrize(
138138
"contents, expected_length, message",
139-
(
139+
[
140140
pytest.param(
141141
GNU_TAR_CONTENTS + PADDING_TO_DEFAULT_BLOCKING_FACTOR,
142142
len(GNU_TAR_CONTENTS + PADDING_TO_DEFAULT_BLOCKING_FACTOR),
@@ -173,7 +173,7 @@
173173
"File end shouldn't include partial zero filled blocks",
174174
id="posix-padded-after-end",
175175
),
176-
),
176+
],
177177
)
178178
def test_offset(contents: bytes, expected_length: int, message: str):
179179
f = File.from_bytes(contents)
@@ -184,7 +184,7 @@ def test_offset(contents: bytes, expected_length: int, message: str):
184184

185185
@pytest.mark.parametrize(
186186
"contents",
187-
(
187+
[
188188
pytest.param(
189189
GNU_TAR_CONTENTS,
190190
id="gnu-tar",
@@ -193,11 +193,11 @@ def test_offset(contents: bytes, expected_length: int, message: str):
193193
POSIX_TAR_CONTENTS,
194194
id="posix-tar",
195195
),
196-
),
196+
],
197197
)
198198
@pytest.mark.parametrize(
199199
"start_complete, message",
200-
(
200+
[
201201
pytest.param(
202202
False,
203203
"File is truncated and no content can be recovered",
@@ -208,7 +208,7 @@ def test_offset(contents: bytes, expected_length: int, message: str):
208208
"File is truncated but valid parts should be recovered",
209209
id="truncated",
210210
),
211-
),
211+
],
212212
)
213213
def test_truncated_files(contents: bytes, start_complete: bool, message: str):
214214
truncated = contents[:0x180]
@@ -298,10 +298,10 @@ def test_different_blocking_factor():
298298

299299
@pytest.mark.parametrize(
300300
"prefix",
301-
(
301+
[
302302
pytest.param(b"", id="zero-prefix"),
303303
pytest.param(b"some prefix ", id="nonzero-prefix"),
304-
),
304+
],
305305
)
306306
def test_calculate_chunk(prefix):
307307
tar_file = File.from_bytes(prefix + GNU_TAR_CONTENTS)

0 commit comments

Comments
 (0)