Compare commits
471 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
615887a7fe | ||
|
|
07808a58f2 | ||
|
|
fe568c08d2 | ||
|
|
7741d43ae5 | ||
|
|
1b3e54231c | ||
|
|
3a8e98341b | ||
|
|
8593739f88 | ||
|
|
242dd3dae1 | ||
|
|
875f61cb62 | ||
|
|
3ec1ea8ac2 | ||
|
|
1e45b13958 | ||
|
|
9e61956711 | ||
|
|
5eae3fbbfb | ||
|
|
41e38ffa98 | ||
|
|
27903cdb11 | ||
|
|
3b1709ba1e | ||
|
|
33394e4a69 | ||
|
|
7b9bdc494a | ||
|
|
b06ca25421 | ||
|
|
c42f8b93d2 | ||
|
|
f59a22b6e5 | ||
|
|
b5edc6dfc9 | ||
|
|
626169e2ef | ||
|
|
e9f359ac5e | ||
|
|
318c2c80e2 | ||
|
|
92aa3a8178 | ||
|
|
22a4ab51f9 | ||
|
|
f70a49ed8b | ||
|
|
f039bf36a2 | ||
|
|
169dd72328 | ||
|
|
fd39ec4bdd | ||
|
|
7c0f17279c | ||
|
|
81d0884974 | ||
|
|
a45753f462 | ||
|
|
b08326162b | ||
|
|
3a65af4dae | ||
|
|
474aa0b196 | ||
|
|
4892167217 | ||
|
|
a5494b8541 | ||
|
|
9ac9a1c69e | ||
|
|
f06dff8af8 | ||
|
|
fe7443ce2f | ||
|
|
4bdb2dd362 | ||
|
|
53a4743631 | ||
|
|
4ffcd8366a | ||
|
|
dfb772c6f1 | ||
|
|
c21eb06922 | ||
|
|
16a350c731 | ||
|
|
fa04861724 | ||
|
|
404504ab41 | ||
|
|
621e4353e3 | ||
|
|
0c4926ff7b | ||
|
|
61653b9f27 | ||
|
|
8dd3959e74 | ||
|
|
50f9db21da | ||
|
|
1dd3cbd047 | ||
|
|
bd935cbd49 | ||
|
|
babd0a05ac | ||
|
|
87fab4a2e1 | ||
|
|
2e21920adf | ||
|
|
dedf4cbdeb | ||
|
|
92179e6369 | ||
|
|
33d2457909 | ||
|
|
373a77e8c2 | ||
|
|
73df267635 | ||
|
|
f5e5caaa25 | ||
|
|
d9ed0aae69 | ||
|
|
e0df62b841 | ||
|
|
bbc87b7177 | ||
|
|
667130a4c3 | ||
|
|
72febf98b7 | ||
|
|
e99e1fae2b | ||
|
|
eff84442bc | ||
|
|
aa51ecedc5 | ||
|
|
9ae9cc9d2f | ||
|
|
de1106b95a | ||
|
|
e636c5fcf0 | ||
|
|
12dfd57211 | ||
|
|
d188d242a0 | ||
|
|
57796c5e59 | ||
|
|
2545869797 | ||
|
|
58353a4bf4 | ||
|
|
a36139ae21 | ||
|
|
7e904111b1 | ||
|
|
344daebb1b | ||
|
|
432059de35 | ||
|
|
c50d6da8b4 | ||
|
|
1b738f88c4 | ||
|
|
1eff3dffa5 | ||
|
|
8c7317eb8d | ||
|
|
106a93eab0 | ||
|
|
78c2b0ac47 | ||
|
|
d5700d7c69 | ||
|
|
3a7bdb39c9 | ||
|
|
a82fe4a139 | ||
|
|
62ff3b62e3 | ||
|
|
1e5db58b7b | ||
|
|
a6e998d639 | ||
|
|
a8c1915e2e | ||
|
|
c515a1b31a | ||
|
|
aa97a092bd | ||
|
|
685c242761 | ||
|
|
b540407b74 | ||
|
|
3a5fbd6d74 | ||
|
|
227679b5cb | ||
|
|
c2750a59ab | ||
|
|
2a4d6ab3b2 | ||
|
|
7a80bcec58 | ||
|
|
297749a3a8 | ||
|
|
8955e32b5c | ||
|
|
cd192eddf9 | ||
|
|
675227db5c | ||
|
|
a65c6806a6 | ||
|
|
6c576872d4 | ||
|
|
9858df1ac9 | ||
|
|
7fb7268e8a | ||
|
|
0f78f27713 | ||
|
|
12a6fc7041 | ||
|
|
d2988043af | ||
|
|
cc8b13d3a7 | ||
|
|
1e081cf9a6 | ||
|
|
841bcf1cdd | ||
|
|
7062d1db16 | ||
|
|
8b561313aa | ||
|
|
cfa2924664 | ||
|
|
a3aeec6377 | ||
|
|
b983d5eb3f | ||
|
|
bb3bb24b59 | ||
|
|
872829ca72 | ||
|
|
2383228709 | ||
|
|
952307d39d | ||
|
|
024caca233 | ||
|
|
08ec11a31e | ||
|
|
bd05a8a74d | ||
|
|
229f1c34cb | ||
|
|
a7f3532395 | ||
|
|
3349ceb969 | ||
|
|
da1f83fe32 | ||
|
|
0a9d259f9c | ||
|
|
130e733023 | ||
|
|
ff2c0dd491 | ||
|
|
dfe1cad928 | ||
|
|
ffad0bcdaa | ||
|
|
bc869d4f52 | ||
|
|
a3de791f0a | ||
|
|
d9dfec30eb | ||
|
|
3f04def3a5 | ||
|
|
98177754de | ||
|
|
8d5374762c | ||
|
|
bad6bdda1f | ||
|
|
a5d302fcbf | ||
|
|
bced58ce40 | ||
|
|
10e252e2fb | ||
|
|
4dead7541f | ||
|
|
fea1af5a63 | ||
|
|
c0ad875339 | ||
|
|
8437399496 | ||
|
|
074f5634a5 | ||
|
|
694d41897a | ||
|
|
e1ebd9130d | ||
|
|
fc8ca6edd2 | ||
|
|
709dba2e71 | ||
|
|
d1c48016eb | ||
|
|
348a38d261 | ||
|
|
22e6778e17 | ||
|
|
30c71dc59a | ||
|
|
5d8591fec4 | ||
|
|
673aa6e90f | ||
|
|
51fe9f7d4b | ||
|
|
d7767b2bad | ||
|
|
40d3b40c14 | ||
|
|
376ef929b1 | ||
|
|
8828e12283 | ||
|
|
f13633cc9f | ||
|
|
889c05c87e | ||
|
|
bbbc44336e | ||
|
|
d216b2aaa8 | ||
|
|
367cc43c42 | ||
|
|
b5b26d5a3e | ||
|
|
dedf8aa5cc | ||
|
|
eb42ce9319 | ||
|
|
cdbe2ee496 | ||
|
|
d1288dc2b1 | ||
|
|
3bcffb5bdd | ||
|
|
98209be8aa | ||
|
|
a03fa93c3a | ||
|
|
4de3882088 | ||
|
|
3a98b68dc0 | ||
|
|
7e291e542d | ||
|
|
6f649d6579 | ||
|
|
508bc605a5 | ||
|
|
ffdf6e35e6 | ||
|
|
886992c6c2 | ||
|
|
187104e396 | ||
|
|
3ed539d50e | ||
|
|
4a70a4c323 | ||
|
|
310f13c7db | ||
|
|
2168404fc2 | ||
|
|
a032b66c2e | ||
|
|
af5f7dbd83 | ||
|
|
8066607ea3 | ||
|
|
0ed9fccce9 | ||
|
|
074a343a63 | ||
|
|
c7e09b54b0 | ||
|
|
67d1f74587 | ||
|
|
1c79dff3bd | ||
|
|
f5f09b489b | ||
|
|
061495a9eb | ||
|
|
470e1c1754 | ||
|
|
16be691712 | ||
|
|
270015865b | ||
|
|
ccfa9d5b20 | ||
|
|
2261e194a0 | ||
|
|
cd6413ca09 | ||
|
|
c65585e14a | ||
|
|
d2a6ed7be6 | ||
|
|
16e2dae0c2 | ||
|
|
e8ba9c9e21 | ||
|
|
d285f5c90a | ||
|
|
386ca7c9a1 | ||
|
|
40c5abf16e | ||
|
|
7e7aec7d74 | ||
|
|
4b5538f74e | ||
|
|
36d134fd41 | ||
|
|
0b7d6b9097 | ||
|
|
994e2e0903 | ||
|
|
bc79f540e4 | ||
|
|
3a78b59314 | ||
|
|
5f83851329 | ||
|
|
484ce7b8fc | ||
|
|
1c75071136 | ||
|
|
51bca19c1d | ||
|
|
a8a312e862 | ||
|
|
33c31cda27 | ||
|
|
cd9fbeb560 | ||
|
|
84e96cdcd9 | ||
|
|
248590224a | ||
|
|
bbc55cdb04 | ||
|
|
2792439eac | ||
|
|
0694aee1b6 | ||
|
|
a17b5c134a | ||
|
|
42f61535b5 | ||
|
|
1c01b3c934 | ||
|
|
39b9a1637f | ||
|
|
2c692e3acf | ||
|
|
24add5f56c | ||
|
|
0b7736ad79 | ||
|
|
eef85067c8 | ||
|
|
da98fab4ae | ||
|
|
0f37a98d91 | ||
|
|
f38624824d | ||
|
|
159422071e | ||
|
|
6eaacf96be | ||
|
|
eb15371453 | ||
|
|
198b301baf | ||
|
|
c8c575dd43 | ||
|
|
6e54cd8233 | ||
|
|
a688a237d7 | ||
|
|
bda2a0007a | ||
|
|
32d165b7ad | ||
|
|
ac79bf4ee9 | ||
|
|
376eab3a53 | ||
|
|
08be7bd285 | ||
|
|
f5241451d8 | ||
|
|
c9fe0708cb | ||
|
|
09f8c487ea | ||
|
|
1e7233a8eb | ||
|
|
f967f344fc | ||
|
|
095f005bf4 | ||
|
|
0f04aa2a5f | ||
|
|
ad7ba77fff | ||
|
|
77d43795f8 | ||
|
|
4357f2be0f | ||
|
|
e5c1f95545 | ||
|
|
227ff62a4e | ||
|
|
d8e4902516 | ||
|
|
e66739884f | ||
|
|
5fd827545b | ||
|
|
c1ddcb8a60 | ||
|
|
48a317d5f6 | ||
|
|
74e18b6cff | ||
|
|
21d02cd51f | ||
|
|
049e77b939 | ||
|
|
b9bfb81e36 | ||
|
|
2d4fae45d9 | ||
|
|
726adb7efc | ||
|
|
dbdfdeb0e1 | ||
|
|
1c41789c2a | ||
|
|
2f9de335db | ||
|
|
ba61bb6a6c | ||
|
|
17ab71ff75 | ||
|
|
4ad4e3e091 | ||
|
|
6ced5122e4 | ||
|
|
7d55b417f7 | ||
|
|
f0e0efc46f | ||
|
|
1efa2e07ad | ||
|
|
df3932f750 | ||
|
|
817d0b4902 | ||
|
|
ffd8e958fc | ||
|
|
ed33b75bad | ||
|
|
262e768fd3 | ||
|
|
bc3a9ce003 | ||
|
|
48005d87f8 | ||
|
|
e37e9c2ca3 | ||
|
|
8fde63b323 | ||
|
|
97338e4cd6 | ||
|
|
9645790a8b | ||
|
|
18800c6884 | ||
|
|
fd638a2e54 | ||
|
|
fa1459d56e | ||
|
|
d93c5811ea | ||
|
|
06e426f509 | ||
|
|
6eb014b3b2 | ||
|
|
d9fd78d907 | ||
|
|
37df07d2e0 | ||
|
|
d5c65b5f1b | ||
|
|
cdc4e86158 | ||
|
|
50ec6d3b0f | ||
|
|
a6eb60cdd5 | ||
|
|
90c04b9cff | ||
|
|
b701cca779 | ||
|
|
ce8953442d | ||
|
|
7d4e513a82 | ||
|
|
35f7f7b66d | ||
|
|
6e02405bd6 | ||
|
|
b657468346 | ||
|
|
f72ed255e5 | ||
|
|
7e9dea0027 | ||
|
|
9545958ad8 | ||
|
|
41faa335d1 | ||
|
|
4cfa350112 | ||
|
|
41f163fc8d | ||
|
|
d21dd994e6 | ||
|
|
6f5a6b8c8b | ||
|
|
35606d7b05 | ||
|
|
3ad257cfea | ||
|
|
b39f960cd1 | ||
|
|
c297d46899 | ||
|
|
d6a100028c | ||
|
|
35d4e03f2a | ||
|
|
41e77bb01d | ||
|
|
2ff3dd5fbe | ||
|
|
0f0e7a521a | ||
|
|
b75663be6d | ||
|
|
4d3d04ee61 | ||
|
|
87422ba362 | ||
|
|
c1d2976fff | ||
|
|
13281cd9ca | ||
|
|
e53652779d | ||
|
|
db4c611c6f | ||
|
|
c25be31eb1 | ||
|
|
a7c533634d | ||
|
|
cfa6883431 | ||
|
|
216aa929af | ||
|
|
9e45424ed6 | ||
|
|
db7f16e276 | ||
|
|
a10a500a26 | ||
|
|
b9fef7cef7 | ||
|
|
34294ccc00 | ||
|
|
a934d01bdb | ||
|
|
0dd590f137 | ||
|
|
909a5c3253 | ||
|
|
5c987874c4 | ||
|
|
0cfe4f9c69 | ||
|
|
6a369e4a30 | ||
|
|
6f97e2c457 | ||
|
|
bebd412469 | ||
|
|
cd1f57b713 | ||
|
|
a0912deb2b | ||
|
|
50ee14a418 | ||
|
|
f5adbbebc5 | ||
|
|
c88e05dc1b | ||
|
|
d658bfc024 | ||
|
|
b0d72c47b4 | ||
|
|
8195873cdf | ||
|
|
bf8108469f | ||
|
|
a2277cfeba | ||
|
|
180541a924 | ||
|
|
34664a0ca0 | ||
|
|
e081455b06 | ||
|
|
4f18fa6733 | ||
|
|
6088a36cd3 | ||
|
|
66a162fa40 | ||
|
|
e6722f92ed | ||
|
|
750c28868f | ||
|
|
5157f584ab | ||
|
|
1c01ec21cb | ||
|
|
879512742f | ||
|
|
a919041dda | ||
|
|
059601d968 | ||
|
|
2ec1701543 | ||
|
|
370c3a5daf | ||
|
|
fdcb78fd8c | ||
|
|
2a744d24e5 | ||
|
|
cc30738148 | ||
|
|
147c6ff1db | ||
|
|
036380e6a8 | ||
|
|
b6587e51ee | ||
|
|
1bc37110d4 | ||
|
|
28acdb76cf | ||
|
|
7b09972c97 | ||
|
|
f8d46d09ef | ||
|
|
294cd95c54 | ||
|
|
d8e709648d | ||
|
|
52cc4d6537 | ||
|
|
08e9d12137 | ||
|
|
39fdc71b49 | ||
|
|
6b0736cf4b | ||
|
|
58269a918a | ||
|
|
9168a12679 | ||
|
|
cb971d3a48 | ||
|
|
57a5071b4e | ||
|
|
976fe364d4 | ||
|
|
028c7855b2 | ||
|
|
e5179f67fd | ||
|
|
c9c199dbca | ||
|
|
70e378b736 | ||
|
|
ca49b00e55 | ||
|
|
f661c90bd7 | ||
|
|
5a84df293f | ||
|
|
23d9309111 | ||
|
|
98ea94fdb7 | ||
|
|
746e1d3436 | ||
|
|
016ff01a04 | ||
|
|
298498e934 | ||
|
|
3ef1c2e303 | ||
|
|
ac028cd9f8 | ||
|
|
c0eb5c28d1 | ||
|
|
a77b4566e4 | ||
|
|
860993187e | ||
|
|
58d4e00604 | ||
|
|
2d95912699 | ||
|
|
4f927fbacc | ||
|
|
2e41301520 | ||
|
|
3179fc110d | ||
|
|
03ae0118b7 | ||
|
|
05176890ee | ||
|
|
849b947b3e | ||
|
|
c314e10e54 | ||
|
|
9eda286dcd | ||
|
|
65a3461519 | ||
|
|
1b8d2df3bf | ||
|
|
179ead0157 | ||
|
|
d451c7a506 | ||
|
|
502ce80c91 | ||
|
|
49d22d8fe2 | ||
|
|
08e0b76587 | ||
|
|
f7515739ac | ||
|
|
53e810ed3e | ||
|
|
66a195f805 | ||
|
|
b8483975a4 | ||
|
|
4dd2032687 | ||
|
|
c6c15d5cf9 | ||
|
|
2bf7b35268 | ||
|
|
6d1adc85fc | ||
|
|
02285c18d1 | ||
|
|
8120d7c974 | ||
|
|
c858804ed4 | ||
|
|
b9d075c252 | ||
|
|
7627e840c9 | ||
|
|
3c03e2cb2e | ||
|
|
aeae63b7ea | ||
|
|
7be17c5f1e | ||
|
|
6128346b08 | ||
|
|
1705574e75 | ||
|
|
15f65fa8d6 | ||
|
|
d1cf0ee52b | ||
|
|
32520ff07f | ||
|
|
3659236580 | ||
|
|
dde69d50b5 | ||
|
|
67198ce7b3 |
@@ -1,5 +1,6 @@
|
||||
[alias]
|
||||
dev = "run --package ruff_dev --bin ruff_dev"
|
||||
benchmark = "bench -p ruff_benchmark --"
|
||||
|
||||
[target.'cfg(all())']
|
||||
rustflags = [
|
||||
|
||||
6
.gitattributes
vendored
Normal file
6
.gitattributes
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
* text=auto eol=lf
|
||||
|
||||
crates/ruff/resources/test/fixtures/isort/line_ending_crlf.py text eol=crlf
|
||||
crates/ruff/resources/test/fixtures/pycodestyle/W605_1.py text eol=crlf
|
||||
|
||||
ruff.schema.json linguist-generated=true text=auto eol=lf
|
||||
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
time: "12:00"
|
||||
timezone: "America/New_York"
|
||||
commit-message:
|
||||
prefix: "ci(deps)"
|
||||
135
.github/workflows/benchmark.yaml
vendored
Normal file
135
.github/workflows/benchmark.yaml
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
name: Benchmark
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
run-benchmark:
|
||||
if: github.event_name == 'pull_request'
|
||||
name: "Run | ${{ matrix.os }}"
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: "PR - Checkout Branch"
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: "PR - Install Rust toolchain"
|
||||
run: rustup show
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: "PR - Build benchmarks"
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: bench
|
||||
args: -p ruff_benchmark --no-run
|
||||
|
||||
- name: "PR - Run benchmarks"
|
||||
run: cargo benchmark --save-baseline=pr
|
||||
|
||||
- name: "Main - Checkout Branch"
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
clean: false
|
||||
ref: main
|
||||
|
||||
- name: "Main - Install Rust toolchain"
|
||||
run: rustup show
|
||||
|
||||
- name: "Main - Build benchmarks"
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: bench
|
||||
args: -p ruff_benchmark --no-run
|
||||
|
||||
- name: "Main - Run benchmarks"
|
||||
run: cargo benchmark --save-baseline=main
|
||||
|
||||
- name: "Upload benchmark results"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: benchmark-results-${{ matrix.os }}
|
||||
path: ./target/criterion
|
||||
|
||||
# Cleanup
|
||||
- name: Remove Criterion Artifact
|
||||
uses: JesseTG/rm@v1.0.3
|
||||
with:
|
||||
path: ./target/criterion
|
||||
|
||||
benchmark-compare:
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
name: Compare
|
||||
needs:
|
||||
- run-benchmark
|
||||
|
||||
steps:
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
|
||||
- name: "Install cargo-binstall"
|
||||
uses: taiki-e/install-action@cargo-binstall
|
||||
|
||||
- name: "Install critcmp"
|
||||
run: cargo binstall critcmp -y
|
||||
|
||||
- name: "Linux | Download PR benchmark results"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: benchmark-results-ubuntu-latest
|
||||
path: ./target/criterion
|
||||
|
||||
- name: "Linux | Compare benchmark results"
|
||||
shell: bash
|
||||
run: |
|
||||
echo "### Benchmark" >> summary.md
|
||||
echo "#### Linux" >> summary.md
|
||||
echo "\`\`\`" >> summary.md
|
||||
critcmp main pr >> summary.md
|
||||
echo "\`\`\`" >> summary.md
|
||||
echo "" >> summary.md
|
||||
|
||||
- name: "Linux | Cleanup benchmark results"
|
||||
run: rm -rf ./target/criterion
|
||||
|
||||
- name: "Windows | Download PR benchmark results"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: benchmark-results-windows-latest
|
||||
path: ./target/criterion
|
||||
|
||||
- name: "Windows | Compare benchmark results"
|
||||
shell: bash
|
||||
run: |
|
||||
echo "#### Windows" >> summary.md
|
||||
echo "\`\`\`" >> summary.md
|
||||
critcmp main pr >> summary.md
|
||||
echo "\`\`\`" >> summary.md
|
||||
echo "" >> summary.md
|
||||
|
||||
echo ${{ github.event.pull_request.number }} > pr-number
|
||||
|
||||
cat summary.md > $GITHUB_STEP_SUMMARY
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
name: Upload PR Number
|
||||
with:
|
||||
name: pr-number
|
||||
path: pr-number
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
name: Upload Summary
|
||||
with:
|
||||
name: summary
|
||||
path: summary.md
|
||||
136
.github/workflows/ci.yaml
vendored
136
.github/workflows/ci.yaml
vendored
@@ -17,20 +17,6 @@ env:
|
||||
RUSTUP_MAX_RETRIES: 10
|
||||
|
||||
jobs:
|
||||
cargo-build:
|
||||
name: "cargo build"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- run: cargo build --all
|
||||
- run: ./target/debug/ruff_dev generate-all
|
||||
- run: git diff --quiet README.md || echo "::error file=README.md::This file is outdated. Run 'cargo dev generate-all'."
|
||||
- run: git diff --quiet ruff.schema.json || echo "::error file=ruff.schema.json::This file is outdated. Run 'cargo dev generate-all'."
|
||||
- run: git diff --exit-code -- README.md ruff.schema.json
|
||||
|
||||
cargo-fmt:
|
||||
name: "cargo fmt"
|
||||
runs-on: ubuntu-latest
|
||||
@@ -48,7 +34,7 @@ jobs:
|
||||
- name: "Install Rust toolchain"
|
||||
run: |
|
||||
rustup component add clippy
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- run: cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
|
||||
cargo-clippy-wasm:
|
||||
@@ -60,8 +46,8 @@ jobs:
|
||||
run: |
|
||||
rustup component add clippy
|
||||
rustup target add wasm32-unknown-unknown
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- run: cargo clippy -p ruff --target wasm32-unknown-unknown --all-features -- -D warnings
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- run: cargo clippy -p ruff_wasm --target wasm32-unknown-unknown --all-features -- -D warnings
|
||||
|
||||
cargo-test:
|
||||
strategy:
|
||||
@@ -73,9 +59,9 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- run: cargo install cargo-insta
|
||||
- run: pip install black[d]==22.12.0
|
||||
- run: pip install black[d]==23.1.0
|
||||
- name: "Run tests (Ubuntu)"
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
run: |
|
||||
@@ -93,6 +79,30 @@ jobs:
|
||||
env:
|
||||
# Setting RUSTDOCFLAGS because `cargo doc --check` isn't yet implemented (https://github.com/rust-lang/cargo/issues/10025).
|
||||
RUSTDOCFLAGS: "-D warnings"
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
with:
|
||||
name: ruff
|
||||
path: target/debug/ruff
|
||||
|
||||
cargo-test-wasm:
|
||||
runs-on: ubuntu-latest
|
||||
name: "cargo test (wasm)"
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup target add wasm32-unknown-unknown
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "npm"
|
||||
cache-dependency-path: playground/package-lock.json
|
||||
- uses: jetli/wasm-pack-action@v0.4.0
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: "Run wasm-pack"
|
||||
run: |
|
||||
cd crates/ruff_wasm
|
||||
wasm-pack test --node
|
||||
|
||||
scripts:
|
||||
name: "test scripts"
|
||||
@@ -101,7 +111,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- run: ./scripts/add_rule.py --name DoTheThing --code PLC999 --linter pylint
|
||||
- run: cargo check
|
||||
- run: |
|
||||
@@ -109,21 +119,6 @@ jobs:
|
||||
./scripts/add_rule.py --name FirstRule --code TST001 --linter test
|
||||
- run: cargo check
|
||||
|
||||
maturin-build:
|
||||
name: "maturin build"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- run: pip install maturin
|
||||
- run: maturin build -b bin
|
||||
- run: python scripts/transform_readme.py --target pypi
|
||||
|
||||
typos:
|
||||
name: "spell check"
|
||||
runs-on: ubuntu-latest
|
||||
@@ -132,3 +127,74 @@ jobs:
|
||||
- uses: crate-ci/typos@master
|
||||
with:
|
||||
files: .
|
||||
|
||||
ecosystem:
|
||||
name: "ecosystem"
|
||||
runs-on: ubuntu-latest
|
||||
needs: cargo-test
|
||||
# Only runs on pull requests, since that is the only we way we can find the base version for comparison.
|
||||
if: github.event_name == 'pull_request'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
name: Download Ruff binary
|
||||
id: ruff-target
|
||||
with:
|
||||
name: ruff
|
||||
path: target/debug
|
||||
|
||||
- uses: dawidd6/action-download-artifact@v2
|
||||
name: Download base results
|
||||
with:
|
||||
name: ruff
|
||||
branch: ${{ github.event.pull_request.base.ref }}
|
||||
check_artifacts: true
|
||||
|
||||
- name: Run ecosystem check
|
||||
run: |
|
||||
# Make executable, since artifact download doesn't preserve this
|
||||
chmod +x ruff ${{ steps.ruff-target.outputs.download-path }}/ruff
|
||||
|
||||
scripts/check_ecosystem.py ruff ${{ steps.ruff-target.outputs.download-path }}/ruff | tee ecosystem-result
|
||||
cat ecosystem-result > $GITHUB_STEP_SUMMARY
|
||||
|
||||
echo ${{ github.event.number }} > pr-number
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
name: Upload PR Number
|
||||
with:
|
||||
name: pr-number
|
||||
path: pr-number
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
name: Upload Results
|
||||
with:
|
||||
name: ecosystem-result
|
||||
path: ecosystem-result
|
||||
|
||||
cargo-udeps:
|
||||
name: "cargo udeps"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup toolchain install nightly
|
||||
- name: "Install cargo-udeps"
|
||||
uses: taiki-e/install-action@cargo-udeps
|
||||
- name: "Run cargo-udeps"
|
||||
run: |
|
||||
unused_dependencies=$(cargo +nightly udeps > unused.txt && cat unused.txt | cut -d $'\n' -f 2-)
|
||||
if [ -z "$unused_dependencies" ]; then
|
||||
echo "No unused dependencies found" > $GITHUB_STEP_SUMMARY
|
||||
exit 0
|
||||
else
|
||||
echo "Unused dependencies found" > $GITHUB_STEP_SUMMARY
|
||||
echo '```console' >> $GITHUB_STEP_SUMMARY
|
||||
echo "$unused_dependencies" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
exit 1
|
||||
fi
|
||||
|
||||
3
.github/workflows/docs.yaml
vendored
3
.github/workflows/docs.yaml
vendored
@@ -13,6 +13,9 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: "Install dependencies"
|
||||
run: |
|
||||
pip install -r docs/requirements.txt
|
||||
|
||||
53
.github/workflows/flake8-to-ruff.yaml
vendored
53
.github/workflows/flake8-to-ruff.yaml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- name: "Build wheels - x86_64"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: x86_64
|
||||
args: --release --out dist --sdist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- name: "Build wheels - universal2"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
args: --release --universal2 --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
- name: "Install built wheel - universal2"
|
||||
@@ -76,7 +76,7 @@ jobs:
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
args: --release --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
@@ -102,7 +102,7 @@ jobs:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
architecture: x64
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
@@ -128,12 +128,12 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
args: --no-default-features --release --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
- uses: uraimo/run-on-arch-action@v2.5.0
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
if: matrix.target != 'ppc64'
|
||||
name: Install built wheel
|
||||
with:
|
||||
@@ -166,7 +166,7 @@ jobs:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
architecture: x64
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: musllinux_1_2
|
||||
@@ -201,12 +201,12 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.platform.target }}
|
||||
manylinux: musllinux_1_2
|
||||
args: --release --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
- uses: uraimo/run-on-arch-action@master
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
name: Install built wheel
|
||||
with:
|
||||
arch: ${{ matrix.platform.arch }}
|
||||
@@ -222,40 +222,6 @@ jobs:
|
||||
name: wheels
|
||||
path: dist
|
||||
|
||||
pypy:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
target: [x86_64, aarch64]
|
||||
python-version:
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
exclude:
|
||||
- os: macos-latest
|
||||
target: aarch64
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: pypy${{ matrix.python-version }}
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
args: --release --out dist -i pypy${{ matrix.python-version }} -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
- name: "Install built wheel"
|
||||
if: matrix.target == 'x86_64'
|
||||
run: |
|
||||
pip install dist/${{ env.CRATE_NAME }}-*.whl --force-reinstall
|
||||
- name: "Upload wheels"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: wheels
|
||||
path: dist
|
||||
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
@@ -267,7 +233,6 @@ jobs:
|
||||
- linux-cross
|
||||
- musllinux
|
||||
- musllinux-cross
|
||||
- pypy
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
|
||||
2
.github/workflows/playground.yaml
vendored
2
.github/workflows/playground.yaml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
- uses: jetli/wasm-pack-action@v0.4.0
|
||||
- uses: jetli/wasm-bindgen-action@v0.2.0
|
||||
- name: "Run wasm-pack"
|
||||
run: wasm-pack build --target web --out-dir ../../playground/src/pkg crates/ruff
|
||||
run: wasm-pack build --target web --out-dir ../../playground/src/pkg crates/ruff_wasm
|
||||
- name: "Install Node dependencies"
|
||||
run: npm ci
|
||||
working-directory: playground
|
||||
|
||||
84
.github/workflows/pr-comment.yaml
vendored
Normal file
84
.github/workflows/pr-comment.yaml
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
name: PR Check Comment
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [CI, Benchmark]
|
||||
types: [completed]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
workflow_run_id:
|
||||
description: The ecosystem workflow that triggers the workflow run
|
||||
required: true
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dawidd6/action-download-artifact@v2
|
||||
name: Download PR Number
|
||||
with:
|
||||
name: pr-number
|
||||
run_id: ${{ github.event.workflow_run.id || github.event.inputs.workflow_run_id }}
|
||||
if_no_artifact_found: ignore
|
||||
|
||||
- name: Extract PR Number
|
||||
id: pr-number
|
||||
run: |
|
||||
if [[ -f pr-number ]]
|
||||
then
|
||||
echo "pr-number=$(<pr-number)" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- uses: dawidd6/action-download-artifact@v2
|
||||
name: "Download Ecosystem Result"
|
||||
id: download-ecosystem-result
|
||||
if: steps.pr-number.outputs.pr-number
|
||||
with:
|
||||
name: ecosystem-result
|
||||
workflow: ci.yaml
|
||||
pr: ${{ steps.pr-number.outputs.pr-number }}
|
||||
path: pr/ecosystem
|
||||
if_no_artifact_found: ignore
|
||||
|
||||
- uses: dawidd6/action-download-artifact@v2
|
||||
name: "Download Benchmark Result"
|
||||
id: download-benchmark-result
|
||||
if: steps.pr-number.outputs.pr-number
|
||||
with:
|
||||
name: summary
|
||||
workflow: benchmark.yaml
|
||||
pr: ${{ steps.pr-number.outputs.pr-number }}
|
||||
path: pr/benchmark
|
||||
if_no_artifact_found: ignore
|
||||
|
||||
- name: Generate Comment
|
||||
id: generate-comment
|
||||
if: steps.download-ecosystem-result.outputs.found_artifact == 'true' || steps.download-benchmark-result.outputs.found_artifact == 'true'
|
||||
run: |
|
||||
echo 'comment<<EOF' >> $GITHUB_OUTPUT
|
||||
echo '## PR Check Results' >> $GITHUB_OUTPUT
|
||||
|
||||
if [[ -f pr/ecosystem/ecosystem-result ]]
|
||||
then
|
||||
echo "### Ecosystem" >> $GITHUB_OUTPUT
|
||||
cat pr/ecosystem/ecosystem-result >> $GITHUB_OUTPUT
|
||||
echo "" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
if [[ -f pr/benchmark/summary.md ]]
|
||||
then
|
||||
cat pr/benchmark/summary.md >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
echo 'EOF' >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create or update comment
|
||||
if: steps.generate-comment.outputs.comment
|
||||
uses: thollander/actions-comment-pull-request@v2
|
||||
with:
|
||||
pr_number: ${{ steps.pr-number.outputs.pr-number }}
|
||||
message: ${{ steps.generate-comment.outputs.comment }}
|
||||
comment_tag: PR Check Results
|
||||
185
.github/workflows/ruff.yaml
vendored
185
.github/workflows/ruff.yaml
vendored
@@ -2,9 +2,8 @@ name: "[ruff] Release"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- '**'
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -30,7 +29,7 @@ jobs:
|
||||
- name: "Prep README.md"
|
||||
run: python scripts/transform_readme.py --target pypi
|
||||
- name: "Build wheels - x86_64"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: x86_64
|
||||
args: --release --out dist --sdist
|
||||
@@ -42,6 +41,19 @@ jobs:
|
||||
with:
|
||||
name: wheels
|
||||
path: dist
|
||||
- name: "Archive binary"
|
||||
run: |
|
||||
ARCHIVE_FILE=ruff-x86_64-apple-darwin.tar.gz
|
||||
tar czvf $ARCHIVE_FILE -C target/x86_64-apple-darwin/release ruff
|
||||
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
||||
- name: "Upload binary"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: binaries
|
||||
path: |
|
||||
*.tar.gz
|
||||
*.sha256
|
||||
|
||||
macos-universal:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
@@ -53,7 +65,7 @@ jobs:
|
||||
- name: "Prep README.md"
|
||||
run: python scripts/transform_readme.py --target pypi
|
||||
- name: "Build wheels - universal2"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
args: --release --universal2 --out dist
|
||||
- name: "Install built wheel - universal2"
|
||||
@@ -64,26 +76,45 @@ jobs:
|
||||
with:
|
||||
name: wheels
|
||||
path: dist
|
||||
- name: "Archive binary"
|
||||
run: |
|
||||
ARCHIVE_FILE=ruff-aarch64-apple-darwin.tar.gz
|
||||
tar czvf $ARCHIVE_FILE -C target/aarch64-apple-darwin/release ruff
|
||||
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
||||
- name: "Upload binary"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: binaries
|
||||
path: |
|
||||
*.tar.gz
|
||||
*.sha256
|
||||
|
||||
windows:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
target: [x64, x86]
|
||||
platform:
|
||||
- target: x86_64-pc-windows-msvc
|
||||
arch: x64
|
||||
- target: i686-pc-windows-msvc
|
||||
arch: x86
|
||||
- target: aarch64-pc-windows-msvc
|
||||
arch: x64
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
architecture: ${{ matrix.target }}
|
||||
architecture: ${{ matrix.platform.arch }}
|
||||
- name: "Prep README.md"
|
||||
run: python scripts/transform_readme.py --target pypi
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
target: ${{ matrix.platform.target }}
|
||||
args: --release --out dist
|
||||
- name: "Install built wheel"
|
||||
if: ${{ !startsWith(matrix.platform.target, 'aarch64') }}
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
|
||||
@@ -92,12 +123,27 @@ jobs:
|
||||
with:
|
||||
name: wheels
|
||||
path: dist
|
||||
- name: "Archive binary"
|
||||
shell: bash
|
||||
run: |
|
||||
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.zip
|
||||
7z a $ARCHIVE_FILE ./target/${{ matrix.platform.target }}/release/ruff.exe
|
||||
sha256sum $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
||||
- name: "Upload binary"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: binaries
|
||||
path: |
|
||||
*.zip
|
||||
*.sha256
|
||||
|
||||
linux:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
target: [x86_64, i686]
|
||||
target:
|
||||
- x86_64-unknown-linux-gnu
|
||||
- i686-unknown-linux-gnu
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
@@ -107,13 +153,13 @@ jobs:
|
||||
- name: "Prep README.md"
|
||||
run: python scripts/transform_readme.py --target pypi
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
args: --release --out dist
|
||||
- name: "Install built wheel"
|
||||
if: matrix.target == 'x86_64'
|
||||
if: ${{ startsWith(matrix.target, 'x86_64') }}
|
||||
run: |
|
||||
pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
|
||||
- name: "Upload wheels"
|
||||
@@ -121,12 +167,34 @@ jobs:
|
||||
with:
|
||||
name: wheels
|
||||
path: dist
|
||||
- name: "Archive binary"
|
||||
run: |
|
||||
ARCHIVE_FILE=ruff-${{ matrix.target }}.tar.gz
|
||||
tar czvf $ARCHIVE_FILE -C target/${{ matrix.target }}/release ruff
|
||||
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
||||
- name: "Upload binary"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: binaries
|
||||
path: |
|
||||
*.tar.gz
|
||||
*.sha256
|
||||
|
||||
linux-cross:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
target: [aarch64, armv7, s390x, ppc64le, ppc64]
|
||||
platform:
|
||||
- target: aarch64-unknown-linux-gnu
|
||||
arch: aarch64
|
||||
- target: armv7-unknown-linux-gnueabihf
|
||||
arch: armv7
|
||||
- target: s390x-unknown-linux-gnu
|
||||
arch: s390x
|
||||
- target: powerpc64le-unknown-linux-gnu
|
||||
arch: ppc64le
|
||||
- target: powerpc64-unknown-linux-gnu
|
||||
arch: ppc64
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
@@ -135,16 +203,16 @@ jobs:
|
||||
- name: "Prep README.md"
|
||||
run: python scripts/transform_readme.py --target pypi
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
target: ${{ matrix.platform.target }}
|
||||
manylinux: auto
|
||||
args: --release --out dist
|
||||
- uses: uraimo/run-on-arch-action@v2.5.0
|
||||
if: matrix.target != 'ppc64'
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
if: matrix.platform.arch != 'ppc64'
|
||||
name: Install built wheel
|
||||
with:
|
||||
arch: ${{ matrix.target }}
|
||||
arch: ${{ matrix.platform.arch }}
|
||||
distro: ubuntu20.04
|
||||
githubToken: ${{ github.token }}
|
||||
install: |
|
||||
@@ -158,6 +226,18 @@ jobs:
|
||||
with:
|
||||
name: wheels
|
||||
path: dist
|
||||
- name: "Archive binary"
|
||||
run: |
|
||||
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.tar.gz
|
||||
tar czvf $ARCHIVE_FILE -C target/${{ matrix.platform.target }}/release ruff
|
||||
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
||||
- name: "Upload binary"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: binaries
|
||||
path: |
|
||||
*.tar.gz
|
||||
*.sha256
|
||||
|
||||
musllinux:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -175,7 +255,7 @@ jobs:
|
||||
- name: "Prep README.md"
|
||||
run: python scripts/transform_readme.py --target pypi
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: musllinux_1_2
|
||||
@@ -194,6 +274,18 @@ jobs:
|
||||
with:
|
||||
name: wheels
|
||||
path: dist
|
||||
- name: "Archive binary"
|
||||
run: |
|
||||
ARCHIVE_FILE=ruff-${{ matrix.target }}.tar.gz
|
||||
tar czvf $ARCHIVE_FILE -C target/${{ matrix.target }}/release ruff
|
||||
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
||||
- name: "Upload binary"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: binaries
|
||||
path: |
|
||||
*.tar.gz
|
||||
*.sha256
|
||||
|
||||
musllinux-cross:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -212,12 +304,12 @@ jobs:
|
||||
- name: "Prep README.md"
|
||||
run: python scripts/transform_readme.py --target pypi
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.platform.target }}
|
||||
manylinux: musllinux_1_2
|
||||
args: --release --out dist
|
||||
- uses: uraimo/run-on-arch-action@master
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
name: Install built wheel
|
||||
with:
|
||||
arch: ${{ matrix.platform.arch }}
|
||||
@@ -232,42 +324,18 @@ jobs:
|
||||
with:
|
||||
name: wheels
|
||||
path: dist
|
||||
|
||||
pypy:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
target: [x86_64, aarch64]
|
||||
python-version:
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
exclude:
|
||||
- os: macos-latest
|
||||
target: aarch64
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: pypy${{ matrix.python-version }}
|
||||
- name: "Prep README.md"
|
||||
run: python scripts/transform_readme.py --target pypi
|
||||
- name: "Build wheels"
|
||||
uses: messense/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
args: --release --out dist -i pypy${{ matrix.python-version }}
|
||||
- name: "Install built wheel"
|
||||
if: matrix.target == 'x86_64'
|
||||
- name: "Archive binary"
|
||||
run: |
|
||||
pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
|
||||
- name: "Upload wheels"
|
||||
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.tar.gz
|
||||
tar czvf $ARCHIVE_FILE -C target/${{ matrix.platform.target }}/release ruff
|
||||
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
||||
- name: "Upload binary"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: wheels
|
||||
path: dist
|
||||
name: binaries
|
||||
path: |
|
||||
*.tar.gz
|
||||
*.sha256
|
||||
|
||||
release:
|
||||
name: Release
|
||||
@@ -280,7 +348,6 @@ jobs:
|
||||
- linux-cross
|
||||
- musllinux
|
||||
- musllinux-cross
|
||||
- pypy
|
||||
if: "startsWith(github.ref, 'refs/tags/')"
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
@@ -297,3 +364,11 @@ jobs:
|
||||
- name: "Update pre-commit mirror"
|
||||
run: |
|
||||
curl -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ secrets.RUFF_PRE_COMMIT_PAT }}" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/charliermarsh/ruff-pre-commit/dispatches --data '{"event_type": "pypi_release"}'
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: binaries
|
||||
path: binaries
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: binaries/*
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,10 +1,6 @@
|
||||
# Local cache
|
||||
.ruff_cache
|
||||
crates/ruff/resources/test/cpython
|
||||
docs/*
|
||||
!docs/rules
|
||||
!docs/assets
|
||||
!docs/requirements.txt
|
||||
mkdocs.yml
|
||||
.overrides
|
||||
|
||||
@@ -191,3 +187,7 @@ cython_debug/
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/
|
||||
|
||||
# VIM
|
||||
.*.sw?
|
||||
.sw?
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
fail_fast: true
|
||||
repos:
|
||||
- repo: https://github.com/abravalheri/validate-pyproject
|
||||
rev: v0.10.1
|
||||
rev: v0.12.1
|
||||
hooks:
|
||||
- id: validate-pyproject
|
||||
|
||||
- repo: https://github.com/executablebooks/mdformat
|
||||
rev: 0.7.16
|
||||
hooks:
|
||||
- id: mdformat
|
||||
additional_dependencies:
|
||||
- mdformat-black
|
||||
- black==23.1.0 # Must be the latest version of Black
|
||||
|
||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||
rev: v0.33.0
|
||||
hooks:
|
||||
@@ -19,26 +28,41 @@ repos:
|
||||
- id: cargo-fmt
|
||||
name: cargo fmt
|
||||
entry: cargo fmt --
|
||||
language: rust
|
||||
language: system
|
||||
types: [rust]
|
||||
- id: clippy
|
||||
name: clippy
|
||||
entry: cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
language: rust
|
||||
language: system
|
||||
pass_filenames: false
|
||||
- id: ruff
|
||||
name: ruff
|
||||
entry: cargo run -- --no-cache --fix
|
||||
language: rust
|
||||
entry: cargo run -p ruff_cli -- check --no-cache --force-exclude --fix --exit-non-zero-on-fix
|
||||
language: system
|
||||
types_or: [python, pyi]
|
||||
require_serial: true
|
||||
exclude: ^crates/ruff/resources
|
||||
exclude: |
|
||||
(?x)^(
|
||||
crates/ruff/resources/.*|
|
||||
crates/ruff_python_formatter/resources/.*
|
||||
)$
|
||||
- id: dev-generate-all
|
||||
name: dev-generate-all
|
||||
entry: cargo dev generate-all
|
||||
language: rust
|
||||
language: system
|
||||
pass_filenames: false
|
||||
exclude: target
|
||||
|
||||
# Black
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.1.0
|
||||
hooks:
|
||||
- id: black
|
||||
exclude: |
|
||||
(?x)^(
|
||||
crates/ruff/resources/.*|
|
||||
crates/ruff_python_formatter/resources/.*
|
||||
)$
|
||||
|
||||
ci:
|
||||
skip: [cargo-fmt, clippy, dev-generate-all]
|
||||
|
||||
@@ -20,8 +20,7 @@ the intention of adding a stable public API in the future.
|
||||
### `select`, `extend-select`, `ignore`, and `extend-ignore` have new semantics ([#2312](https://github.com/charliermarsh/ruff/pull/2312))
|
||||
|
||||
Previously, the interplay between `select` and its related options could lead to unexpected
|
||||
behavior. For example, `ruff --select E501 --ignore ALL` and `ruff --select E501 --extend-ignore
|
||||
ALL` behaved differently. (See [#2312](https://github.com/charliermarsh/ruff/pull/2312) for more
|
||||
behavior. For example, `ruff --select E501 --ignore ALL` and `ruff --select E501 --extend-ignore ALL` behaved differently. (See [#2312](https://github.com/charliermarsh/ruff/pull/2312) for more
|
||||
examples.)
|
||||
|
||||
When Ruff determines the enabled rule set, it has to reconcile `select` and `ignore` from a variety
|
||||
@@ -74,7 +73,7 @@ ruff rule E402 --format json # Works! (And preferred.)
|
||||
This change is largely backwards compatible -- most users should experience
|
||||
no change in behavior. However, please note the following exceptions:
|
||||
|
||||
* Subcommands will now fail when invoked with unsupported arguments, instead
|
||||
- Subcommands will now fail when invoked with unsupported arguments, instead
|
||||
of silently ignoring them. For example, the following will now fail:
|
||||
|
||||
```console
|
||||
@@ -83,16 +82,16 @@ no change in behavior. However, please note the following exceptions:
|
||||
|
||||
(the `clean` command doesn't support `--respect-gitignore`.)
|
||||
|
||||
* The semantics of `ruff <arg>` have changed slightly when `<arg>` is a valid subcommand.
|
||||
- The semantics of `ruff <arg>` have changed slightly when `<arg>` is a valid subcommand.
|
||||
For example, prior to this release, running `ruff rule` would run `ruff` over a file or
|
||||
directory called `rule`. Now, `ruff rule` would invoke the `rule` subcommand. This should
|
||||
only impact projects with files or directories named `rule`, `check`, `explain`, `clean`,
|
||||
or `generate-shell-completion`.
|
||||
|
||||
* Scripts that invoke ruff should supply `--` before any positional arguments.
|
||||
- Scripts that invoke ruff should supply `--` before any positional arguments.
|
||||
(The semantics of `ruff -- <arg>` have not changed.)
|
||||
|
||||
* `--explain` previously treated `--format grouped` as a synonym for `--format text`.
|
||||
- `--explain` previously treated `--format grouped` as a synonym for `--format text`.
|
||||
This is no longer supported; instead, use `--format text`.
|
||||
|
||||
## 0.0.226
|
||||
@@ -146,4 +145,4 @@ default.
|
||||
`pyproject.toml` files are now resolved hierarchically, such that for each Python file, we find
|
||||
the first `pyproject.toml` file in its path, and use that to determine its lint settings.
|
||||
|
||||
See the [README](https://github.com/charliermarsh/ruff#pyprojecttoml-discovery) for more.
|
||||
See the [documentation](https://beta.ruff.rs/docs/configuration/#python-file-discovery) for more.
|
||||
|
||||
@@ -29,23 +29,23 @@ diverse, inclusive, and healthy community.
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
- Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
- The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
@@ -132,7 +132,7 @@ version 2.0, available [here](https://www.contributor-covenant.org/version/2/0/c
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the [FAQ](https://www.contributor-covenant.org/faq).
|
||||
Translations are available [here](https://www.contributor-covenant.org/translations).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
@@ -29,13 +29,10 @@ If you're looking for a place to start, we recommend implementing a new lint rul
|
||||
pattern-match against the examples in the existing codebase. Many lint rules are inspired by
|
||||
existing Python plugins, which can be used as a reference implementation.
|
||||
|
||||
As a concrete example: consider taking on one of the rules from the [`tryceratops`](https://github.com/charliermarsh/ruff/issues/2056)
|
||||
plugin, and looking to the originating [Python source](https://github.com/guilatrova/tryceratops)
|
||||
As a concrete example: consider taking on one of the rules from the [`flake8-pyi`](https://github.com/charliermarsh/ruff/issues/848)
|
||||
plugin, and looking to the originating [Python source](https://github.com/PyCQA/flake8-pyi)
|
||||
for guidance.
|
||||
|
||||
Alternatively, we've started work on the [`flake8-pyi`](https://github.com/charliermarsh/ruff/issues/848)
|
||||
plugin (see the [Python source](https://github.com/PyCQA/flake8-pyi)) -- another good place to start.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Ruff is written in Rust. You'll need to install the
|
||||
@@ -52,16 +49,16 @@ cargo install cargo-insta
|
||||
After cloning the repository, run Ruff locally with:
|
||||
|
||||
```shell
|
||||
cargo run check /path/to/file.py --no-cache
|
||||
cargo run -p ruff_cli -- check /path/to/file.py --no-cache
|
||||
```
|
||||
|
||||
Prior to opening a pull request, ensure that your code has been auto-formatted,
|
||||
and that it passes both the lint and test validation checks:
|
||||
|
||||
```shell
|
||||
cargo fmt --all # Auto-formatting...
|
||||
cargo fmt # Auto-formatting...
|
||||
cargo clippy --fix --workspace --all-targets --all-features # Linting...
|
||||
cargo test --all # Testing...
|
||||
cargo test # Testing...
|
||||
```
|
||||
|
||||
These checks will run on GitHub Actions when you open your Pull Request, but running them locally
|
||||
@@ -106,19 +103,19 @@ At time of writing, the repository includes the following crates:
|
||||
At a high level, the steps involved in adding a new lint rule are as follows:
|
||||
|
||||
1. Determine a name for the new rule as per our [rule naming convention](#rule-naming-convention).
|
||||
2. Create a file for your rule (e.g., `crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs`).
|
||||
3. In that file, define a violation struct. You can grep for `define_violation!` to see examples.
|
||||
4. Map the violation struct to a rule code in `crates/ruff/src/registry.rs` (e.g., `E402`).
|
||||
5. Define the logic for triggering the violation in `crates/ruff/src/checkers/ast.rs` (for AST-based
|
||||
1. Create a file for your rule (e.g., `crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs`).
|
||||
1. In that file, define a violation struct. You can grep for `#[violation]` to see examples.
|
||||
1. Map the violation struct to a rule code in `crates/ruff/src/registry.rs` (e.g., `E402`).
|
||||
1. Define the logic for triggering the violation in `crates/ruff/src/checkers/ast.rs` (for AST-based
|
||||
checks), `crates/ruff/src/checkers/tokens.rs` (for token-based checks), `crates/ruff/src/checkers/lines.rs`
|
||||
(for text-based checks), or `crates/ruff/src/checkers/filesystem.rs` (for filesystem-based
|
||||
checks).
|
||||
6. Add a test fixture.
|
||||
7. Update the generated files (documentation and generated code).
|
||||
1. Add a test fixture.
|
||||
1. Update the generated files (documentation and generated code).
|
||||
|
||||
To define the violation, start by creating a dedicated file for your rule under the appropriate
|
||||
rule linter (e.g., `crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs`). That file should
|
||||
contain a struct defined via `define_violation!`, along with a function that creates the violation
|
||||
contain a struct defined via `#[violation]`, along with a function that creates the violation
|
||||
based on any required inputs. (Many of the existing examples live in `crates/ruff/src/violations.rs`,
|
||||
but we're looking to place new rules in their own files.)
|
||||
|
||||
@@ -135,10 +132,10 @@ contain a variety of violations and non-violations designed to evaluate and demo
|
||||
of your lint rule.
|
||||
|
||||
Run `cargo dev generate-all` to generate the code for your new fixture. Then run Ruff
|
||||
locally with (e.g.) `cargo run check crates/ruff/resources/test/fixtures/pycodestyle/E402.py --no-cache --select E402`.
|
||||
locally with (e.g.) `cargo run -p ruff_cli -- check crates/ruff/resources/test/fixtures/pycodestyle/E402.py --no-cache --select E402`.
|
||||
|
||||
Once you're satisfied with the output, codify the behavior as a snapshot test by adding a new
|
||||
`test_case` macro in the relevant `crates/ruff/src/[linter]/mod.rs` file. Then, run `cargo test --all`.
|
||||
`test_case` macro in the relevant `crates/ruff/src/[linter]/mod.rs` file. Then, run `cargo test`.
|
||||
Your test will fail, but you'll be prompted to follow-up with `cargo insta review`. Accept the
|
||||
generated snapshot, then commit the snapshot file alongside the rest of your changes.
|
||||
|
||||
@@ -146,15 +143,18 @@ Finally, regenerate the documentation and generated code with `cargo dev generat
|
||||
|
||||
#### Rule naming convention
|
||||
|
||||
The rule name should make sense when read as "allow *rule-name*" or "allow *rule-name* items".
|
||||
The rule name should make sense when read as "allow _rule-name_" or "allow _rule-name_ items".
|
||||
|
||||
This implies that rule names:
|
||||
|
||||
* should state the bad thing being checked for
|
||||
- should state the bad thing being checked for
|
||||
|
||||
* should not contain instructions on what you what you should use instead
|
||||
- should not contain instructions on what you what you should use instead
|
||||
(these belong in the rule documentation and the `autofix_title` for rules that have autofix)
|
||||
|
||||
When re-implementing rules from other linters, this convention is given more importance than
|
||||
preserving the original rule name.
|
||||
|
||||
### Example: Adding a new configuration option
|
||||
|
||||
Ruff's user-facing settings live in a few different places.
|
||||
@@ -186,14 +186,19 @@ Finally, regenerate the documentation and generated code with `cargo dev generat
|
||||
To preview any changes to the documentation locally:
|
||||
|
||||
1. Install MkDocs and Material for MkDocs with:
|
||||
|
||||
```shell
|
||||
pip install -r docs/requirements.txt
|
||||
```
|
||||
2. Generate the MkDocs site with:
|
||||
|
||||
1. Generate the MkDocs site with:
|
||||
|
||||
```shell
|
||||
python scripts/generate_mkdocs.py
|
||||
```
|
||||
3. Run the development server with:
|
||||
|
||||
1. Run the development server with:
|
||||
|
||||
```shell
|
||||
mkdocs serve
|
||||
```
|
||||
|
||||
1300
Cargo.lock
generated
1300
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
57
Cargo.toml
57
Cargo.toml
@@ -1,15 +1,54 @@
|
||||
[workspace]
|
||||
members = ["crates/*"]
|
||||
default-members = ["crates/ruff", "crates/ruff_cli"]
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
rust-version = "1.67"
|
||||
homepage = "https://beta.ruff.rs/docs/"
|
||||
documentation = "https://beta.ruff.rs/docs/"
|
||||
repository = "https://github.com/charliermarsh/ruff"
|
||||
authors = ["Charlie Marsh <charlie.r.marsh@gmail.com>"]
|
||||
|
||||
[workspace.dependencies]
|
||||
libcst = { git = "https://github.com/charliermarsh/LibCST", rev = "f2f0b7a487a8725d161fe8b3ed73a6758b21e177" }
|
||||
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "61b48f108982d865524f86624a9d5bc2ae3bccef" }
|
||||
rustpython-parser = { features = ["lalrpop"], git = "https://github.com/RustPython/RustPython.git", rev = "61b48f108982d865524f86624a9d5bc2ae3bccef" }
|
||||
anyhow = { version = "1.0.69" }
|
||||
bitflags = { version = "1.3.2" }
|
||||
chrono = { version = "0.4.23", default-features = false, features = ["clock"] }
|
||||
clap = { version = "4.1.8", features = ["derive"] }
|
||||
colored = { version = "2.0.0" }
|
||||
filetime = { version = "0.2.20" }
|
||||
glob = { version = "0.3.1" }
|
||||
globset = { version = "0.4.10" }
|
||||
ignore = { version = "0.4.20" }
|
||||
insta = { version = "1.28.0" }
|
||||
is-macro = { version = "0.2.2" }
|
||||
itertools = { version = "0.10.5" }
|
||||
libcst = { git = "https://github.com/charliermarsh/LibCST", rev = "80e4c1399f95e5beb532fdd1e209ad2dbb470438" }
|
||||
log = { version = "0.4.17" }
|
||||
once_cell = { version = "1.17.1" }
|
||||
path-absolutize = { version = "3.0.14" }
|
||||
proc-macro2 = { version = "1.0.51" }
|
||||
quote = { version = "1.0.23" }
|
||||
regex = { version = "1.7.1" }
|
||||
rustc-hash = { version = "1.1.0" }
|
||||
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "c15f670f2c30cfae6b41a1874893590148c74bc4" }
|
||||
rustpython-parser = { features = [
|
||||
"lalrpop",
|
||||
"serde",
|
||||
], git = "https://github.com/RustPython/RustPython.git", rev = "c15f670f2c30cfae6b41a1874893590148c74bc4" }
|
||||
schemars = { version = "0.8.12" }
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
serde_json = { version = "1.0.93", features = ["preserve_order"] }
|
||||
shellexpand = { version = "3.0.0" }
|
||||
similar = { version = "2.2.1" }
|
||||
strum = { version = "0.24.1", features = ["strum_macros"] }
|
||||
strum_macros = { version = "0.24.3" }
|
||||
syn = { version = "1.0.109" }
|
||||
test-case = { version = "3.0.0" }
|
||||
textwrap = { version = "0.16.0" }
|
||||
toml = { version = "0.7.2" }
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
lto = "thin"
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
||||
opt-level = 3
|
||||
|
||||
@@ -23,3 +62,9 @@ opt-level = 3
|
||||
# https://github.com/bytecodealliance/wasm-tools/blob/b5c3d98e40590512a3b12470ef358d5c7b983b15/crates/wasmparser/src/limits.rs#L29
|
||||
[profile.dev.package.rustpython-parser]
|
||||
opt-level = 1
|
||||
|
||||
# Use the `--profile release-debug` flag to show symbols in release mode.
|
||||
# e.g. `cargo build --profile release-debug`
|
||||
[profile.release-debug]
|
||||
inherits = "release"
|
||||
debug = 1
|
||||
|
||||
78
LICENSE
78
LICENSE
@@ -393,7 +393,6 @@ are:
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
|
||||
- autoflake, licensed as follows:
|
||||
"""
|
||||
Copyright (C) 2012-2018 Steven Myint
|
||||
@@ -417,6 +416,31 @@ are:
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
- autotyping, licensed as follows:
|
||||
"""
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Jelle Zijlstra
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
- Flake8, licensed as follows:
|
||||
"""
|
||||
== Flake8 License (MIT) ==
|
||||
@@ -1062,3 +1086,55 @@ are:
|
||||
"""
|
||||
|
||||
- flake8-django, licensed under the GPL license.
|
||||
|
||||
- rust-analyzer/text-size, licensed under the MIT license:
|
||||
"""
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
"""
|
||||
|
||||
- rome/tools, licensed under the MIT license:
|
||||
"""
|
||||
MIT License
|
||||
|
||||
Copyright (c) Rome Tools, Inc. and its affiliates.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
@@ -1,2 +1,7 @@
|
||||
[files]
|
||||
extend-exclude = ["snapshots"]
|
||||
extend-exclude = ["snapshots", "black"]
|
||||
|
||||
[default.extend-words]
|
||||
trivias = "trivias"
|
||||
hel = "hel"
|
||||
whos = "whos"
|
||||
|
||||
7
clippy.toml
Normal file
7
clippy.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
doc-valid-idents = [
|
||||
"StackOverflow",
|
||||
"CodeQL",
|
||||
"IPython",
|
||||
"NumPy",
|
||||
"..",
|
||||
]
|
||||
@@ -1,19 +1,21 @@
|
||||
[package]
|
||||
name = "flake8-to-ruff"
|
||||
version = "0.0.246"
|
||||
edition = "2021"
|
||||
version = "0.0.258"
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
anyhow = { version = "1.0.66" }
|
||||
clap = { version = "4.0.1", features = ["derive"] }
|
||||
colored = { version = "2.0.0" }
|
||||
configparser = { version = "3.0.2" }
|
||||
once_cell = { version = "1.16.0" }
|
||||
regex = { version = "1.6.0" }
|
||||
ruff = { path = "../ruff", default-features = false }
|
||||
rustc-hash = { version = "1.1.0" }
|
||||
serde = { version = "1.0.147", features = ["derive"] }
|
||||
serde_json = { version = "1.0.87" }
|
||||
strum = { version = "0.24.1", features = ["strum_macros"] }
|
||||
strum_macros = { version = "0.24.3" }
|
||||
toml = { version = "0.6.0" }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
colored = { workspace = true }
|
||||
configparser = { version = "3.0.2" }
|
||||
once_cell = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
rustc-hash = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
strum = { workspace = true }
|
||||
strum_macros = { workspace = true }
|
||||
toml = { workspace = true }
|
||||
|
||||
@@ -84,9 +84,10 @@ flake8-to-ruff path/to/.flake8 --plugin flake8-builtins --plugin flake8-quotes
|
||||
1. Ruff only supports a subset of the Flake configuration options. `flake8-to-ruff` will warn on and
|
||||
ignore unsupported options in the `.flake8` file (or equivalent). (Similarly, Ruff has a few
|
||||
configuration options that don't exist in Flake8.)
|
||||
2. Ruff will omit any rule codes that are unimplemented or unsupported by Ruff, including rule
|
||||
codes from unsupported plugins. (See the [Ruff README](https://github.com/charliermarsh/ruff#user-content-how-does-ruff-compare-to-flake8)
|
||||
for the complete list of supported plugins.)
|
||||
1. Ruff will omit any rule codes that are unimplemented or unsupported by Ruff, including rule
|
||||
codes from unsupported plugins. (See the
|
||||
[documentation](https://beta.ruff.rs/docs/faq/#how-does-ruff-compare-to-flake8) for the complete
|
||||
list of supported plugins.)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -46,8 +46,15 @@ fn main() -> Result<()> {
|
||||
.map(|tool| ExternalConfig {
|
||||
black: tool.black.as_ref(),
|
||||
isort: tool.isort.as_ref(),
|
||||
..Default::default()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let external_config = ExternalConfig {
|
||||
project: pyproject
|
||||
.as_ref()
|
||||
.and_then(|pyproject| pyproject.project.as_ref()),
|
||||
..external_config
|
||||
};
|
||||
|
||||
// Create Ruff's pyproject.toml section.
|
||||
let pyproject = flake8_to_ruff::convert(&config, &external_config, args.plugin)?;
|
||||
|
||||
@@ -1,82 +1,77 @@
|
||||
[package]
|
||||
name = "ruff"
|
||||
version = "0.0.246"
|
||||
authors = ["Charlie Marsh <charlie.r.marsh@gmail.com>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.65.0"
|
||||
documentation = "https://github.com/charliermarsh/ruff"
|
||||
homepage = "https://github.com/charliermarsh/ruff"
|
||||
repository = "https://github.com/charliermarsh/ruff"
|
||||
version = "0.0.258"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
documentation.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
|
||||
[lib]
|
||||
name = "ruff"
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = { version = "1.0.66" }
|
||||
ruff_cache = { path = "../ruff_cache" }
|
||||
ruff_diagnostics = { path = "../ruff_diagnostics", features = ["serde"] }
|
||||
ruff_macros = { path = "../ruff_macros" }
|
||||
ruff_python_ast = { path = "../ruff_python_ast" }
|
||||
ruff_python_stdlib = { path = "../ruff_python_stdlib" }
|
||||
ruff_rustpython = { path = "../ruff_rustpython" }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
bisection = { version = "0.1.0" }
|
||||
bitflags = { version = "1.3.2" }
|
||||
cfg-if = { version = "1.0.0" }
|
||||
chrono = { version = "0.4.21", default-features = false, features = ["clock"] }
|
||||
clap = { version = "4.0.1", features = ["derive", "env"] }
|
||||
colored = { version = "2.0.0" }
|
||||
bitflags = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive", "string"], optional = true }
|
||||
colored = { workspace = true }
|
||||
dirs = { version = "4.0.0" }
|
||||
fern = { version = "0.6.1" }
|
||||
glob = { version = "0.3.0" }
|
||||
globset = { version = "0.4.9" }
|
||||
ignore = { version = "0.4.18" }
|
||||
imperative = { version = "1.0.3" }
|
||||
itertools = { version = "0.10.5" }
|
||||
glob = { workspace = true }
|
||||
globset = { workspace = true }
|
||||
ignore = { workspace = true }
|
||||
imperative = { version = "1.0.4" }
|
||||
is-macro = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
libcst = { workspace = true }
|
||||
log = { version = "0.4.17" }
|
||||
log = { workspace = true }
|
||||
natord = { version = "1.0.9" }
|
||||
nohash-hasher = { version = "0.2.0" }
|
||||
num-bigint = { version = "0.4.3" }
|
||||
num-traits = "0.2.15"
|
||||
once_cell = { version = "1.16.0" }
|
||||
path-absolutize = { version = "3.0.14", features = ["once_cell_cache", "use_unix_paths_on_wasm"] }
|
||||
regex = { version = "1.6.0" }
|
||||
ruff_macros = { version = "0.0.246", path = "../ruff_macros" }
|
||||
ruff_python = { version = "0.0.246", path = "../ruff_python" }
|
||||
rustc-hash = { version = "1.1.0" }
|
||||
num-traits = { version = "0.2.15" }
|
||||
once_cell = { workspace = true }
|
||||
path-absolutize = { workspace = true, features = [
|
||||
"once_cell_cache",
|
||||
"use_unix_paths_on_wasm",
|
||||
] }
|
||||
pathdiff = { version = "0.2.1" }
|
||||
pep440_rs = { git = "https://github.com/konstin/pep440-rs.git", features = [
|
||||
"serde",
|
||||
], rev = "a8fef4ec47f4c25b070b39cdbe6a0b9847e49941" }
|
||||
regex = { workspace = true }
|
||||
result-like = { version = "0.4.6" }
|
||||
rustc-hash = { workspace = true }
|
||||
rustpython-common = { workspace = true }
|
||||
rustpython-parser = { workspace = true }
|
||||
schemars = { version = "0.8.11" }
|
||||
schemars = { workspace = true }
|
||||
semver = { version = "1.0.16" }
|
||||
serde = { version = "1.0.147", features = ["derive"] }
|
||||
shellexpand = { version = "3.0.0" }
|
||||
serde = { workspace = true }
|
||||
shellexpand = { workspace = true }
|
||||
smallvec = { version = "1.10.0" }
|
||||
strum = { version = "0.24.1", features = ["strum_macros"] }
|
||||
strum_macros = { version = "0.24.3" }
|
||||
textwrap = { version = "0.16.0" }
|
||||
thiserror = { version = "1.0" }
|
||||
titlecase = { version = "2.2.1" }
|
||||
toml = { version = "0.6.0" }
|
||||
|
||||
# https://docs.rs/getrandom/0.2.7/getrandom/#webassembly-support
|
||||
# For (future) wasm-pack support
|
||||
[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies]
|
||||
getrandom = { version = "0.2.7", features = ["js"] }
|
||||
console_error_panic_hook = { version = "0.1.7" }
|
||||
console_log = { version = "0.2.0" }
|
||||
serde-wasm-bindgen = { version = "0.4" }
|
||||
js-sys = { version = "0.3.60" }
|
||||
wasm-bindgen = { version = "0.2.83" }
|
||||
|
||||
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
||||
is_executable = "1.0.1"
|
||||
strum = { workspace = true }
|
||||
strum_macros = { workspace = true }
|
||||
textwrap = { workspace = true }
|
||||
thiserror = { version = "1.0.38" }
|
||||
toml = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
insta = { version = "1.19.0", features = ["yaml", "redactions"] }
|
||||
test-case = { version = "2.2.2" }
|
||||
wasm-bindgen-test = { version = "0.3.33" }
|
||||
|
||||
[target.'cfg(not(target_family = "wasm"))'.dev-dependencies]
|
||||
criterion = { version = "0.4.0" }
|
||||
insta = { workspace = true, features = ["yaml", "redactions"] }
|
||||
pretty_assertions = "1.3.0"
|
||||
test-case = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
logical_lines = []
|
||||
jupyter_notebook = []
|
||||
|
||||
@@ -2,3 +2,7 @@ avoid-*
|
||||
do-not-*
|
||||
uses-*
|
||||
*-used
|
||||
rewrite-*
|
||||
prefer-*
|
||||
consider-*
|
||||
use-*
|
||||
|
||||
@@ -103,3 +103,11 @@ class Foo:
|
||||
@classmethod
|
||||
def foo(cls, a: int, b: int) -> int:
|
||||
pass
|
||||
|
||||
# ANN101
|
||||
def foo(self, /, a: int, b: int) -> int:
|
||||
pass
|
||||
|
||||
|
||||
# OK
|
||||
def f(*args: *tuple[int]) -> None: ...
|
||||
|
||||
42
crates/ruff/resources/test/fixtures/flake8_annotations/simple_magic_methods.py
vendored
Normal file
42
crates/ruff/resources/test/fixtures/flake8_annotations/simple_magic_methods.py
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
class Foo:
|
||||
def __str__(self):
|
||||
...
|
||||
|
||||
def __repr__(self):
|
||||
...
|
||||
|
||||
def __len__(self):
|
||||
...
|
||||
|
||||
def __length_hint__(self):
|
||||
...
|
||||
|
||||
def __init__(self):
|
||||
...
|
||||
|
||||
def __del__(self):
|
||||
...
|
||||
|
||||
def __bool__(self):
|
||||
...
|
||||
|
||||
def __bytes__(self):
|
||||
...
|
||||
|
||||
def __format__(self, format_spec):
|
||||
...
|
||||
|
||||
def __contains__(self, item):
|
||||
...
|
||||
|
||||
def __complex__(self):
|
||||
...
|
||||
|
||||
def __int__(self):
|
||||
...
|
||||
|
||||
def __float__(self):
|
||||
...
|
||||
|
||||
def __index__(self):
|
||||
...
|
||||
@@ -19,6 +19,8 @@ token = "s3cr3t"
|
||||
secrete = "s3cr3t"
|
||||
safe = password = "s3cr3t"
|
||||
password = safe = "s3cr3t"
|
||||
PASSWORD = "s3cr3t"
|
||||
PassWord = "s3cr3t"
|
||||
|
||||
d["password"] = "s3cr3t"
|
||||
d["pass"] = "s3cr3t"
|
||||
@@ -61,3 +63,15 @@ if token == "3\t4":
|
||||
|
||||
if token == "5\r6":
|
||||
pass
|
||||
|
||||
|
||||
# These should not be flagged
|
||||
passed_msg = "You have passed!"
|
||||
compassion = "Please don't match!"
|
||||
impassable = "You shall not pass!"
|
||||
passwords = ""
|
||||
PASSWORDS = ""
|
||||
passphrases = ""
|
||||
PassPhrases = ""
|
||||
tokens = ""
|
||||
secrets = ""
|
||||
|
||||
3
crates/ruff/resources/test/fixtures/flake8_bandit/S301.py
vendored
Normal file
3
crates/ruff/resources/test/fixtures/flake8_bandit/S301.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import pickle
|
||||
|
||||
pickle.loads()
|
||||
3
crates/ruff/resources/test/fixtures/flake8_bandit/S312.py
vendored
Normal file
3
crates/ruff/resources/test/fixtures/flake8_bandit/S312.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from telnetlib import Telnet
|
||||
|
||||
Telnet("localhost", 23)
|
||||
@@ -57,6 +57,12 @@ dict.fromkeys(("world",), True)
|
||||
{}.deploy(True, False)
|
||||
getattr(someobj, attrname, False)
|
||||
mylist.index(True)
|
||||
int(True)
|
||||
str(int(False))
|
||||
cfg.get("hello", True)
|
||||
cfg.getint("hello", True)
|
||||
cfg.getfloat("hello", True)
|
||||
cfg.getboolean("hello", True)
|
||||
|
||||
|
||||
class Registry:
|
||||
@@ -66,3 +72,11 @@ class Registry:
|
||||
# FBT001: Boolean positional arg in function definition
|
||||
def __setitem__(self, switch: Switch, value: bool) -> None:
|
||||
self._switches[switch.value] = value
|
||||
|
||||
@foo.setter
|
||||
def foo(self, value: bool) -> None:
|
||||
pass
|
||||
|
||||
# FBT001: Boolean positional arg in function definition
|
||||
def foo(self, value: bool) -> None:
|
||||
pass
|
||||
|
||||
@@ -17,6 +17,11 @@ s.rstrip(".facebook.com") # warning
|
||||
s.rstrip("e") # no warning
|
||||
s.rstrip("\n\t ") # no warning
|
||||
s.rstrip(r"\n\t ") # warning
|
||||
s.strip("a") # no warning
|
||||
s.strip("あ") # no warning
|
||||
s.strip("ああ") # warning
|
||||
s.strip("\ufeff") # no warning
|
||||
s.strip("\u0074\u0065\u0073\u0074") # warning
|
||||
|
||||
from somewhere import other_type, strip
|
||||
|
||||
|
||||
@@ -105,3 +105,25 @@ while True:
|
||||
pass
|
||||
finally:
|
||||
break # warning
|
||||
|
||||
|
||||
while True:
|
||||
try:
|
||||
pass
|
||||
finally:
|
||||
match *0, 1, *2:
|
||||
case 0,:
|
||||
y = 0
|
||||
case 0, *x:
|
||||
break # warning
|
||||
|
||||
|
||||
while True:
|
||||
try:
|
||||
pass
|
||||
finally:
|
||||
match *0, 1, *2:
|
||||
case 0,:
|
||||
y = 0
|
||||
case 0, *x:
|
||||
pass # no warning
|
||||
|
||||
101
crates/ruff/resources/test/fixtures/flake8_bugbear/B027.pyi
vendored
Normal file
101
crates/ruff/resources/test/fixtures/flake8_bugbear/B027.pyi
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
"""
|
||||
Should emit:
|
||||
B027 - on lines 13, 16, 19, 23
|
||||
"""
|
||||
import abc
|
||||
from abc import ABC
|
||||
from abc import abstractmethod, abstractproperty
|
||||
from abc import abstractmethod as notabstract
|
||||
from abc import abstractproperty as notabstract_property
|
||||
|
||||
|
||||
class AbstractClass(ABC):
|
||||
def empty_1(self): # error
|
||||
...
|
||||
|
||||
def empty_2(self): # error
|
||||
pass
|
||||
|
||||
def empty_3(self): # error
|
||||
"""docstring"""
|
||||
...
|
||||
|
||||
def empty_4(self): # error
|
||||
"""multiple ellipsis/pass"""
|
||||
...
|
||||
pass
|
||||
...
|
||||
pass
|
||||
|
||||
@notabstract
|
||||
def abstract_0(self):
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def abstract_1(self):
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def abstract_2(self):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def abstract_3(self):
|
||||
...
|
||||
|
||||
@abc.abstractproperty
|
||||
def abstract_4(self):
|
||||
...
|
||||
|
||||
@abstractproperty
|
||||
def abstract_5(self):
|
||||
...
|
||||
|
||||
@notabstract_property
|
||||
def abstract_6(self):
|
||||
...
|
||||
|
||||
def body_1(self):
|
||||
print("foo")
|
||||
...
|
||||
|
||||
def body_2(self):
|
||||
self.body_1()
|
||||
|
||||
|
||||
class NonAbstractClass:
|
||||
def empty_1(self): # safe
|
||||
...
|
||||
|
||||
def empty_2(self): # safe
|
||||
pass
|
||||
|
||||
|
||||
# ignore @overload, fixes issue #304
|
||||
# ignore overload with other imports, fixes #308
|
||||
import typing
|
||||
import typing as t
|
||||
import typing as anything
|
||||
from typing import Union, overload
|
||||
|
||||
|
||||
class AbstractClass(ABC):
|
||||
@overload
|
||||
def empty_1(self, foo: str):
|
||||
...
|
||||
|
||||
@typing.overload
|
||||
def empty_1(self, foo: int):
|
||||
...
|
||||
|
||||
@t.overload
|
||||
def empty_1(self, foo: list):
|
||||
...
|
||||
|
||||
@anything.overload
|
||||
def empty_1(self, foo: float):
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def empty_1(self, foo: Union[str, int, list, float]):
|
||||
...
|
||||
11
crates/ruff/resources/test/fixtures/flake8_bugbear/B028.py
vendored
Normal file
11
crates/ruff/resources/test/fixtures/flake8_bugbear/B028.py
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import warnings
|
||||
|
||||
"""
|
||||
Should emit:
|
||||
B028 - on lines 8 and 9
|
||||
"""
|
||||
|
||||
warnings.warn(DeprecationWarning("test"))
|
||||
warnings.warn(DeprecationWarning("test"), source=None)
|
||||
warnings.warn(DeprecationWarning("test"), source=None, stacklevel=2)
|
||||
warnings.warn(DeprecationWarning("test"), stacklevel=1)
|
||||
14
crates/ruff/resources/test/fixtures/flake8_bugbear/B029.py
vendored
Normal file
14
crates/ruff/resources/test/fixtures/flake8_bugbear/B029.py
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
"""
|
||||
Should emit:
|
||||
B029 - on lines 8 and 13
|
||||
"""
|
||||
|
||||
try:
|
||||
pass
|
||||
except ():
|
||||
pass
|
||||
|
||||
try:
|
||||
pass
|
||||
except () as e:
|
||||
pass
|
||||
47
crates/ruff/resources/test/fixtures/flake8_bugbear/B030.py
vendored
Normal file
47
crates/ruff/resources/test/fixtures/flake8_bugbear/B030.py
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
Should emit:
|
||||
B030:
|
||||
- line 12, column 8
|
||||
- line 17, column 9
|
||||
- line 22, column 21
|
||||
- line 27, column 37
|
||||
"""
|
||||
|
||||
try:
|
||||
pass
|
||||
except 1: # error
|
||||
pass
|
||||
|
||||
try:
|
||||
pass
|
||||
except (1, ValueError): # error
|
||||
pass
|
||||
|
||||
try:
|
||||
pass
|
||||
except (ValueError, (RuntimeError, (KeyError, TypeError))): # error
|
||||
pass
|
||||
|
||||
try:
|
||||
pass
|
||||
except (ValueError, *(RuntimeError, (KeyError, TypeError))): # error
|
||||
pass
|
||||
|
||||
|
||||
try:
|
||||
pass
|
||||
except (ValueError, *(RuntimeError, TypeError)): # ok
|
||||
pass
|
||||
|
||||
try:
|
||||
pass
|
||||
except (ValueError, *[RuntimeError, *(TypeError,)]): # ok
|
||||
pass
|
||||
|
||||
def what_to_catch():
|
||||
return ...
|
||||
|
||||
try:
|
||||
pass
|
||||
except what_to_catch(): # ok
|
||||
pass
|
||||
29
crates/ruff/resources/test/fixtures/flake8_bugbear/B032.py
vendored
Normal file
29
crates/ruff/resources/test/fixtures/flake8_bugbear/B032.py
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
Should emit:
|
||||
B032 - on lines 9, 10, 12, 13, 16-19
|
||||
"""
|
||||
|
||||
# Flag these
|
||||
dct = {"a": 1}
|
||||
|
||||
dct["b"]: 2
|
||||
dct.b: 2
|
||||
|
||||
dct["b"]: "test"
|
||||
dct.b: "test"
|
||||
|
||||
test = "test"
|
||||
dct["b"]: test
|
||||
dct["b"]: test.lower()
|
||||
dct.b: test
|
||||
dct.b: test.lower()
|
||||
|
||||
# Do not flag below
|
||||
typed_dct: dict[str, int] = {"a": 1}
|
||||
typed_dct["b"] = 2
|
||||
typed_dct.b = 2
|
||||
|
||||
|
||||
class TestClass:
|
||||
def test_self(self):
|
||||
self.test: int
|
||||
@@ -1,6 +1,6 @@
|
||||
"""
|
||||
Should emit:
|
||||
B904 - on lines 10, 11 and 16
|
||||
B904 - on lines 10, 11, 16, 62, and 64
|
||||
"""
|
||||
|
||||
try:
|
||||
@@ -53,3 +53,20 @@ except ImportError:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
raise
|
||||
|
||||
|
||||
try:
|
||||
...
|
||||
except Exception as e:
|
||||
if ...:
|
||||
raise RuntimeError("boom!")
|
||||
else:
|
||||
raise RuntimeError("bang!")
|
||||
|
||||
|
||||
try:
|
||||
...
|
||||
except Exception as e:
|
||||
match 0:
|
||||
case 0:
|
||||
raise RuntimeError("boom!")
|
||||
|
||||
@@ -626,3 +626,8 @@ result = function(
|
||||
bar,
|
||||
**{'ham': spam}
|
||||
)
|
||||
|
||||
# Make sure the COM812 and UP034 rules don't autofix simultaneously and cause a syntax error.
|
||||
the_first_one = next(
|
||||
(i for i in range(10) if i // 2 == 0) # COM812 fix should include the final bracket
|
||||
)
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
x = [1, 2, 3]
|
||||
y = [("a", 1), ("b", 2), ("c", 3)]
|
||||
z = [(1,), (2,), (3,)]
|
||||
d = {"a": 1, "b": 2, "c": 3}
|
||||
|
||||
[i for i in x]
|
||||
{i for i in x}
|
||||
{k: v for k, v in y}
|
||||
{k: v for k, v in d.items()}
|
||||
|
||||
[i for i, in z]
|
||||
[i for i, j in y]
|
||||
[i for i in x if i > 1]
|
||||
[i for i in x for j in x]
|
||||
|
||||
{v: k for k, v in y}
|
||||
{k.foo: k for k in y}
|
||||
{k["foo"]: k for k in y}
|
||||
{k: v if v else None for k, v in y}
|
||||
|
||||
@@ -12,7 +12,16 @@ class IncorrectModel(models.Model):
|
||||
urlfield = models.URLField(max_length=255, null=True)
|
||||
|
||||
|
||||
class IncorrectModelWithAliasedBase(DjangoModel):
|
||||
class IncorrectModelWithAlias(DjangoModel):
|
||||
charfield = DjangoModel.CharField(max_length=255, null=True)
|
||||
textfield = SmthCharField(max_length=255, null=True)
|
||||
slugfield = models.SlugField(max_length=255, null=True)
|
||||
emailfield = models.EmailField(max_length=255, null=True)
|
||||
filepathfield = models.FilePathField(max_length=255, null=True)
|
||||
urlfield = models.URLField(max_length=255, null=True)
|
||||
|
||||
|
||||
class IncorrectModelWithoutSuperclass:
|
||||
charfield = DjangoModel.CharField(max_length=255, null=True)
|
||||
textfield = SmthCharField(max_length=255, null=True)
|
||||
slugfield = models.SlugField(max_length=255, null=True)
|
||||
|
||||
21
crates/ruff/resources/test/fixtures/flake8_django/DJ003.py
vendored
Normal file
21
crates/ruff/resources/test/fixtures/flake8_django/DJ003.py
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
|
||||
def test_view1(request):
|
||||
return render(request, "index.html", locals())
|
||||
|
||||
|
||||
def test_view2(request):
|
||||
return render(request, "index.html", context=locals())
|
||||
|
||||
|
||||
def test_view3(request):
|
||||
return render(request, "index.html")
|
||||
|
||||
|
||||
def test_view4(request):
|
||||
return render(request, "index.html", {})
|
||||
|
||||
|
||||
def test_view5(request):
|
||||
return render(request, "index.html", context={})
|
||||
11
crates/ruff/resources/test/fixtures/flake8_django/DJ006.py
vendored
Normal file
11
crates/ruff/resources/test/fixtures/flake8_django/DJ006.py
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
from django import forms
|
||||
|
||||
|
||||
class TestModelForm1(forms.ModelForm):
|
||||
class Meta:
|
||||
exclude = ["bar"]
|
||||
|
||||
|
||||
class TestModelForm2(forms.ModelForm):
|
||||
class Meta:
|
||||
fields = ["foo"]
|
||||
16
crates/ruff/resources/test/fixtures/flake8_django/DJ007.py
vendored
Normal file
16
crates/ruff/resources/test/fixtures/flake8_django/DJ007.py
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
from django import forms
|
||||
|
||||
|
||||
class TestModelForm1(forms.ModelForm):
|
||||
class Meta:
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class TestModelForm2(forms.ModelForm):
|
||||
class Meta:
|
||||
fields = b"__all__"
|
||||
|
||||
|
||||
class TestModelForm3(forms.ModelForm):
|
||||
class Meta:
|
||||
fields = ["foo"]
|
||||
113
crates/ruff/resources/test/fixtures/flake8_django/DJ012.py
vendored
Normal file
113
crates/ruff/resources/test/fixtures/flake8_django/DJ012.py
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
from django.db import models
|
||||
from django.db.models import Model
|
||||
|
||||
|
||||
class StrBeforeRandomField(models.Model):
|
||||
"""Model with `__str__` before a random property."""
|
||||
|
||||
class Meta:
|
||||
verbose_name = "test"
|
||||
verbose_name_plural = "tests"
|
||||
|
||||
def __str__(self):
|
||||
return ""
|
||||
|
||||
random_property = "foo"
|
||||
|
||||
|
||||
class StrBeforeFieldModel(models.Model):
|
||||
"""Model with `__str__` before fields."""
|
||||
|
||||
class Meta:
|
||||
verbose_name = "test"
|
||||
verbose_name_plural = "tests"
|
||||
|
||||
def __str__(self):
|
||||
return "foobar"
|
||||
|
||||
first_name = models.CharField(max_length=32)
|
||||
|
||||
|
||||
class ManagerBeforeField(models.Model):
|
||||
"""Model with manager before fields."""
|
||||
|
||||
objects = "manager"
|
||||
|
||||
class Meta:
|
||||
verbose_name = "test"
|
||||
verbose_name_plural = "tests"
|
||||
|
||||
def __str__(self):
|
||||
return "foobar"
|
||||
|
||||
first_name = models.CharField(max_length=32)
|
||||
|
||||
|
||||
class CustomMethodBeforeStr(models.Model):
|
||||
"""Model with a custom method before `__str__`."""
|
||||
|
||||
class Meta:
|
||||
verbose_name = "test"
|
||||
verbose_name_plural = "tests"
|
||||
|
||||
def my_method(self):
|
||||
pass
|
||||
|
||||
def __str__(self):
|
||||
return "foobar"
|
||||
|
||||
|
||||
class GetAbsoluteUrlBeforeSave(Model):
|
||||
"""Model with `get_absolute_url` method before `save` method.
|
||||
|
||||
Subclass this directly using the `Model` class.
|
||||
"""
|
||||
|
||||
def get_absolute_url(self):
|
||||
pass
|
||||
|
||||
def save(self):
|
||||
pass
|
||||
|
||||
|
||||
class ConstantsAreNotFields(models.Model):
|
||||
"""Model with an assignment to a constant after `__str__`."""
|
||||
|
||||
first_name = models.CharField(max_length=32)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "test"
|
||||
verbose_name_plural = "tests"
|
||||
|
||||
def __str__(self):
|
||||
pass
|
||||
|
||||
MY_CONSTANT = id(1)
|
||||
|
||||
|
||||
class PerfectlyFine(models.Model):
|
||||
"""Model which has everything in perfect order."""
|
||||
|
||||
first_name = models.CharField(max_length=32)
|
||||
last_name = models.CharField(max_length=32)
|
||||
objects = "manager"
|
||||
|
||||
class Meta:
|
||||
verbose_name = "test"
|
||||
verbose_name_plural = "tests"
|
||||
|
||||
def __str__(self):
|
||||
return "Perfectly fine!"
|
||||
|
||||
def save(self, **kwargs):
|
||||
super(PerfectlyFine, self).save(**kwargs)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return "http://%s" % self
|
||||
|
||||
def my_method(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def random_property(self):
|
||||
return "%s" % self
|
||||
@@ -15,3 +15,23 @@ def correct_pre_save_handler():
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
def incorrect_pre_save_handler():
|
||||
pass
|
||||
|
||||
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
@test_decorator
|
||||
def correct_multiple():
|
||||
pass
|
||||
|
||||
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
def correct_multiple():
|
||||
pass
|
||||
|
||||
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
@test_decorator
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
def incorrect_multiple():
|
||||
pass
|
||||
|
||||
16
crates/ruff/resources/test/fixtures/flake8_pie/PIE802.py
vendored
Normal file
16
crates/ruff/resources/test/fixtures/flake8_pie/PIE802.py
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# no error
|
||||
all((x.id for x in bar))
|
||||
all(x.id for x in bar)
|
||||
all(x.id for x in bar)
|
||||
any(x.id for x in bar)
|
||||
any({x.id for x in bar})
|
||||
|
||||
# PIE 802
|
||||
any([x.id for x in bar])
|
||||
all([x.id for x in bar])
|
||||
any( # first comment
|
||||
[x.id for x in bar], # second comment
|
||||
) # third comment
|
||||
all( # first comment
|
||||
[x.id for x in bar], # second comment
|
||||
) # third comment
|
||||
@@ -18,3 +18,10 @@ class Foo:
|
||||
|
||||
class FooTable(BaseTable):
|
||||
bar = fields.ListField(list)
|
||||
|
||||
|
||||
lambda *args, **kwargs: []
|
||||
|
||||
lambda *args: []
|
||||
|
||||
lambda **kwargs: []
|
||||
|
||||
@@ -6,6 +6,8 @@ obj.endswith("foo") or obj.endswith("bar")
|
||||
obj.startswith(foo) or obj.startswith(bar)
|
||||
# error
|
||||
obj.startswith(foo) or obj.startswith("foo")
|
||||
# error
|
||||
obj.endswith(foo) or obj.startswith(foo) or obj.startswith("foo")
|
||||
|
||||
# ok
|
||||
obj.startswith(("foo", "bar"))
|
||||
|
||||
14
crates/ruff/resources/test/fixtures/flake8_pyi/PYI006.py
vendored
Normal file
14
crates/ruff/resources/test/fixtures/flake8_pyi/PYI006.py
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import sys
|
||||
from sys import version_info as python_version
|
||||
|
||||
if sys.version_info < (3, 9): ... # OK
|
||||
|
||||
if sys.version_info >= (3, 9): ... # OK
|
||||
|
||||
if sys.version_info == (3, 9): ... # OK
|
||||
|
||||
if sys.version_info <= (3, 10): ... # OK
|
||||
|
||||
if sys.version_info > (3, 10): ... # OK
|
||||
|
||||
if python_version > (3, 10): ... # OK
|
||||
18
crates/ruff/resources/test/fixtures/flake8_pyi/PYI006.pyi
vendored
Normal file
18
crates/ruff/resources/test/fixtures/flake8_pyi/PYI006.pyi
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import sys
|
||||
from sys import version_info as python_version
|
||||
|
||||
if sys.version_info < (3, 9): ... # OK
|
||||
|
||||
if sys.version_info >= (3, 9): ... # OK
|
||||
|
||||
if sys.version_info == (3, 9): ... # OK
|
||||
|
||||
if sys.version_info == (3, 9): ... # Error: PYI006 Use only `<` and `>=` for version info comparisons
|
||||
|
||||
if sys.version_info <= (3, 10): ... # Error: PYI006 Use only `<` and `>=` for version info comparisons
|
||||
|
||||
if sys.version_info <= (3, 10): ... # Error: PYI006 Use only `<` and `>=` for version info comparisons
|
||||
|
||||
if sys.version_info > (3, 10): ... # Error: PYI006 Use only `<` and `>=` for version info comparisons
|
||||
|
||||
if python_version > (3, 10): ... # Error: PYI006 Use only `<` and `>=` for version info comparisons
|
||||
14
crates/ruff/resources/test/fixtures/flake8_pyi/PYI009.py
vendored
Normal file
14
crates/ruff/resources/test/fixtures/flake8_pyi/PYI009.py
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
def bar():
|
||||
... # OK
|
||||
|
||||
|
||||
def foo():
|
||||
pass # OK, since we're not in a stub file
|
||||
|
||||
|
||||
class Bar:
|
||||
... # OK
|
||||
|
||||
|
||||
class Foo:
|
||||
pass # OK, since we're not in a stub file
|
||||
8
crates/ruff/resources/test/fixtures/flake8_pyi/PYI009.pyi
vendored
Normal file
8
crates/ruff/resources/test/fixtures/flake8_pyi/PYI009.pyi
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
def bar(): ... # OK
|
||||
def foo():
|
||||
pass # ERROR PYI009, since we're in a stub file
|
||||
|
||||
class Bar: ... # OK
|
||||
|
||||
class Foo:
|
||||
pass # ERROR PYI009, since we're in a stub file
|
||||
18
crates/ruff/resources/test/fixtures/flake8_pyi/PYI010.py
vendored
Normal file
18
crates/ruff/resources/test/fixtures/flake8_pyi/PYI010.py
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
def bar():
|
||||
... # OK
|
||||
|
||||
|
||||
def foo():
|
||||
"""foo""" # OK
|
||||
|
||||
|
||||
def buzz():
|
||||
print("buzz") # OK, not in stub file
|
||||
|
||||
|
||||
def foo2():
|
||||
123 # OK, not in a stub file
|
||||
|
||||
|
||||
def bizz():
|
||||
x = 123 # OK, not in a stub file
|
||||
12
crates/ruff/resources/test/fixtures/flake8_pyi/PYI010.pyi
vendored
Normal file
12
crates/ruff/resources/test/fixtures/flake8_pyi/PYI010.pyi
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
def bar(): ... # OK
|
||||
def foo():
|
||||
"""foo""" # OK, strings are handled by another rule
|
||||
|
||||
def buzz():
|
||||
print("buzz") # ERROR PYI010
|
||||
|
||||
def foo2():
|
||||
123 # ERROR PYI010
|
||||
|
||||
def bizz():
|
||||
x = 123 # ERROR PYI010
|
||||
79
crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.py
vendored
Normal file
79
crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.py
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
def f12(
|
||||
x,
|
||||
y: str = os.pathsep, # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f11(*, x: str = "x") -> None: # OK
|
||||
...
|
||||
|
||||
|
||||
def f13(
|
||||
x: list[str] = [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
] # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f14(
|
||||
x: tuple[str, ...] = (
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
) # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f15(
|
||||
x: set[str] = {
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
} # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f16(x: frozenset[bytes] = frozenset({b"foo", b"bar", b"baz"})) -> None: # OK
|
||||
...
|
||||
|
||||
|
||||
def f17(
|
||||
x: str = "foo" + "bar", # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f18(
|
||||
x: str = b"foo" + b"bar", # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f19(
|
||||
x: object = "foo" + 4, # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f20(
|
||||
x: int = 5 + 5, # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f21(
|
||||
x: complex = 3j - 3j, # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f22(
|
||||
x: complex = -42.5j + 4.3j, # OK
|
||||
) -> None:
|
||||
...
|
||||
116
crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.pyi
vendored
Normal file
116
crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.pyi
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
import math
|
||||
import os
|
||||
import sys
|
||||
from math import inf
|
||||
|
||||
import numpy as np
|
||||
|
||||
def f12(
|
||||
x,
|
||||
y: str = os.pathsep, # Error PYI011 Only simple default values allowed for typed arguments
|
||||
) -> None: ...
|
||||
def f11(*, x: str = "x") -> None: ... # OK
|
||||
def f13(
|
||||
x: list[
|
||||
str
|
||||
] = [ # Error PYI011 Only simple default values allowed for typed arguments
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
) -> None: ...
|
||||
def f14(
|
||||
x: tuple[
|
||||
str, ...
|
||||
] = ( # Error PYI011 Only simple default values allowed for typed arguments
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
)
|
||||
) -> None: ...
|
||||
def f15(
|
||||
x: set[
|
||||
str
|
||||
] = { # Error PYI011 Only simple default values allowed for typed arguments
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
}
|
||||
) -> None: ...
|
||||
def f16(
|
||||
x: frozenset[
|
||||
bytes
|
||||
] = frozenset( # Error PYI011 Only simple default values allowed for typed arguments
|
||||
{b"foo", b"bar", b"baz"}
|
||||
)
|
||||
) -> None: ...
|
||||
def f17(
|
||||
x: str = "foo" # Error PYI011 Only simple default values allowed for typed arguments
|
||||
+ "bar",
|
||||
) -> None: ...
|
||||
def f18(
|
||||
x: str = b"foo" # Error PYI011 Only simple default values allowed for typed arguments
|
||||
+ b"bar",
|
||||
) -> None: ...
|
||||
def f19(
|
||||
x: object = "foo" # Error PYI011 Only simple default values allowed for typed arguments
|
||||
+ 4,
|
||||
) -> None: ...
|
||||
def f20(
|
||||
x: int = 5
|
||||
+ 5, # Error PYI011 Only simple default values allowed for typed arguments
|
||||
) -> None: ...
|
||||
def f21(
|
||||
x: complex = 3j
|
||||
- 3j, # Error PYI011 Only simple default values allowed for typed arguments
|
||||
) -> None: ...
|
||||
def f22(
|
||||
x: complex = -42.5j # Error PYI011 Only simple default values allowed for typed arguments
|
||||
+ 4.3j,
|
||||
) -> None: ...
|
||||
def f23(
|
||||
x: bool = True, # OK
|
||||
) -> None: ...
|
||||
def f24(
|
||||
x: float = 3.14, # OK
|
||||
) -> None: ...
|
||||
def f25(
|
||||
x: float = -3.14, # OK
|
||||
) -> None: ...
|
||||
def f26(
|
||||
x: complex = -3.14j, # OK
|
||||
) -> None: ...
|
||||
def f27(
|
||||
x: complex = -3 - 3.14j, # OK
|
||||
) -> None: ...
|
||||
def f28(
|
||||
x: float = math.tau, # OK
|
||||
) -> None: ...
|
||||
def f29(
|
||||
x: float = math.inf, # OK
|
||||
) -> None: ...
|
||||
def f30(
|
||||
x: float = -math.inf, # OK
|
||||
) -> None: ...
|
||||
def f31(
|
||||
x: float = inf, # Error PYI011 Only simple default values allowed for typed arguments
|
||||
) -> None: ...
|
||||
def f32(
|
||||
x: float = np.inf, # Error PYI011 Only simple default values allowed for typed arguments
|
||||
) -> None: ...
|
||||
def f33(
|
||||
x: float = math.nan, # OK
|
||||
) -> None: ...
|
||||
def f34(
|
||||
x: float = -math.nan, # Error PYI011 Only simple default values allowed for typed arguments
|
||||
) -> None: ...
|
||||
def f35(
|
||||
x: complex = math.inf # Error PYI011 Only simple default values allowed for typed arguments
|
||||
+ 1j,
|
||||
) -> None: ...
|
||||
def f36(
|
||||
*, x: str = sys.version, # OK
|
||||
) -> None: ...
|
||||
def f37(
|
||||
*, x: str = "" + "", # Error PYI011 Only simple default values allowed for typed arguments
|
||||
) -> None: ...
|
||||
79
crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.py
vendored
Normal file
79
crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.py
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
def f12(
|
||||
x,
|
||||
y=os.pathsep, # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f11(*, x="x") -> None:
|
||||
... # OK
|
||||
|
||||
|
||||
def f13(
|
||||
x=[ # OK
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f14(
|
||||
x=( # OK
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
)
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f15(
|
||||
x={ # OK
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
}
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f16(x=frozenset({b"foo", b"bar", b"baz"})) -> None:
|
||||
... # OK
|
||||
|
||||
|
||||
def f17(
|
||||
x="foo" + "bar", # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f18(
|
||||
x=b"foo" + b"bar", # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f19(
|
||||
x="foo" + 4, # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f20(
|
||||
x=5 + 5, # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f21(
|
||||
x=3j - 3j, # OK
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f22(
|
||||
x=-42.5j + 4.3j, # OK
|
||||
) -> None:
|
||||
...
|
||||
48
crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.pyi
vendored
Normal file
48
crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.pyi
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
def f12(
|
||||
x,
|
||||
y=os.pathsep, # Error PYI014
|
||||
) -> None: ...
|
||||
def f11(*, x="x") -> None: ... # OK
|
||||
def f13(
|
||||
x=[ # Error PYI014
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
) -> None: ...
|
||||
def f14(
|
||||
x=( # Error PYI014
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
)
|
||||
) -> None: ...
|
||||
def f15(
|
||||
x={ # Error PYI014
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
}
|
||||
) -> None: ...
|
||||
def f16(x=frozenset({b"foo", b"bar", b"baz"})) -> None: ... # Error PYI014
|
||||
def f17(
|
||||
x="foo" + "bar", # Error PYI014
|
||||
) -> None: ...
|
||||
def f18(
|
||||
x=b"foo" + b"bar", # Error PYI014
|
||||
) -> None: ...
|
||||
def f19(
|
||||
x="foo" + 4, # Error PYI014
|
||||
) -> None: ...
|
||||
def f20(
|
||||
x=5 + 5, # Error PYI014
|
||||
) -> None: ...
|
||||
def f21(
|
||||
x=3j - 3j, # Error PYI014
|
||||
) -> None: ...
|
||||
def f22(
|
||||
x=-42.5j + 4.3j, # Error PYI014
|
||||
) -> None: ...
|
||||
def f23(
|
||||
x=True, # OK
|
||||
) -> None: ...
|
||||
14
crates/ruff/resources/test/fixtures/flake8_pyi/PYI021.py
vendored
Normal file
14
crates/ruff/resources/test/fixtures/flake8_pyi/PYI021.py
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
"""foo""" # OK, not in stub
|
||||
|
||||
|
||||
def foo():
|
||||
"""foo""" # OK, doc strings are allowed in non-stubs
|
||||
|
||||
|
||||
class Bar:
|
||||
"""bar""" # OK, doc strings are allowed in non-stubs
|
||||
|
||||
|
||||
def bar():
|
||||
x = 1
|
||||
"""foo""" # OK, not a doc string
|
||||
11
crates/ruff/resources/test/fixtures/flake8_pyi/PYI021.pyi
vendored
Normal file
11
crates/ruff/resources/test/fixtures/flake8_pyi/PYI021.pyi
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
"""foo""" # ERROR PYI021
|
||||
|
||||
def foo():
|
||||
"""foo""" # ERROR PYI021
|
||||
|
||||
class Bar:
|
||||
"""bar""" # ERROR PYI021
|
||||
|
||||
def bar():
|
||||
x = 1
|
||||
"""foo""" # OK, not a doc string
|
||||
33
crates/ruff/resources/test/fixtures/flake8_pyi/PYI033.py
vendored
Normal file
33
crates/ruff/resources/test/fixtures/flake8_pyi/PYI033.py
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# From https://github.com/PyCQA/flake8-pyi/blob/4212bec43dbc4020a59b90e2957c9488575e57ba/tests/type_comments.pyi
|
||||
|
||||
from collections.abc import Sequence
|
||||
from typing import TypeAlias
|
||||
|
||||
A: TypeAlias = None # type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
B: TypeAlias = None # type: str # And here's an extra comment about why it's that type # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
C: TypeAlias = None #type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
D: TypeAlias = None # type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
E: TypeAlias = None# type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
F: TypeAlias = None#type:int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
|
||||
def func(
|
||||
arg1, # type: dict[str, int] # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
arg2 # type: Sequence[bytes] # And here's some more info about this arg # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
): ...
|
||||
|
||||
class Foo:
|
||||
Attr: TypeAlias = None # type: set[str] # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
|
||||
G: TypeAlias = None # type: ignore
|
||||
H: TypeAlias = None # type: ignore[attr-defined]
|
||||
I: TypeAlias = None #type: ignore
|
||||
J: TypeAlias = None # type: ignore
|
||||
K: TypeAlias = None# type: ignore
|
||||
L: TypeAlias = None#type:ignore
|
||||
|
||||
# Whole line commented out # type: int
|
||||
M: TypeAlias = None # type: can't parse me!
|
||||
|
||||
class Bar:
|
||||
N: TypeAlias = None # type: can't parse me either!
|
||||
# This whole line is commented out and indented # type: str
|
||||
33
crates/ruff/resources/test/fixtures/flake8_pyi/PYI033.pyi
vendored
Normal file
33
crates/ruff/resources/test/fixtures/flake8_pyi/PYI033.pyi
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# From https://github.com/PyCQA/flake8-pyi/blob/4212bec43dbc4020a59b90e2957c9488575e57ba/tests/type_comments.pyi
|
||||
|
||||
from collections.abc import Sequence
|
||||
from typing import TypeAlias
|
||||
|
||||
A: TypeAlias = None # type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
B: TypeAlias = None # type: str # And here's an extra comment about why it's that type # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
C: TypeAlias = None #type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
D: TypeAlias = None # type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
E: TypeAlias = None# type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
F: TypeAlias = None#type:int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
|
||||
def func(
|
||||
arg1, # type: dict[str, int] # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
arg2 # type: Sequence[bytes] # And here's some more info about this arg # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
): ...
|
||||
|
||||
class Foo:
|
||||
Attr: TypeAlias = None # type: set[str] # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
|
||||
|
||||
G: TypeAlias = None # type: ignore
|
||||
H: TypeAlias = None # type: ignore[attr-defined]
|
||||
I: TypeAlias = None #type: ignore
|
||||
J: TypeAlias = None # type: ignore
|
||||
K: TypeAlias = None# type: ignore
|
||||
L: TypeAlias = None#type:ignore
|
||||
|
||||
# Whole line commented out # type: int
|
||||
M: TypeAlias = None # type: can't parse me!
|
||||
|
||||
class Bar:
|
||||
N: TypeAlias = None # type: can't parse me either!
|
||||
# This whole line is commented out and indented # type: str
|
||||
@@ -17,6 +17,12 @@ class Test(unittest.TestCase):
|
||||
self.assertTrue(**{"expr": expr, "msg": msg}) # Error, unfixable
|
||||
self.assertTrue(msg=msg, expr=expr, unexpected_arg=False) # Error, unfixable
|
||||
self.assertTrue(msg=msg) # Error, unfixable
|
||||
(
|
||||
self.assertIsNotNone(value) # Error, unfixable
|
||||
if expect_condition
|
||||
else self.assertIsNone(value) # Error, unfixable
|
||||
)
|
||||
return self.assertEqual(True, False) # Error, unfixable
|
||||
|
||||
def test_assert_false(self):
|
||||
self.assertFalse(True) # Error
|
||||
|
||||
@@ -6,6 +6,8 @@ def test_ok():
|
||||
assert something or something_else
|
||||
assert something or something_else and something_third
|
||||
assert not (something and something_else)
|
||||
assert something, "something message"
|
||||
assert something or something_else and something_third, "another message"
|
||||
|
||||
|
||||
def test_error():
|
||||
@@ -13,6 +15,27 @@ def test_error():
|
||||
assert something and something_else and something_third
|
||||
assert something and not something_else
|
||||
assert something and (something_else or something_third)
|
||||
assert not something and something_else
|
||||
assert not (something or something_else)
|
||||
assert not (something or something_else or something_third)
|
||||
assert something and something_else == """error
|
||||
message
|
||||
"""
|
||||
|
||||
# recursive case
|
||||
assert not (a or not (b or c))
|
||||
assert not (a or not (b and c))
|
||||
|
||||
# detected, but no autofix for messages
|
||||
assert something and something_else, "error message"
|
||||
assert not (something or something_else and something_third), "with message"
|
||||
# detected, but no autofix for mixed conditions (e.g. `a or b and c`)
|
||||
assert not (something or something_else and something_third)
|
||||
# detected, but no autofix for parenthesized conditions
|
||||
assert (
|
||||
something
|
||||
and something_else
|
||||
== """error
|
||||
message
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -3,6 +3,8 @@ import os
|
||||
import posix
|
||||
from posix import abort
|
||||
import sys as std_sys
|
||||
import typing
|
||||
import typing_extensions
|
||||
import _thread
|
||||
import _winapi
|
||||
|
||||
@@ -77,7 +79,7 @@ def x(y):
|
||||
|
||||
# last line in while loop
|
||||
def x(y):
|
||||
while True:
|
||||
while i > 0:
|
||||
if y > 0:
|
||||
return 1
|
||||
y += 1
|
||||
@@ -211,6 +213,18 @@ def noreturn_sys_exit():
|
||||
std_sys.exit(0)
|
||||
|
||||
|
||||
def noreturn_typing_assert_never():
|
||||
if x > 0:
|
||||
return 1
|
||||
typing.assert_never(0)
|
||||
|
||||
|
||||
def noreturn_typing_extensions_assert_never():
|
||||
if x > 0:
|
||||
return 1
|
||||
typing_extensions.assert_never(0)
|
||||
|
||||
|
||||
def noreturn__thread_exit():
|
||||
if x > 0:
|
||||
return 1
|
||||
@@ -251,3 +265,58 @@ def noreturn_pytest_xfail_2():
|
||||
if x > 0:
|
||||
return 1
|
||||
py_xfail("oof")
|
||||
|
||||
|
||||
def nested(values):
|
||||
if not values:
|
||||
return False
|
||||
|
||||
for value in values:
|
||||
print(value)
|
||||
|
||||
|
||||
def while_true():
|
||||
while True:
|
||||
if y > 0:
|
||||
return 1
|
||||
y += 1
|
||||
|
||||
|
||||
# match
|
||||
def x(y):
|
||||
match y:
|
||||
case 0:
|
||||
return 1
|
||||
case 1:
|
||||
print() # error
|
||||
|
||||
|
||||
def foo(baz: str) -> str:
|
||||
return baz
|
||||
|
||||
|
||||
def end_of_statement():
|
||||
def example():
|
||||
if True:
|
||||
return ""
|
||||
|
||||
|
||||
def example():
|
||||
if True:
|
||||
return ""
|
||||
|
||||
|
||||
def example():
|
||||
if True:
|
||||
return "" # type: ignore
|
||||
|
||||
|
||||
def example():
|
||||
if True:
|
||||
return "" ;
|
||||
|
||||
|
||||
def example():
|
||||
if True:
|
||||
return "" \
|
||||
; # type: ignore
|
||||
|
||||
@@ -6,22 +6,6 @@ def x():
|
||||
return a # error
|
||||
|
||||
|
||||
def x():
|
||||
a = 1
|
||||
print(a)
|
||||
a = 2
|
||||
return a # error
|
||||
|
||||
|
||||
def x():
|
||||
a = 1
|
||||
if True:
|
||||
return a # error
|
||||
a = 2
|
||||
print(a)
|
||||
return a
|
||||
|
||||
|
||||
# Can be refactored false positives
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issuecomment-1122571066
|
||||
def get_bar_if_exists(obj):
|
||||
@@ -165,44 +149,6 @@ def my_func():
|
||||
return foo
|
||||
|
||||
|
||||
# Refactored incorrect false positives
|
||||
# See test cases above marked: "Can be refactored false positives"
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issuecomment-1122571066
|
||||
def get_bar_if_exists(obj):
|
||||
if hasattr(obj, "bar"):
|
||||
return str(obj.bar)
|
||||
return ""
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issue-641117366
|
||||
def x():
|
||||
formatted = _USER_AGENT_FORMATTER.format(format_string, **values)
|
||||
# clean up after any blank components
|
||||
return formatted.replace("()", "").replace(" ", " ").strip()
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issue-641117366
|
||||
def user_agent_username(username=None):
|
||||
|
||||
if not username:
|
||||
return ""
|
||||
|
||||
username = username.replace(" ", "_") # Avoid spaces or %20.
|
||||
try:
|
||||
username.encode("ascii") # just test,
|
||||
# but not actually use it
|
||||
except UnicodeEncodeError:
|
||||
username = quote(username.encode("utf-8"))
|
||||
else:
|
||||
# % is legal in the default $wgLegalTitleChars
|
||||
# This is so that ops know the real pywikibot will not
|
||||
# allow a useragent in the username to allow through a
|
||||
# hand-coded percent-encoded value.
|
||||
if "%" in username:
|
||||
username = quote(username)
|
||||
return username
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/116#issue-1367575481
|
||||
def no_exception_loop():
|
||||
success = False
|
||||
@@ -260,3 +206,44 @@ def nonlocal_assignment():
|
||||
nonlocal X
|
||||
X = 1
|
||||
return X
|
||||
|
||||
|
||||
def decorator() -> Flask:
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/hello')
|
||||
def hello() -> str:
|
||||
"""Hello endpoint."""
|
||||
return 'Hello, World!'
|
||||
|
||||
return app
|
||||
|
||||
|
||||
def default():
|
||||
y = 1
|
||||
|
||||
def f(x = y) -> X:
|
||||
return x
|
||||
|
||||
return y
|
||||
|
||||
|
||||
def get_queryset(option_1, option_2):
|
||||
queryset: Any = None
|
||||
queryset = queryset.filter(a=1)
|
||||
if option_1:
|
||||
queryset = queryset.annotate(b=Value(2))
|
||||
if option_2:
|
||||
queryset = queryset.filter(c=3)
|
||||
return queryset
|
||||
|
||||
|
||||
def get_queryset():
|
||||
queryset = Model.filter(a=1)
|
||||
queryset = queryset.filter(c=3)
|
||||
return queryset
|
||||
|
||||
|
||||
def get_queryset():
|
||||
queryset = Model.filter(a=1)
|
||||
return queryset # error
|
||||
|
||||
@@ -136,3 +136,24 @@ def nested2(x, y, z):
|
||||
break
|
||||
else:
|
||||
a = z
|
||||
|
||||
|
||||
def elif1(x, y, w, z):
|
||||
for i in x:
|
||||
if i > y:
|
||||
a = z
|
||||
elif i > w:
|
||||
break
|
||||
else:
|
||||
a = z
|
||||
|
||||
|
||||
def elif2(x, y, w, z):
|
||||
for i in x:
|
||||
if i > y:
|
||||
a = z
|
||||
else:
|
||||
if i > w:
|
||||
break
|
||||
else:
|
||||
a = z
|
||||
|
||||
@@ -35,6 +35,13 @@ class Foo(metaclass=BazMeta):
|
||||
return None
|
||||
if self.bar()._private: # SLF001
|
||||
return None
|
||||
if Bar._private_thing: # SLF001
|
||||
return None
|
||||
if Foo._private_thing:
|
||||
return None
|
||||
Foo = Bar()
|
||||
if Foo._private_thing: # SLF001
|
||||
return None
|
||||
return self.bar
|
||||
|
||||
def public_func(self):
|
||||
@@ -49,15 +56,17 @@ class Foo(metaclass=BazMeta):
|
||||
|
||||
foo = Foo()
|
||||
|
||||
print(foo.public_thing)
|
||||
print(foo.public_func())
|
||||
print(foo.__dict__)
|
||||
print(foo.__str__())
|
||||
print(foo().__class__)
|
||||
|
||||
print(foo._private_thing) # SLF001
|
||||
print(foo.__really_private_thing) # SLF001
|
||||
print(foo._private_func()) # SLF001
|
||||
print(foo.__really_private_func(1)) # SLF001
|
||||
print(foo.bar._private) # SLF001
|
||||
print(foo()._private_thing) # SLF001
|
||||
print(foo()._private_thing__) # SLF001
|
||||
|
||||
print(foo.public_thing)
|
||||
print(foo.public_func())
|
||||
print(foo.__dict__)
|
||||
print(foo.__str__())
|
||||
print(foo().__class__)
|
||||
print(foo._asdict())
|
||||
|
||||
86
crates/ruff/resources/test/fixtures/flake8_simplify/SIM116.py
vendored
Normal file
86
crates/ruff/resources/test/fixtures/flake8_simplify/SIM116.py
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
# Errors
|
||||
a = "hello"
|
||||
|
||||
# SIM116
|
||||
if a == "foo":
|
||||
return "bar"
|
||||
elif a == "bar":
|
||||
return "baz"
|
||||
elif a == "boo":
|
||||
return "ooh"
|
||||
else:
|
||||
return 42
|
||||
|
||||
# SIM116
|
||||
if a == 1:
|
||||
return (1, 2, 3)
|
||||
elif a == 2:
|
||||
return (4, 5, 6)
|
||||
elif a == 3:
|
||||
return (7, 8, 9)
|
||||
else:
|
||||
return (10, 11, 12)
|
||||
|
||||
# SIM116
|
||||
if a == 1:
|
||||
return (1, 2, 3)
|
||||
elif a == 2:
|
||||
return (4, 5, 6)
|
||||
elif a == 3:
|
||||
return (7, 8, 9)
|
||||
|
||||
# SIM116
|
||||
if a == "hello 'sir'":
|
||||
return (1, 2, 3)
|
||||
elif a == 'goodbye "mam"':
|
||||
return (4, 5, 6)
|
||||
elif a == """Fairwell 'mister'""":
|
||||
return (7, 8, 9)
|
||||
else:
|
||||
return (10, 11, 12)
|
||||
|
||||
# SIM116
|
||||
if a == b"one":
|
||||
return 1
|
||||
elif a == b"two":
|
||||
return 2
|
||||
elif a == b"three":
|
||||
return 3
|
||||
|
||||
# SIM116
|
||||
if a == "hello 'sir'":
|
||||
return ("hello'", 'hi"', 3)
|
||||
elif a == 'goodbye "mam"':
|
||||
return (4, 5, 6)
|
||||
elif a == """Fairwell 'mister'""":
|
||||
return (7, 8, 9)
|
||||
else:
|
||||
return (10, 11, 12)
|
||||
|
||||
# OK
|
||||
if a == "foo":
|
||||
return "bar"
|
||||
elif a == "bar":
|
||||
return baz()
|
||||
elif a == "boo":
|
||||
return "ooh"
|
||||
else:
|
||||
return 42
|
||||
|
||||
# OK
|
||||
if a == b"one":
|
||||
return 1
|
||||
elif b == b"two":
|
||||
return 2
|
||||
elif a == b"three":
|
||||
return 3
|
||||
|
||||
# SIM116
|
||||
if func_name == "create":
|
||||
return "A"
|
||||
elif func_name == "modify":
|
||||
return "M"
|
||||
elif func_name == "remove":
|
||||
return "D"
|
||||
elif func_name == "move":
|
||||
return "MV"
|
||||
@@ -6,11 +6,14 @@
|
||||
"yoda" <= compare # SIM300
|
||||
"yoda" < compare # SIM300
|
||||
42 > age # SIM300
|
||||
-42 > age # SIM300
|
||||
+42 > age # SIM300
|
||||
YODA == age # SIM300
|
||||
YODA > age # SIM300
|
||||
YODA >= age # SIM300
|
||||
JediOrder.YODA == age # SIM300
|
||||
0 < (number - 100) # SIM300
|
||||
SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
|
||||
|
||||
# OK
|
||||
compare == "yoda"
|
||||
|
||||
@@ -18,8 +18,6 @@ from \
|
||||
..parent\
|
||||
import \
|
||||
world_hello
|
||||
|
||||
# TID252 (without autofix; too many levels up)
|
||||
from ..... import ultragrantparent
|
||||
from ...... import ultragrantparent
|
||||
from ....... import ultragrantparent
|
||||
|
||||
0
crates/ruff/resources/test/fixtures/flake8_tidy_imports/TID252/my_package/__init__.py
vendored
Normal file
0
crates/ruff/resources/test/fixtures/flake8_tidy_imports/TID252/my_package/__init__.py
vendored
Normal file
0
crates/ruff/resources/test/fixtures/flake8_tidy_imports/TID252/my_package/sublib/__init__.py
vendored
Normal file
0
crates/ruff/resources/test/fixtures/flake8_tidy_imports/TID252/my_package/sublib/__init__.py
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
from typing import TYPE_CHECKING, Any, ClassVar
|
||||
|
||||
import attrs
|
||||
|
||||
from ....import unknown
|
||||
from ..protocol import commands, definitions, responses
|
||||
from ..server import example
|
||||
from .. import server
|
||||
from . import logger, models
|
||||
10
crates/ruff/resources/test/fixtures/flake8_type_checking/TCH004_13.py
vendored
Normal file
10
crates/ruff/resources/test/fixtures/flake8_type_checking/TCH004_13.py
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Final, Literal, TypeAlias
|
||||
|
||||
RatingKey: TypeAlias = Literal["good", "fair", "poor"]
|
||||
|
||||
RATING_KEYS: Final[tuple[RatingKey, ...]] = ("good", "fair", "poor")
|
||||
3
crates/ruff/resources/test/fixtures/flake8_type_checking/TCH004_14.pyi
vendored
Normal file
3
crates/ruff/resources/test/fixtures/flake8_type_checking/TCH004_14.pyi
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from typing import Tuple
|
||||
|
||||
x: Tuple
|
||||
38
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_1.py
vendored
Normal file
38
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_1.py
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pydantic
|
||||
from pydantic import BaseModel
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import datetime # TCH004
|
||||
from array import array # TCH004
|
||||
|
||||
import pandas # TCH004
|
||||
import pyproj
|
||||
|
||||
|
||||
class A(pydantic.BaseModel):
|
||||
x: datetime.datetime
|
||||
|
||||
|
||||
class B(BaseModel):
|
||||
x: pandas.DataFrame
|
||||
|
||||
|
||||
class C(BaseModel):
|
||||
x: pathlib.Path
|
||||
|
||||
|
||||
class E:
|
||||
pass
|
||||
|
||||
|
||||
class F(E):
|
||||
x: pyproj.Transformer
|
||||
|
||||
|
||||
class G(BaseModel):
|
||||
x: array
|
||||
28
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_2.py
vendored
Normal file
28
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_2.py
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import geopandas as gpd # TCH002
|
||||
import pydantic
|
||||
import pyproj # TCH002
|
||||
from pydantic import BaseModel
|
||||
|
||||
import numpy
|
||||
|
||||
|
||||
class A(BaseModel):
|
||||
x: pandas.DataFrame
|
||||
|
||||
|
||||
class B(pydantic.BaseModel):
|
||||
x: numpy.ndarray
|
||||
|
||||
|
||||
class C:
|
||||
pass
|
||||
|
||||
|
||||
class D(C):
|
||||
x: pyproj.Transformer
|
||||
|
||||
|
||||
class E(C):
|
||||
x: gpd.GeoDataFrame
|
||||
24
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py
vendored
Normal file
24
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import pathlib
|
||||
from uuid import UUID # TCH003
|
||||
|
||||
import pydantic
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class A(pydantic.BaseModel):
|
||||
x: datetime.datetime
|
||||
|
||||
|
||||
class B(BaseModel):
|
||||
x: pathlib.Path
|
||||
|
||||
|
||||
class C:
|
||||
pass
|
||||
|
||||
|
||||
class D(C):
|
||||
x: UUID
|
||||
46
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_1.py
vendored
Normal file
46
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_1.py
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import attrs
|
||||
from attrs import frozen
|
||||
|
||||
import numpy
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import datetime # TCH004
|
||||
from array import array # TCH004
|
||||
|
||||
import pandas # TCH004
|
||||
import pyproj
|
||||
|
||||
|
||||
@attrs.define(auto_attribs=True)
|
||||
class A:
|
||||
x: datetime.datetime
|
||||
|
||||
|
||||
@attrs.define
|
||||
class B:
|
||||
x: pandas.DataFrame
|
||||
|
||||
|
||||
@frozen(auto_attribs=True)
|
||||
class C:
|
||||
x: pathlib.Path
|
||||
|
||||
|
||||
@frozen
|
||||
class D:
|
||||
x: array
|
||||
|
||||
|
||||
@dataclass
|
||||
class E:
|
||||
x: pyproj.Transformer
|
||||
|
||||
|
||||
@attrs.define
|
||||
class F:
|
||||
x: numpy.ndarray
|
||||
30
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_2.py
vendored
Normal file
30
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_2.py
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
import attrs
|
||||
import pandas
|
||||
import pyproj
|
||||
from attrs import frozen
|
||||
|
||||
import numpy # TCH002
|
||||
|
||||
|
||||
@attrs.define(auto_attribs=True)
|
||||
class A:
|
||||
x: pyproj.Transformer
|
||||
|
||||
|
||||
@attrs.define
|
||||
class B:
|
||||
x: pandas.DataFrame
|
||||
|
||||
|
||||
@frozen
|
||||
class C:
|
||||
x: pandas.DataFrame
|
||||
|
||||
|
||||
@dataclass
|
||||
class D:
|
||||
x: numpy.ndarray
|
||||
24
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_3.py
vendored
Normal file
24
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_3.py
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
from array import array
|
||||
from dataclasses import dataclass
|
||||
from uuid import UUID # TCH003
|
||||
|
||||
import attrs
|
||||
from attrs import frozen
|
||||
|
||||
|
||||
@attrs.define(auto_attribs=True)
|
||||
class A:
|
||||
x: datetime.datetime
|
||||
|
||||
|
||||
@frozen
|
||||
class B:
|
||||
x: array
|
||||
|
||||
|
||||
@dataclass
|
||||
class C:
|
||||
x: UUID
|
||||
15
crates/ruff/resources/test/fixtures/isort/as_imports_comments.py
vendored
Normal file
15
crates/ruff/resources/test/fixtures/isort/as_imports_comments.py
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
from foo import ( # Comment on `foo`
|
||||
Member as Alias, # Comment on `Alias`
|
||||
)
|
||||
|
||||
from bar import ( # Comment on `bar`
|
||||
Member, # Comment on `Member`
|
||||
)
|
||||
|
||||
from baz import ( # Comment on `baz`
|
||||
Member as Alias # Comment on `Alias`
|
||||
)
|
||||
|
||||
from bop import ( # Comment on `bop`
|
||||
Member # Comment on `Member`
|
||||
)
|
||||
@@ -1,5 +1,10 @@
|
||||
import sys, math
|
||||
from os import path, uname
|
||||
from json import detect_encoding
|
||||
from json import dump
|
||||
from json import dumps as json_dumps
|
||||
from json import load
|
||||
from json import loads as json_loads
|
||||
from logging.handlers import StreamHandler, FileHandler
|
||||
|
||||
# comment 1
|
||||
@@ -10,9 +15,10 @@ from third_party import lib4
|
||||
|
||||
from foo import bar # comment 3
|
||||
from foo2 import bar2 # comment 4
|
||||
from foo3 import bar3, baz3 # comment 5
|
||||
|
||||
# comment 5
|
||||
# comment 6
|
||||
from bar import (
|
||||
a, # comment 6
|
||||
b, # comment 7
|
||||
)
|
||||
a, # comment 7
|
||||
b, # comment 8
|
||||
)
|
||||
|
||||
@@ -2,7 +2,9 @@ from a import a1 # import_from
|
||||
from c import * # import_from_star
|
||||
import a # import
|
||||
import c.d
|
||||
from z import z1
|
||||
import b as b1 # import_as
|
||||
import z
|
||||
|
||||
from ..parent import *
|
||||
from .my import fn
|
||||
|
||||
23
crates/ruff/resources/test/fixtures/isort/force_to_top.py
vendored
Normal file
23
crates/ruff/resources/test/fixtures/isort/force_to_top.py
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import lib6
|
||||
import lib2
|
||||
import lib5
|
||||
import lib1
|
||||
import lib3
|
||||
import lib4
|
||||
|
||||
import foo
|
||||
import z
|
||||
from foo import bar
|
||||
from lib1 import foo
|
||||
from lib2 import foo
|
||||
from lib1.lib2 import foo
|
||||
from foo.lib1.bar import baz
|
||||
from lib4 import lib1
|
||||
from lib5 import lib2
|
||||
from lib4 import lib2
|
||||
from lib5 import lib1
|
||||
|
||||
import lib3.lib4
|
||||
import lib3.lib4.lib5
|
||||
from lib3.lib4 import foo
|
||||
from lib3.lib4.lib5 import foo
|
||||
@@ -1,2 +1,2 @@
|
||||
from long_module_name import member_one, member_two, member_three, member_four, member_five
|
||||
from long_module_name import member_one, member_two, member_three, member_four, member_five
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user