Compare commits
117 Commits
zanie/rule
...
string-pre
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d2513e5a9 | ||
|
|
272306bf5a | ||
|
|
f8f1cd5016 | ||
|
|
87a0cd219f | ||
|
|
b685ee4749 | ||
|
|
ad893f8295 | ||
|
|
621bed55c0 | ||
|
|
86faee1522 | ||
|
|
a0917ec658 | ||
|
|
ee9ee005c5 | ||
|
|
5df0326bc8 | ||
|
|
6540321966 | ||
|
|
b34278e0cd | ||
|
|
222f1c37b8 | ||
|
|
8f41eab0c7 | ||
|
|
83daddbeb7 | ||
|
|
b19eec9b2a | ||
|
|
ca3c15858d | ||
|
|
bb4f7c681a | ||
|
|
0a167dd20b | ||
|
|
c43542896f | ||
|
|
192463c2fb | ||
|
|
5849a75223 | ||
|
|
dcbd8eacd8 | ||
|
|
297ec2c2d2 | ||
|
|
511cc25fc4 | ||
|
|
4c4eceee36 | ||
|
|
e07670ad97 | ||
|
|
b792140579 | ||
|
|
36a60bd50e | ||
|
|
4ae463d04b | ||
|
|
6dade5b9ab | ||
|
|
97510c888b | ||
|
|
94b68f201b | ||
|
|
ef34c5cbec | ||
|
|
fdbefd777c | ||
|
|
078547adbb | ||
|
|
42a0bec146 | ||
|
|
37b7d0f921 | ||
|
|
6a4dbd622b | ||
|
|
28b48ab902 | ||
|
|
4123d074bd | ||
|
|
c6ba7dfbc6 | ||
|
|
40f6456add | ||
|
|
3e1dffab20 | ||
|
|
3336d23f48 | ||
|
|
2421805033 | ||
|
|
359f50e6dc | ||
|
|
bccba5d73f | ||
|
|
0bfdb15ecf | ||
|
|
a902d14c31 | ||
|
|
728539291f | ||
|
|
c2bd8af59a | ||
|
|
c946bf157e | ||
|
|
8ab2519717 | ||
|
|
c4d85d6fb6 | ||
|
|
70ea49bf72 | ||
|
|
8e255974bc | ||
|
|
d358604464 | ||
|
|
8243db74fe | ||
|
|
0346e781d4 | ||
|
|
b66bfa6570 | ||
|
|
28273eb00b | ||
|
|
12acd191e1 | ||
|
|
64b929bc29 | ||
|
|
26ae0a6e8d | ||
|
|
959338d39d | ||
|
|
422ff82f4a | ||
|
|
8d0a5e01bd | ||
|
|
aae02cf275 | ||
|
|
7e2eba2592 | ||
|
|
22770fb4be | ||
|
|
1880cceac1 | ||
|
|
0d1fb823d6 | ||
|
|
c907317199 | ||
|
|
916dd5b7fa | ||
|
|
2cbe1733c8 | ||
|
|
1f6e1485f9 | ||
|
|
9b43162cc4 | ||
|
|
cc9e84c144 | ||
|
|
f4d50a2aec | ||
|
|
0c030b5bf3 | ||
|
|
1b082ce67e | ||
|
|
f936d319cc | ||
|
|
85d8b6228f | ||
|
|
7594dadc1d | ||
|
|
de37fbfac9 | ||
|
|
4e2769a16c | ||
|
|
75b5c314e3 | ||
|
|
450fb9b99a | ||
|
|
6163c99551 | ||
|
|
3112202a5b | ||
|
|
64ea00048b | ||
|
|
067a4acd54 | ||
|
|
c88376f468 | ||
|
|
9b7c29853d | ||
|
|
3e21d32b79 | ||
|
|
f9e3ea23ba | ||
|
|
6856d0b44b | ||
|
|
21539f1663 | ||
|
|
b9bb6bf780 | ||
|
|
d39eae2713 | ||
|
|
5d21b9c22e | ||
|
|
ec2f229a45 | ||
|
|
34c1cb7d11 | ||
|
|
2ddea7c657 | ||
|
|
45eabdd2c3 | ||
|
|
675c86c175 | ||
|
|
1f8e2b8f14 | ||
|
|
58b3040342 | ||
|
|
6a9b8aede1 | ||
|
|
f48126ad00 | ||
|
|
11287f944f | ||
|
|
a65efcf459 | ||
|
|
04183b0299 | ||
|
|
36fa1fe359 | ||
|
|
6e625bd93d |
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -1,7 +1,7 @@
|
||||
* 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
|
||||
crates/ruff_linter/resources/test/fixtures/isort/line_ending_crlf.py text eol=crlf
|
||||
crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_1.py text eol=crlf
|
||||
|
||||
ruff.schema.json linguist-generated=true text=auto eol=lf
|
||||
*.md.snap linguist-language=Markdown
|
||||
|
||||
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -6,4 +6,4 @@
|
||||
# - Order is important. The last matching pattern has the most precedence.
|
||||
|
||||
# Jupyter
|
||||
/crates/ruff/src/jupyter/ @dhruvmanila
|
||||
/crates/ruff_linter/src/jupyter/ @dhruvmanila
|
||||
|
||||
2
.github/workflows/docs.yaml
vendored
2
.github/workflows/docs.yaml
vendored
@@ -52,4 +52,4 @@ jobs:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
# `github.head_ref` is only set during pull requests and for manual runs or tags we use `main` to deploy to production
|
||||
command: pages deploy site --project-name=ruff-docs --branch ${{ github.head_ref || 'main' }} --commit-hash ${GITHUB_SHA}
|
||||
command: pages deploy site --project-name=astral-docs --branch ${{ github.head_ref || 'main' }} --commit-hash ${GITHUB_SHA}
|
||||
|
||||
2
.github/workflows/playground.yaml
vendored
2
.github/workflows/playground.yaml
vendored
@@ -44,4 +44,4 @@ jobs:
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
command: pages publish playground/dist --project-name=ruff --branch ${GITHUB_HEAD_REF} --commit-hash ${GITHUB_SHA}
|
||||
command: pages deploy playground/dist --project-name=ruff-playground --branch ${GITHUB_HEAD_REF} --commit-hash ${GITHUB_SHA}
|
||||
|
||||
30
.github/workflows/release.yaml
vendored
30
.github/workflows/release.yaml
vendored
@@ -419,18 +419,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.sha }}
|
||||
- name: Check tag consistency
|
||||
run: |
|
||||
version=$(grep "version = " pyproject.toml | sed -e 's/version = "\(.*\)"/\1/g')
|
||||
if [ "${{ inputs.tag }}" != "${version}" ]; then
|
||||
echo "The input tag does not match the version from pyproject.toml:" >&2
|
||||
echo "${{ inputs.tag }}" >&2
|
||||
echo "${version}" >&2
|
||||
exit 1
|
||||
else
|
||||
echo "Releasing ${version}"
|
||||
fi
|
||||
ref: main # We checkout the main branch to check for the commit
|
||||
- name: Check main branch
|
||||
if: ${{ inputs.sha }}
|
||||
run: |
|
||||
@@ -440,17 +429,18 @@ jobs:
|
||||
echo "The specified sha is not on the main branch" >&2
|
||||
exit 1
|
||||
fi
|
||||
- name: Check SHA consistency
|
||||
if: ${{ inputs.sha }}
|
||||
- name: Check tag consistency
|
||||
run: |
|
||||
git_sha=$(git rev-parse HEAD)
|
||||
if [ "${{ inputs.sha }}" != "${git_sha}" ]; then
|
||||
echo "The specified sha does not match the git checkout" >&2
|
||||
echo "${{ inputs.sha }}" >&2
|
||||
echo "${git_sha}" >&2
|
||||
# Switch to the commit we want to release
|
||||
git checkout ${{ inputs.sha }}
|
||||
version=$(grep "version = " pyproject.toml | sed -e 's/version = "\(.*\)"/\1/g')
|
||||
if [ "${{ inputs.tag }}" != "${version}" ]; then
|
||||
echo "The input tag does not match the version from pyproject.toml:" >&2
|
||||
echo "${{ inputs.tag }}" >&2
|
||||
echo "${version}" >&2
|
||||
exit 1
|
||||
else
|
||||
echo "Releasing ${git_sha}"
|
||||
echo "Releasing ${version}"
|
||||
fi
|
||||
|
||||
upload-release:
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
# Benchmarking cpython (CONTRIBUTING.md)
|
||||
crates/ruff/resources/test/cpython
|
||||
crates/ruff_linter/resources/test/cpython
|
||||
# generate_mkdocs.py
|
||||
mkdocs.generated.yml
|
||||
# check_ecosystem.py
|
||||
|
||||
@@ -2,8 +2,8 @@ fail_fast: true
|
||||
|
||||
exclude: |
|
||||
(?x)^(
|
||||
crates/ruff/resources/.*|
|
||||
crates/ruff/src/rules/.*/snapshots/.*|
|
||||
crates/ruff_linter/resources/.*|
|
||||
crates/ruff_linter/src/rules/.*/snapshots/.*|
|
||||
crates/ruff_cli/resources/.*|
|
||||
crates/ruff_python_formatter/resources/.*|
|
||||
crates/ruff_python_formatter/tests/snapshots/.*|
|
||||
@@ -50,7 +50,7 @@ repos:
|
||||
require_serial: true
|
||||
exclude: |
|
||||
(?x)^(
|
||||
crates/ruff/resources/.*|
|
||||
crates/ruff_linter/resources/.*|
|
||||
crates/ruff_python_formatter/resources/.*
|
||||
)$
|
||||
|
||||
|
||||
@@ -299,4 +299,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 [documentation](https://beta.ruff.rs/docs/configuration/#python-file-discovery) for more.
|
||||
See the [documentation](https://docs.astral.sh/ruff/configuration/#python-file-discovery) for more.
|
||||
|
||||
101
CONTRIBUTING.md
101
CONTRIBUTING.md
@@ -112,11 +112,11 @@ Ruff is structured as a monorepo with a [flat crate structure](https://matklad.g
|
||||
such that all crates are contained in a flat `crates` directory.
|
||||
|
||||
The vast majority of the code, including all lint rules, lives in the `ruff` crate (located at
|
||||
`crates/ruff`). As a contributor, that's the crate that'll be most relevant to you.
|
||||
`crates/ruff_linter`). As a contributor, that's the crate that'll be most relevant to you.
|
||||
|
||||
At time of writing, the repository includes the following crates:
|
||||
|
||||
- `crates/ruff`: library crate containing all lint rules and the core logic for running them.
|
||||
- `crates/ruff_linter`: library crate containing all lint rules and the core logic for running them.
|
||||
If you're working on a rule, this is the crate for you.
|
||||
- `crates/ruff_benchmark`: binary crate for running micro-benchmarks.
|
||||
- `crates/ruff_cache`: library crate for caching lint results.
|
||||
@@ -153,7 +153,7 @@ 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)
|
||||
(e.g., `AssertFalse`, as in, "allow `assert False`").
|
||||
|
||||
1. Create a file for your rule (e.g., `crates/ruff/src/rules/flake8_bugbear/rules/assert_false.rs`).
|
||||
1. Create a file for your rule (e.g., `crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_false.rs`).
|
||||
|
||||
1. In that file, define a violation struct (e.g., `pub struct AssertFalse`). You can grep for
|
||||
`#[violation]` to see examples.
|
||||
@@ -162,21 +162,21 @@ At a high level, the steps involved in adding a new lint rule are as follows:
|
||||
(e.g., `pub(crate) fn assert_false`) based on whatever inputs are required for the rule (e.g.,
|
||||
an `ast::StmtAssert` node).
|
||||
|
||||
1. Define the logic for invoking the diagnostic in `crates/ruff/src/checkers/ast/analyze` (for
|
||||
AST-based rules), `crates/ruff/src/checkers/tokens.rs` (for token-based rules),
|
||||
`crates/ruff/src/checkers/physical_lines.rs` (for text-based rules),
|
||||
`crates/ruff/src/checkers/filesystem.rs` (for filesystem-based rules), etc. For AST-based rules,
|
||||
1. Define the logic for invoking the diagnostic in `crates/ruff_linter/src/checkers/ast/analyze` (for
|
||||
AST-based rules), `crates/ruff_linter/src/checkers/tokens.rs` (for token-based rules),
|
||||
`crates/ruff_linter/src/checkers/physical_lines.rs` (for text-based rules),
|
||||
`crates/ruff_linter/src/checkers/filesystem.rs` (for filesystem-based rules), etc. For AST-based rules,
|
||||
you'll likely want to modify `analyze/statement.rs` (if your rule is based on analyzing
|
||||
statements, like imports) or `analyze/expression.rs` (if your rule is based on analyzing
|
||||
expressions, like function calls).
|
||||
|
||||
1. Map the violation struct to a rule code in `crates/ruff/src/codes.rs` (e.g., `B011`).
|
||||
1. Map the violation struct to a rule code in `crates/ruff_linter/src/codes.rs` (e.g., `B011`).
|
||||
|
||||
1. Add proper [testing](#rule-testing-fixtures-and-snapshots) for your rule.
|
||||
|
||||
1. Update the generated files (documentation and generated code).
|
||||
|
||||
To trigger the violation, you'll likely want to augment the logic in `crates/ruff/src/checkers/ast.rs`
|
||||
To trigger the violation, you'll likely want to augment the logic in `crates/ruff_linter/src/checkers/ast.rs`
|
||||
to call your new function at the appropriate time and with the appropriate inputs. The `Checker`
|
||||
defined therein is a Python AST visitor, which iterates over the AST, building up a semantic model,
|
||||
and calling out to lint rule analyzer functions as it goes.
|
||||
@@ -221,7 +221,7 @@ Ruff's output for each fixture, which you can then commit alongside your changes
|
||||
|
||||
Once you've completed the code for the rule itself, you can define tests with the following steps:
|
||||
|
||||
1. Add a Python file to `crates/ruff/resources/test/fixtures/[linter]` that contains the code you
|
||||
1. Add a Python file to `crates/ruff_linter/resources/test/fixtures/[linter]` that contains the code you
|
||||
want to test. The file name should match the rule name (e.g., `E402.py`), and it should include
|
||||
examples of both violations and non-violations.
|
||||
|
||||
@@ -230,16 +230,16 @@ Once you've completed the code for the rule itself, you can define tests with th
|
||||
For example, if you're adding a new rule named `E402`, you would run:
|
||||
|
||||
```shell
|
||||
cargo run -p ruff_cli -- check crates/ruff/resources/test/fixtures/pycodestyle/E402.py --no-cache --select E402
|
||||
cargo run -p ruff_cli -- check crates/ruff_linter/resources/test/fixtures/pycodestyle/E402.py --no-cache --select E402
|
||||
```
|
||||
|
||||
**Note:** Only a subset of rules are enabled by default. When testing a new rule, ensure that
|
||||
you activate it by adding `--select ${rule_code}` to the command.
|
||||
|
||||
1. Add the test to the relevant `crates/ruff/src/rules/[linter]/mod.rs` file. If you're contributing
|
||||
1. Add the test to the relevant `crates/ruff_linter/src/rules/[linter]/mod.rs` file. If you're contributing
|
||||
a rule to a pre-existing set, you should be able to find a similar example to pattern-match
|
||||
against. If you're adding a new linter, you'll need to create a new `mod.rs` file (see,
|
||||
e.g., `crates/ruff/src/rules/flake8_bugbear/mod.rs`)
|
||||
e.g., `crates/ruff_linter/src/rules/flake8_bugbear/mod.rs`)
|
||||
|
||||
1. Run `cargo test`. Your test will fail, but you'll be prompted to follow-up
|
||||
with `cargo insta review`. Run `cargo insta review`, review and accept the generated snapshot,
|
||||
@@ -251,25 +251,24 @@ Once you've completed the code for the rule itself, you can define tests with th
|
||||
|
||||
Ruff's user-facing settings live in a few different places.
|
||||
|
||||
First, the command-line options are defined via the `Cli` struct in `crates/ruff/src/cli.rs`.
|
||||
First, the command-line options are defined via the `Args` struct in `crates/ruff_cli/src/args.rs`.
|
||||
|
||||
Second, the `pyproject.toml` options are defined in `crates/ruff/src/settings/options.rs` (via the
|
||||
`Options` struct), `crates/ruff/src/settings/configuration.rs` (via the `Configuration` struct), and
|
||||
`crates/ruff/src/settings/mod.rs` (via the `Settings` struct). These represent, respectively: the
|
||||
schema used to parse the `pyproject.toml` file; an internal, intermediate representation; and the
|
||||
final, internal representation used to power Ruff.
|
||||
Second, the `pyproject.toml` options are defined in `crates/ruff_workspace/src/options.rs` (via the
|
||||
`Options` struct), `crates/ruff_workspace/src/configuration.rs` (via the `Configuration` struct),
|
||||
and `crates/ruff_workspace/src/settings.rs` (via the `Settings` struct), which then includes
|
||||
the `LinterSettings` struct as a field.
|
||||
|
||||
These represent, respectively: the schema used to parse the `pyproject.toml` file; an internal,
|
||||
intermediate representation; and the final, internal representation used to power Ruff.
|
||||
|
||||
To add a new configuration option, you'll likely want to modify these latter few files (along with
|
||||
`cli.rs`, if appropriate). If you want to pattern-match against an existing example, grep for
|
||||
`arg.rs`, if appropriate). If you want to pattern-match against an existing example, grep for
|
||||
`dummy_variable_rgx`, which defines a regular expression to match against acceptable unused
|
||||
variables (e.g., `_`).
|
||||
|
||||
Note that plugin-specific configuration options are defined in their own modules (e.g.,
|
||||
`crates/ruff/src/flake8_unused_arguments/settings.rs`).
|
||||
|
||||
You may also want to add the new configuration option to the `flake8-to-ruff` tool, which is
|
||||
responsible for converting `flake8` configuration files to Ruff's TOML format. This logic
|
||||
lives in `crates/ruff/src/flake8_to_ruff/converter.rs`.
|
||||
`Settings` in `crates/ruff_linter/src/flake8_unused_arguments/settings.rs` coupled with
|
||||
`Flake8UnusedArgumentsOptions` in `crates/ruff_workspace/src/options.rs`).
|
||||
|
||||
Finally, regenerate the documentation and generated code with `cargo dev generate-all`.
|
||||
|
||||
@@ -362,46 +361,46 @@ First, clone [CPython](https://github.com/python/cpython). It's a large and dive
|
||||
which makes it a good target for benchmarking.
|
||||
|
||||
```shell
|
||||
git clone --branch 3.10 https://github.com/python/cpython.git crates/ruff/resources/test/cpython
|
||||
git clone --branch 3.10 https://github.com/python/cpython.git crates/ruff_linter/resources/test/cpython
|
||||
```
|
||||
|
||||
To benchmark the release build:
|
||||
|
||||
```shell
|
||||
cargo build --release && hyperfine --warmup 10 \
|
||||
"./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache -e" \
|
||||
"./target/release/ruff ./crates/ruff/resources/test/cpython/ -e"
|
||||
"./target/release/ruff ./crates/ruff_linter/resources/test/cpython/ --no-cache -e" \
|
||||
"./target/release/ruff ./crates/ruff_linter/resources/test/cpython/ -e"
|
||||
|
||||
Benchmark 1: ./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache
|
||||
Benchmark 1: ./target/release/ruff ./crates/ruff_linter/resources/test/cpython/ --no-cache
|
||||
Time (mean ± σ): 293.8 ms ± 3.2 ms [User: 2384.6 ms, System: 90.3 ms]
|
||||
Range (min … max): 289.9 ms … 301.6 ms 10 runs
|
||||
|
||||
Benchmark 2: ./target/release/ruff ./crates/ruff/resources/test/cpython/
|
||||
Benchmark 2: ./target/release/ruff ./crates/ruff_linter/resources/test/cpython/
|
||||
Time (mean ± σ): 48.0 ms ± 3.1 ms [User: 65.2 ms, System: 124.7 ms]
|
||||
Range (min … max): 45.0 ms … 66.7 ms 62 runs
|
||||
|
||||
Summary
|
||||
'./target/release/ruff ./crates/ruff/resources/test/cpython/' ran
|
||||
6.12 ± 0.41 times faster than './target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache'
|
||||
'./target/release/ruff ./crates/ruff_linter/resources/test/cpython/' ran
|
||||
6.12 ± 0.41 times faster than './target/release/ruff ./crates/ruff_linter/resources/test/cpython/ --no-cache'
|
||||
```
|
||||
|
||||
To benchmark against the ecosystem's existing tools:
|
||||
|
||||
```shell
|
||||
hyperfine --ignore-failure --warmup 5 \
|
||||
"./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache" \
|
||||
"pyflakes crates/ruff/resources/test/cpython" \
|
||||
"./target/release/ruff ./crates/ruff_linter/resources/test/cpython/ --no-cache" \
|
||||
"pyflakes crates/ruff_linter/resources/test/cpython" \
|
||||
"autoflake --recursive --expand-star-imports --remove-all-unused-imports --remove-unused-variables --remove-duplicate-keys resources/test/cpython" \
|
||||
"pycodestyle crates/ruff/resources/test/cpython" \
|
||||
"flake8 crates/ruff/resources/test/cpython"
|
||||
"pycodestyle crates/ruff_linter/resources/test/cpython" \
|
||||
"flake8 crates/ruff_linter/resources/test/cpython"
|
||||
|
||||
Benchmark 1: ./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache
|
||||
Benchmark 1: ./target/release/ruff ./crates/ruff_linter/resources/test/cpython/ --no-cache
|
||||
Time (mean ± σ): 294.3 ms ± 3.3 ms [User: 2467.5 ms, System: 89.6 ms]
|
||||
Range (min … max): 291.1 ms … 302.8 ms 10 runs
|
||||
|
||||
Warning: Ignoring non-zero exit code.
|
||||
|
||||
Benchmark 2: pyflakes crates/ruff/resources/test/cpython
|
||||
Benchmark 2: pyflakes crates/ruff_linter/resources/test/cpython
|
||||
Time (mean ± σ): 15.786 s ± 0.143 s [User: 15.560 s, System: 0.214 s]
|
||||
Range (min … max): 15.640 s … 16.157 s 10 runs
|
||||
|
||||
@@ -411,31 +410,31 @@ Benchmark 3: autoflake --recursive --expand-star-imports --remove-all-unused-imp
|
||||
Time (mean ± σ): 6.175 s ± 0.169 s [User: 54.102 s, System: 1.057 s]
|
||||
Range (min … max): 5.950 s … 6.391 s 10 runs
|
||||
|
||||
Benchmark 4: pycodestyle crates/ruff/resources/test/cpython
|
||||
Benchmark 4: pycodestyle crates/ruff_linter/resources/test/cpython
|
||||
Time (mean ± σ): 46.921 s ± 0.508 s [User: 46.699 s, System: 0.202 s]
|
||||
Range (min … max): 46.171 s … 47.863 s 10 runs
|
||||
|
||||
Warning: Ignoring non-zero exit code.
|
||||
|
||||
Benchmark 5: flake8 crates/ruff/resources/test/cpython
|
||||
Benchmark 5: flake8 crates/ruff_linter/resources/test/cpython
|
||||
Time (mean ± σ): 12.260 s ± 0.321 s [User: 102.934 s, System: 1.230 s]
|
||||
Range (min … max): 11.848 s … 12.933 s 10 runs
|
||||
|
||||
Warning: Ignoring non-zero exit code.
|
||||
|
||||
Summary
|
||||
'./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache' ran
|
||||
'./target/release/ruff ./crates/ruff_linter/resources/test/cpython/ --no-cache' ran
|
||||
20.98 ± 0.62 times faster than 'autoflake --recursive --expand-star-imports --remove-all-unused-imports --remove-unused-variables --remove-duplicate-keys resources/test/cpython'
|
||||
41.66 ± 1.18 times faster than 'flake8 crates/ruff/resources/test/cpython'
|
||||
53.64 ± 0.77 times faster than 'pyflakes crates/ruff/resources/test/cpython'
|
||||
159.43 ± 2.48 times faster than 'pycodestyle crates/ruff/resources/test/cpython'
|
||||
41.66 ± 1.18 times faster than 'flake8 crates/ruff_linter/resources/test/cpython'
|
||||
53.64 ± 0.77 times faster than 'pyflakes crates/ruff_linter/resources/test/cpython'
|
||||
159.43 ± 2.48 times faster than 'pycodestyle crates/ruff_linter/resources/test/cpython'
|
||||
```
|
||||
|
||||
To benchmark a subset of rules, e.g. `LineTooLong` and `DocLineTooLong`:
|
||||
|
||||
```shell
|
||||
cargo build --release && hyperfine --warmup 10 \
|
||||
"./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache -e --select W505,E501"
|
||||
"./target/release/ruff ./crates/ruff_linter/resources/test/cpython/ --no-cache -e --select W505,E501"
|
||||
```
|
||||
|
||||
You can run `poetry install` from `./scripts/benchmarks` to create a working environment for the
|
||||
@@ -468,10 +467,10 @@ rm Lib/test/bad_coding.py \
|
||||
Lib/test/test_typing.py
|
||||
```
|
||||
|
||||
Then, from `crates/ruff/resources/test/cpython`, run: `time pylint -j 0 -E $(git ls-files '*.py')`. This
|
||||
Then, from `crates/ruff_linter/resources/test/cpython`, run: `time pylint -j 0 -E $(git ls-files '*.py')`. This
|
||||
will execute Pylint with maximum parallelism and only report errors.
|
||||
|
||||
To benchmark Pyupgrade, run the following from `crates/ruff/resources/test/cpython`:
|
||||
To benchmark Pyupgrade, run the following from `crates/ruff_linter/resources/test/cpython`:
|
||||
|
||||
```shell
|
||||
hyperfine --ignore-failure --warmup 5 --prepare "git reset --hard HEAD" \
|
||||
@@ -719,8 +718,8 @@ Module {
|
||||
- `cargo dev generate-cli-help`, `cargo dev generate-docs` and `cargo dev generate-json-schema`:
|
||||
Update just `docs/configuration.md`, `docs/rules` and `ruff.schema.json` respectively.
|
||||
- `cargo dev generate-options`: Generate a markdown-compatible table of all `pyproject.toml`
|
||||
options. Used for <https://beta.ruff.rs/docs/settings/>
|
||||
- `cargo dev generate-rules-table`: Generate a markdown-compatible table of all rules. Used for <https://beta.ruff.rs/docs/rules/>
|
||||
options. Used for <https://docs.astral.sh/ruff/settings/>.
|
||||
- `cargo dev generate-rules-table`: Generate a markdown-compatible table of all rules. Used for <https://docs.astral.sh/ruff/rules/>.
|
||||
- `cargo dev round-trip <python file or jupyter notebook>`: Read a Python file or Jupyter Notebook,
|
||||
parse it, serialize the parsed representation and write it back. Used to check how good our
|
||||
representation is so that fixes don't rewrite irrelevant parts of a file.
|
||||
@@ -778,7 +777,7 @@ To understand Ruff's import categorization system, we first need to define two c
|
||||
- "Package root": The top-most directory defining the Python package that includes a given Python
|
||||
file. To find the package root for a given Python file, traverse up its parent directories until
|
||||
you reach a parent directory that doesn't contain an `__init__.py` file (and isn't marked as
|
||||
a [namespace package](https://beta.ruff.rs/docs/settings/#namespace-packages)); take the directory
|
||||
a [namespace package](https://docs.astral.sh/ruff/settings/#namespace-packages)); take the directory
|
||||
just before that, i.e., the first directory in the package.
|
||||
|
||||
For example, given:
|
||||
@@ -867,7 +866,7 @@ There are three ways in which an import can be categorized as "first-party":
|
||||
package (e.g., `from foo import bar` or `import foo.bar`), they'll be classified as first-party
|
||||
automatically. This check is as simple as comparing the first segment of the current file's
|
||||
module path to the first segment of the import.
|
||||
1. **Source roots**: Ruff supports a `[src](https://beta.ruff.rs/docs/settings/#src)` setting, which
|
||||
1. **Source roots**: Ruff supports a `[src](https://docs.astral.sh/ruff/settings/#src)` setting, which
|
||||
sets the directories to scan when identifying first-party imports. The algorithm is
|
||||
straightforward: given an import, like `import foo`, iterate over the directories enumerated in
|
||||
the `src` setting and, for each directory, check for the existence of a subdirectory `foo` or a
|
||||
|
||||
567
Cargo.lock
generated
567
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
30
Cargo.toml
30
Cargo.toml
@@ -5,8 +5,8 @@ resolver = "2"
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
rust-version = "1.71"
|
||||
homepage = "https://beta.ruff.rs/docs"
|
||||
documentation = "https://beta.ruff.rs/docs"
|
||||
homepage = "https://docs.astral.sh/ruff"
|
||||
documentation = "https://docs.astral.sh/ruff"
|
||||
repository = "https://github.com/astral-sh/ruff"
|
||||
authors = ["Charlie Marsh <charlie.r.marsh@gmail.com>"]
|
||||
license = "MIT"
|
||||
@@ -14,8 +14,8 @@ license = "MIT"
|
||||
[workspace.dependencies]
|
||||
anyhow = { version = "1.0.69" }
|
||||
bitflags = { version = "2.3.1" }
|
||||
chrono = { version = "0.4.23", default-features = false, features = ["clock"] }
|
||||
clap = { version = "4.1.8", features = ["derive"] }
|
||||
chrono = { version = "0.4.31", default-features = false, features = ["clock"] }
|
||||
clap = { version = "4.4.4", features = ["derive"] }
|
||||
colored = { version = "2.0.0" }
|
||||
filetime = { version = "0.2.20" }
|
||||
glob = { version = "0.3.1" }
|
||||
@@ -23,35 +23,35 @@ globset = { version = "0.4.10" }
|
||||
ignore = { version = "0.4.20" }
|
||||
insta = { version = "1.31.0", feature = ["filters", "glob"] }
|
||||
is-macro = { version = "0.3.0" }
|
||||
itertools = { version = "0.10.5" }
|
||||
itertools = { version = "0.11.0" }
|
||||
log = { version = "0.4.17" }
|
||||
memchr = "2.6.3"
|
||||
num-bigint = { version = "0.4.3" }
|
||||
num-traits = { version = "0.2.15" }
|
||||
once_cell = { version = "1.17.1" }
|
||||
path-absolutize = { version = "3.1.1" }
|
||||
proc-macro2 = { version = "1.0.51" }
|
||||
proc-macro2 = { version = "1.0.67" }
|
||||
quote = { version = "1.0.23" }
|
||||
regex = { version = "1.7.1" }
|
||||
regex = { version = "1.9.5" }
|
||||
rustc-hash = { version = "1.1.0" }
|
||||
schemars = { version = "0.8.12" }
|
||||
schemars = { version = "0.8.15" }
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
serde_json = { version = "1.0.106" }
|
||||
serde_json = { version = "1.0.107" }
|
||||
shellexpand = { version = "3.0.0" }
|
||||
similar = { version = "2.2.1", features = ["inline"] }
|
||||
smallvec = { version = "1.10.0" }
|
||||
static_assertions = "1.1.0"
|
||||
strum = { version = "0.25.0", features = ["strum_macros"] }
|
||||
strum_macros = { version = "0.25.2" }
|
||||
syn = { version = "2.0.15" }
|
||||
test-case = { version = "3.0.0" }
|
||||
thiserror = { version = "1.0.43" }
|
||||
toml = { version = "0.7.2" }
|
||||
syn = { version = "2.0.37" }
|
||||
test-case = { version = "3.2.1" }
|
||||
thiserror = { version = "1.0.48" }
|
||||
toml = { version = "0.7.8" }
|
||||
tracing = "0.1.37"
|
||||
tracing-indicatif = "0.3.4"
|
||||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
||||
unicode-ident = "1.0.11"
|
||||
unicode-width = "0.1.10"
|
||||
unicode-ident = "1.0.12"
|
||||
unicode-width = "0.1.11"
|
||||
uuid = { version = "1.4.1", features = ["v4", "fast-rng", "macro-diagnostics", "js"] }
|
||||
wsl = { version = "0.1.0" }
|
||||
|
||||
|
||||
47
LICENSE
47
LICENSE
@@ -1194,7 +1194,27 @@ are:
|
||||
|
||||
- flake8-self, licensed as follows:
|
||||
"""
|
||||
Freely Distributable
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Korijn van Golen
|
||||
|
||||
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-django, licensed under the GPL license.
|
||||
@@ -1224,6 +1244,31 @@ are:
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
- flake8-logging, licensed as follows:
|
||||
"""
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Adam Johnson
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
- Pyright, licensed as follows:
|
||||
"""
|
||||
MIT License
|
||||
|
||||
27
README.md
27
README.md
@@ -8,7 +8,7 @@
|
||||
[](https://pypi.python.org/pypi/ruff)
|
||||
[](https://github.com/astral-sh/ruff/actions)
|
||||
|
||||
[**Discord**](https://discord.gg/c9MhzV8aU5) | [**Docs**](https://beta.ruff.rs/docs/) | [**Playground**](https://play.ruff.rs/)
|
||||
[**Discord**](https://discord.gg/c9MhzV8aU5) | [**Docs**](https://docs.astral.sh/ruff/) | [**Playground**](https://play.ruff.rs/)
|
||||
|
||||
An extremely fast Python linter, written in Rust.
|
||||
|
||||
@@ -30,13 +30,13 @@ An extremely fast Python linter, written in Rust.
|
||||
- 🤝 Python 3.11 compatibility
|
||||
- 📦 Built-in caching, to avoid re-analyzing unchanged files
|
||||
- 🔧 Autofix support, for automatic error correction (e.g., automatically remove unused imports)
|
||||
- 📏 Over [600 built-in rules](https://beta.ruff.rs/docs/rules/)
|
||||
- ⚖️ [Near-parity](https://beta.ruff.rs/docs/faq/#how-does-ruff-compare-to-flake8) with the
|
||||
- 📏 Over [600 built-in rules](https://docs.astral.sh/ruff/rules/)
|
||||
- ⚖️ [Near-parity](https://docs.astral.sh/ruff/faq/#how-does-ruff-compare-to-flake8) with the
|
||||
built-in Flake8 rule set
|
||||
- 🔌 Native re-implementations of dozens of Flake8 plugins, like flake8-bugbear
|
||||
- ⌨️ First-party [editor integrations](https://beta.ruff.rs/docs/editor-integrations/) for
|
||||
- ⌨️ First-party [editor integrations](https://docs.astral.sh/ruff/editor-integrations/) for
|
||||
[VS Code](https://github.com/astral-sh/ruff-vscode) and [more](https://github.com/astral-sh/ruff-lsp)
|
||||
- 🌎 Monorepo-friendly, with [hierarchical and cascading configuration](https://beta.ruff.rs/docs/configuration/#pyprojecttoml-discovery)
|
||||
- 🌎 Monorepo-friendly, with [hierarchical and cascading configuration](https://docs.astral.sh/ruff/configuration/#pyprojecttoml-discovery)
|
||||
|
||||
Ruff aims to be orders of magnitude faster than alternative tools while integrating more
|
||||
functionality behind a single, common interface.
|
||||
@@ -98,7 +98,7 @@ developer of [Zulip](https://github.com/zulip/zulip):
|
||||
|
||||
## Table of Contents
|
||||
|
||||
For more, see the [documentation](https://beta.ruff.rs/docs/).
|
||||
For more, see the [documentation](https://docs.astral.sh/ruff/).
|
||||
|
||||
1. [Getting Started](#getting-started)
|
||||
1. [Configuration](#configuration)
|
||||
@@ -111,7 +111,7 @@ For more, see the [documentation](https://beta.ruff.rs/docs/).
|
||||
|
||||
## Getting Started
|
||||
|
||||
For more, see the [documentation](https://beta.ruff.rs/docs/).
|
||||
For more, see the [documentation](https://docs.astral.sh/ruff/).
|
||||
|
||||
### Installation
|
||||
|
||||
@@ -122,7 +122,7 @@ pip install ruff
|
||||
```
|
||||
|
||||
You can also install Ruff via [Homebrew](https://formulae.brew.sh/formula/ruff), [Conda](https://anaconda.org/conda-forge/ruff),
|
||||
and with [a variety of other package managers](https://beta.ruff.rs/docs/installation/).
|
||||
and with [a variety of other package managers](https://docs.astral.sh/ruff/installation/).
|
||||
|
||||
### Usage
|
||||
|
||||
@@ -140,7 +140,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com) hook:
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.0.289
|
||||
rev: v0.0.290
|
||||
hooks:
|
||||
- id: ruff
|
||||
```
|
||||
@@ -165,7 +165,7 @@ jobs:
|
||||
### Configuration
|
||||
|
||||
Ruff can be configured through a `pyproject.toml`, `ruff.toml`, or `.ruff.toml` file (see:
|
||||
[_Configuration_](https://beta.ruff.rs/docs/configuration/), or [_Settings_](https://beta.ruff.rs/docs/settings/)
|
||||
[_Configuration_](https://docs.astral.sh/ruff/configuration/), or [_Settings_](https://docs.astral.sh/ruff/settings/)
|
||||
for a complete list of all configuration options).
|
||||
|
||||
If left unspecified, the default configuration is equivalent to:
|
||||
@@ -238,7 +238,7 @@ isort, pyupgrade, and others. Regardless of the rule's origin, Ruff re-implement
|
||||
Rust as a first-party feature.
|
||||
|
||||
By default, Ruff enables Flake8's `E` and `F` rules. Ruff supports all rules from the `F` category,
|
||||
and a [subset](https://beta.ruff.rs/docs/rules/#error-e) of the `E` category, omitting those
|
||||
and a [subset](https://docs.astral.sh/ruff/rules/#error-e) of the `E` category, omitting those
|
||||
stylistic rules made obsolete by the use of an autoformatter, like
|
||||
[Black](https://github.com/psf/black).
|
||||
|
||||
@@ -274,6 +274,7 @@ quality tools, including:
|
||||
- [flake8-gettext](https://pypi.org/project/flake8-gettext/)
|
||||
- [flake8-implicit-str-concat](https://pypi.org/project/flake8-implicit-str-concat/)
|
||||
- [flake8-import-conventions](https://github.com/joaopalmeiro/flake8-import-conventions)
|
||||
- [flake8-logging](https://pypi.org/project/flake8-logging/)
|
||||
- [flake8-logging-format](https://pypi.org/project/flake8-logging-format/)
|
||||
- [flake8-no-pep420](https://pypi.org/project/flake8-no-pep420)
|
||||
- [flake8-pie](https://pypi.org/project/flake8-pie/)
|
||||
@@ -303,12 +304,12 @@ quality tools, including:
|
||||
- [tryceratops](https://pypi.org/project/tryceratops/)
|
||||
- [yesqa](https://pypi.org/project/yesqa/)
|
||||
|
||||
For a complete enumeration of the supported rules, see [_Rules_](https://beta.ruff.rs/docs/rules/).
|
||||
For a complete enumeration of the supported rules, see [_Rules_](https://docs.astral.sh/ruff/rules/).
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome and highly appreciated. To get started, check out the
|
||||
[**contributing guidelines**](https://beta.ruff.rs/docs/contributing/).
|
||||
[**contributing guidelines**](https://docs.astral.sh/ruff/contributing/).
|
||||
|
||||
You can also join us on [**Discord**](https://discord.gg/c9MhzV8aU5).
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "flake8-to-ruff"
|
||||
version = "0.0.289"
|
||||
version = "0.0.290"
|
||||
description = """
|
||||
Convert Flake8 configuration files to Ruff configuration files.
|
||||
"""
|
||||
@@ -13,7 +13,7 @@ repository = { workspace = true }
|
||||
license = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
ruff = { path = "../ruff", default-features = false }
|
||||
ruff_linter = { path = "../ruff_linter", default-features = false }
|
||||
ruff_workspace = { path = "../ruff_workspace" }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
|
||||
@@ -86,7 +86,7 @@ flake8-to-ruff path/to/.flake8 --plugin flake8-builtins --plugin flake8-quotes
|
||||
configuration options that don't exist in Flake8.)
|
||||
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
|
||||
[documentation](https://docs.astral.sh/ruff/faq/#how-does-ruff-compare-to-flake8) for the complete
|
||||
list of supported plugins.)
|
||||
|
||||
## License
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Extract Black configuration settings from a pyproject.toml.
|
||||
|
||||
use ruff::line_width::LineLength;
|
||||
use ruff::settings::types::PythonVersion;
|
||||
use ruff_linter::line_width::LineLength;
|
||||
use ruff_linter::settings::types::PythonVersion;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||
|
||||
@@ -3,17 +3,17 @@ use std::str::FromStr;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use ruff::line_width::LineLength;
|
||||
use ruff::registry::Linter;
|
||||
use ruff::rule_selector::RuleSelector;
|
||||
use ruff::rules::flake8_pytest_style::types::{
|
||||
use ruff_linter::line_width::LineLength;
|
||||
use ruff_linter::registry::Linter;
|
||||
use ruff_linter::rule_selector::RuleSelector;
|
||||
use ruff_linter::rules::flake8_pytest_style::types::{
|
||||
ParametrizeNameType, ParametrizeValuesRowType, ParametrizeValuesType,
|
||||
};
|
||||
use ruff::rules::flake8_quotes::settings::Quote;
|
||||
use ruff::rules::flake8_tidy_imports::settings::Strictness;
|
||||
use ruff::rules::pydocstyle::settings::Convention;
|
||||
use ruff::settings::types::PythonVersion;
|
||||
use ruff::warn_user;
|
||||
use ruff_linter::rules::flake8_quotes::settings::Quote;
|
||||
use ruff_linter::rules::flake8_tidy_imports::settings::Strictness;
|
||||
use ruff_linter::rules::pydocstyle::settings::Convention;
|
||||
use ruff_linter::settings::types::PythonVersion;
|
||||
use ruff_linter::warn_user;
|
||||
use ruff_workspace::options::{
|
||||
Flake8AnnotationsOptions, Flake8BugbearOptions, Flake8BuiltinsOptions, Flake8ErrMsgOptions,
|
||||
Flake8PytestStyleOptions, Flake8QuotesOptions, Flake8TidyImportsOptions, McCabeOptions,
|
||||
@@ -458,12 +458,12 @@ mod tests {
|
||||
use pep440_rs::VersionSpecifiers;
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
use ruff::line_width::LineLength;
|
||||
use ruff::registry::Linter;
|
||||
use ruff::rule_selector::RuleSelector;
|
||||
use ruff::rules::flake8_quotes;
|
||||
use ruff::rules::pydocstyle::settings::Convention;
|
||||
use ruff::settings::types::PythonVersion;
|
||||
use ruff_linter::line_width::LineLength;
|
||||
use ruff_linter::registry::Linter;
|
||||
use ruff_linter::rule_selector::RuleSelector;
|
||||
use ruff_linter::rules::flake8_quotes;
|
||||
use ruff_linter::rules::pydocstyle::settings::Convention;
|
||||
use ruff_linter::settings::types::PythonVersion;
|
||||
use ruff_workspace::options::{Flake8QuotesOptions, Options, PydocstyleOptions};
|
||||
use ruff_workspace::pyproject::Pyproject;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::converter::convert;
|
||||
use crate::external_config::ExternalConfig;
|
||||
use crate::plugin::Plugin;
|
||||
use crate::pyproject::parse;
|
||||
use ruff::logging::{set_up_logging, LogLevel};
|
||||
use ruff_linter::logging::{set_up_logging, LogLevel};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(
|
||||
|
||||
@@ -3,10 +3,11 @@ use std::str::FromStr;
|
||||
use anyhow::{bail, Result};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use ruff::settings::types::PatternPrefixPair;
|
||||
use ruff::{warn_user, RuleSelector};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use ruff_linter::settings::types::PatternPrefixPair;
|
||||
use ruff_linter::{warn_user, RuleSelector};
|
||||
|
||||
static COMMA_SEPARATED_LIST_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"[,\s]").unwrap());
|
||||
|
||||
/// Parse a comma-separated list of `RuleSelector` values (e.g.,
|
||||
@@ -192,11 +193,11 @@ pub(crate) fn collect_per_file_ignores(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use anyhow::Result;
|
||||
use ruff::RuleSelector;
|
||||
|
||||
use ruff::codes;
|
||||
use ruff::registry::Linter;
|
||||
use ruff::settings::types::PatternPrefixPair;
|
||||
use ruff_linter::codes;
|
||||
use ruff_linter::registry::Linter;
|
||||
use ruff_linter::settings::types::PatternPrefixPair;
|
||||
use ruff_linter::RuleSelector;
|
||||
|
||||
use super::{parse_files_to_codes_mapping, parse_prefix_codes, parse_strings};
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use ruff::registry::Linter;
|
||||
use ruff::settings::types::PreviewMode;
|
||||
use ruff::RuleSelector;
|
||||
use ruff_linter::registry::Linter;
|
||||
use ruff_linter::settings::types::PreviewMode;
|
||||
use ruff_linter::RuleSelector;
|
||||
|
||||
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||||
pub enum Plugin {
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
type("")
|
||||
type(b"")
|
||||
type(0)
|
||||
type(0.0)
|
||||
type(0j)
|
||||
|
||||
# OK
|
||||
type(arg)(" ")
|
||||
|
||||
# OK
|
||||
y = x.dtype.type(0.0)
|
||||
|
||||
# OK
|
||||
type = lambda *args, **kwargs: None
|
||||
type("")
|
||||
@@ -1,96 +0,0 @@
|
||||
# project
|
||||
|
||||
An example multi-package Python project used to test setting resolution and other complex
|
||||
behaviors.
|
||||
|
||||
## Expected behavior
|
||||
|
||||
Running from the repo root should pick up and enforce the appropriate settings for each package:
|
||||
|
||||
```console
|
||||
∴ cargo run -p ruff_cli -- check crates/ruff/resources/test/project/
|
||||
crates/ruff/resources/test/project/examples/.dotfiles/script.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||
crates/ruff/resources/test/project/examples/.dotfiles/script.py:1:8: F401 [*] `numpy` imported but unused
|
||||
crates/ruff/resources/test/project/examples/.dotfiles/script.py:2:17: F401 [*] `app.app_file` imported but unused
|
||||
crates/ruff/resources/test/project/examples/docs/docs/file.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||
crates/ruff/resources/test/project/examples/docs/docs/file.py:8:5: F841 [*] Local variable `x` is assigned to but never used
|
||||
crates/ruff/resources/test/project/project/file.py:1:8: F401 [*] `os` imported but unused
|
||||
crates/ruff/resources/test/project/project/import_file.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||
Found 7 errors.
|
||||
[*] 7 potentially fixable with the --fix option.
|
||||
```
|
||||
|
||||
Running from the project directory itself should exhibit the same behavior:
|
||||
|
||||
```console
|
||||
∴ (cd crates/ruff/resources/test/project/ && cargo run -p ruff_cli -- check .)
|
||||
examples/.dotfiles/script.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||
examples/.dotfiles/script.py:1:8: F401 [*] `numpy` imported but unused
|
||||
examples/.dotfiles/script.py:2:17: F401 [*] `app.app_file` imported but unused
|
||||
examples/docs/docs/file.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||
examples/docs/docs/file.py:8:5: F841 [*] Local variable `x` is assigned to but never used
|
||||
project/file.py:1:8: F401 [*] `os` imported but unused
|
||||
project/import_file.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||
Found 7 errors.
|
||||
[*] 7 potentially fixable with the --fix option.
|
||||
```
|
||||
|
||||
Running from the sub-package directory should exhibit the same behavior, but omit the top-level
|
||||
files:
|
||||
|
||||
```console
|
||||
∴ (cd crates/ruff/resources/test/project/examples/docs && cargo run -p ruff_cli -- check .)
|
||||
docs/file.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||
docs/file.py:8:5: F841 [*] Local variable `x` is assigned to but never used
|
||||
Found 2 errors.
|
||||
[*] 2 potentially fixable with the --fix option.
|
||||
```
|
||||
|
||||
`--config` should force Ruff to use the specified `pyproject.toml` for all files, and resolve
|
||||
file paths from the current working directory:
|
||||
|
||||
```console
|
||||
∴ (cargo run -p ruff_cli -- check --config=crates/ruff/resources/test/project/pyproject.toml crates/ruff/resources/test/project/)
|
||||
crates/ruff/resources/test/project/examples/.dotfiles/script.py:1:8: F401 [*] `numpy` imported but unused
|
||||
crates/ruff/resources/test/project/examples/.dotfiles/script.py:2:17: F401 [*] `app.app_file` imported but unused
|
||||
crates/ruff/resources/test/project/examples/docs/docs/concepts/file.py:1:8: F401 [*] `os` imported but unused
|
||||
crates/ruff/resources/test/project/examples/docs/docs/file.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||
crates/ruff/resources/test/project/examples/docs/docs/file.py:1:8: F401 [*] `os` imported but unused
|
||||
crates/ruff/resources/test/project/examples/docs/docs/file.py:3:8: F401 [*] `numpy` imported but unused
|
||||
crates/ruff/resources/test/project/examples/docs/docs/file.py:4:27: F401 [*] `docs.concepts.file` imported but unused
|
||||
crates/ruff/resources/test/project/examples/excluded/script.py:1:8: F401 [*] `os` imported but unused
|
||||
crates/ruff/resources/test/project/project/file.py:1:8: F401 [*] `os` imported but unused
|
||||
Found 9 errors.
|
||||
[*] 9 potentially fixable with the --fix option.
|
||||
```
|
||||
|
||||
Running from a parent directory should "ignore" the `exclude` (hence, `concepts/file.py` gets
|
||||
included in the output):
|
||||
|
||||
```console
|
||||
∴ (cd crates/ruff/resources/test/project/examples && cargo run -p ruff_cli -- check --config=docs/ruff.toml .)
|
||||
docs/docs/concepts/file.py:5:5: F841 [*] Local variable `x` is assigned to but never used
|
||||
docs/docs/file.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||
docs/docs/file.py:8:5: F841 [*] Local variable `x` is assigned to but never used
|
||||
excluded/script.py:5:5: F841 [*] Local variable `x` is assigned to but never used
|
||||
Found 4 errors.
|
||||
[*] 4 potentially fixable with the --fix option.
|
||||
```
|
||||
|
||||
Passing an excluded directory directly should report errors in the contained files:
|
||||
|
||||
```console
|
||||
∴ cargo run -p ruff_cli -- check crates/ruff/resources/test/project/examples/excluded/
|
||||
crates/ruff/resources/test/project/examples/excluded/script.py:1:8: F401 [*] `os` imported but unused
|
||||
Found 1 error.
|
||||
[*] 1 potentially fixable with the --fix option.
|
||||
```
|
||||
|
||||
Unless we `--force-exclude`:
|
||||
|
||||
```console
|
||||
∴ cargo run -p ruff_cli -- check crates/ruff/resources/test/project/examples/excluded/ --force-exclude
|
||||
warning: No Python files found under the given path(s)
|
||||
∴ cargo run -p ruff_cli -- check crates/ruff/resources/test/project/examples/excluded/script.py --force-exclude
|
||||
warning: No Python files found under the given path(s)
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,242 +0,0 @@
|
||||
//! `NoQA` enforcement and validation.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use itertools::Itertools;
|
||||
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
||||
use ruff_source_file::Locator;
|
||||
|
||||
use crate::noqa;
|
||||
use crate::noqa::{Directive, FileExemption, NoqaDirectives, NoqaMapping};
|
||||
use crate::registry::{AsRule, Rule};
|
||||
use crate::rule_redirects::get_redirect_target;
|
||||
use crate::rules::ruff::rules::{UnusedCodes, UnusedNOQA};
|
||||
use crate::settings::Settings;
|
||||
|
||||
pub(crate) fn check_noqa(
|
||||
diagnostics: &mut Vec<Diagnostic>,
|
||||
path: &Path,
|
||||
locator: &Locator,
|
||||
comment_ranges: &[TextRange],
|
||||
noqa_line_for: &NoqaMapping,
|
||||
analyze_directives: bool,
|
||||
settings: &Settings,
|
||||
) -> Vec<usize> {
|
||||
// Identify any codes that are globally exempted (within the current file).
|
||||
let exemption = FileExemption::try_extract(locator.contents(), comment_ranges, path, locator);
|
||||
|
||||
// Extract all `noqa` directives.
|
||||
let mut noqa_directives = NoqaDirectives::from_commented_ranges(comment_ranges, path, locator);
|
||||
|
||||
// Indices of diagnostics that were ignored by a `noqa` directive.
|
||||
let mut ignored_diagnostics = vec![];
|
||||
|
||||
// Remove any ignored diagnostics.
|
||||
'outer: for (index, diagnostic) in diagnostics.iter().enumerate() {
|
||||
if matches!(diagnostic.kind.rule(), Rule::BlanketNOQA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
match &exemption {
|
||||
Some(FileExemption::All) => {
|
||||
// If the file is exempted, ignore all diagnostics.
|
||||
ignored_diagnostics.push(index);
|
||||
continue;
|
||||
}
|
||||
Some(FileExemption::Codes(codes)) => {
|
||||
// If the diagnostic is ignored by a global exemption, ignore it.
|
||||
if codes.contains(&diagnostic.kind.rule().noqa_code()) {
|
||||
ignored_diagnostics.push(index);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
let noqa_offsets = diagnostic
|
||||
.parent
|
||||
.into_iter()
|
||||
.chain(std::iter::once(diagnostic.start()))
|
||||
.map(|position| noqa_line_for.resolve(position))
|
||||
.unique();
|
||||
|
||||
for noqa_offset in noqa_offsets {
|
||||
if let Some(directive_line) = noqa_directives.find_line_with_directive_mut(noqa_offset)
|
||||
{
|
||||
let suppressed = match &directive_line.directive {
|
||||
Directive::All(_) => {
|
||||
directive_line
|
||||
.matches
|
||||
.push(diagnostic.kind.rule().noqa_code());
|
||||
ignored_diagnostics.push(index);
|
||||
true
|
||||
}
|
||||
Directive::Codes(directive) => {
|
||||
if noqa::includes(diagnostic.kind.rule(), directive.codes()) {
|
||||
directive_line
|
||||
.matches
|
||||
.push(diagnostic.kind.rule().noqa_code());
|
||||
ignored_diagnostics.push(index);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if suppressed {
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce that the noqa directive was actually used (RUF100), unless RUF100 was itself
|
||||
// suppressed.
|
||||
if settings.rules.enabled(Rule::UnusedNOQA)
|
||||
&& analyze_directives
|
||||
&& !exemption.is_some_and(|exemption| match exemption {
|
||||
FileExemption::All => true,
|
||||
FileExemption::Codes(codes) => codes.contains(&Rule::UnusedNOQA.noqa_code()),
|
||||
})
|
||||
{
|
||||
for line in noqa_directives.lines() {
|
||||
match &line.directive {
|
||||
Directive::All(directive) => {
|
||||
if line.matches.is_empty() {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(UnusedNOQA { codes: None }, directive.range());
|
||||
if settings.rules.should_fix(diagnostic.kind.rule()) {
|
||||
diagnostic
|
||||
.set_fix(Fix::suggested(delete_noqa(directive.range(), locator)));
|
||||
}
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
Directive::Codes(directive) => {
|
||||
let mut disabled_codes = vec![];
|
||||
let mut unknown_codes = vec![];
|
||||
let mut unmatched_codes = vec![];
|
||||
let mut valid_codes = vec![];
|
||||
let mut self_ignore = false;
|
||||
for code in directive.codes() {
|
||||
let code = get_redirect_target(code).unwrap_or(code);
|
||||
if Rule::UnusedNOQA.noqa_code() == code {
|
||||
self_ignore = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if line.matches.iter().any(|match_| *match_ == code)
|
||||
|| settings.external.contains(code)
|
||||
{
|
||||
valid_codes.push(code);
|
||||
} else {
|
||||
if let Ok(rule) = Rule::from_code(code) {
|
||||
if settings.rules.enabled(rule) {
|
||||
unmatched_codes.push(code);
|
||||
} else {
|
||||
disabled_codes.push(code);
|
||||
}
|
||||
} else {
|
||||
unknown_codes.push(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self_ignore {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !(disabled_codes.is_empty()
|
||||
&& unknown_codes.is_empty()
|
||||
&& unmatched_codes.is_empty())
|
||||
{
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
UnusedNOQA {
|
||||
codes: Some(UnusedCodes {
|
||||
disabled: disabled_codes
|
||||
.iter()
|
||||
.map(|code| (*code).to_string())
|
||||
.collect(),
|
||||
unknown: unknown_codes
|
||||
.iter()
|
||||
.map(|code| (*code).to_string())
|
||||
.collect(),
|
||||
unmatched: unmatched_codes
|
||||
.iter()
|
||||
.map(|code| (*code).to_string())
|
||||
.collect(),
|
||||
}),
|
||||
},
|
||||
directive.range(),
|
||||
);
|
||||
if settings.rules.should_fix(diagnostic.kind.rule()) {
|
||||
if valid_codes.is_empty() {
|
||||
diagnostic.set_fix(Fix::suggested(delete_noqa(
|
||||
directive.range(),
|
||||
locator,
|
||||
)));
|
||||
} else {
|
||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||
format!("# noqa: {}", valid_codes.join(", ")),
|
||||
directive.range(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ignored_diagnostics.sort_unstable();
|
||||
ignored_diagnostics
|
||||
}
|
||||
|
||||
/// Generate a [`Edit`] to delete a `noqa` directive.
|
||||
fn delete_noqa(range: TextRange, locator: &Locator) -> Edit {
|
||||
let line_range = locator.line_range(range.start());
|
||||
|
||||
// Compute the leading space.
|
||||
let prefix = locator.slice(TextRange::new(line_range.start(), range.start()));
|
||||
let leading_space = prefix
|
||||
.rfind(|c: char| !c.is_whitespace())
|
||||
.map_or(prefix.len(), |i| prefix.len() - i - 1);
|
||||
let leading_space_len = TextSize::try_from(leading_space).unwrap();
|
||||
|
||||
// Compute the trailing space.
|
||||
let suffix = locator.slice(TextRange::new(range.end(), line_range.end()));
|
||||
let trailing_space = suffix
|
||||
.find(|c: char| !c.is_whitespace())
|
||||
.map_or(suffix.len(), |i| i);
|
||||
let trailing_space_len = TextSize::try_from(trailing_space).unwrap();
|
||||
|
||||
// Ex) `# noqa`
|
||||
if line_range
|
||||
== TextRange::new(
|
||||
range.start() - leading_space_len,
|
||||
range.end() + trailing_space_len,
|
||||
)
|
||||
{
|
||||
let full_line_end = locator.full_line_end(line_range.end());
|
||||
Edit::deletion(line_range.start(), full_line_end)
|
||||
}
|
||||
// Ex) `x = 1 # noqa`
|
||||
else if range.end() + trailing_space_len == line_range.end() {
|
||||
Edit::deletion(range.start() - leading_space_len, line_range.end())
|
||||
}
|
||||
// Ex) `x = 1 # noqa # type: ignore`
|
||||
else if locator.contents()[usize::from(range.end() + trailing_space_len)..].starts_with('#') {
|
||||
Edit::deletion(range.start(), range.end() + trailing_space_len)
|
||||
}
|
||||
// Ex) `x = 1 # noqa here`
|
||||
else {
|
||||
Edit::deletion(
|
||||
range.start() + "# ".text_len(),
|
||||
range.end() + trailing_space_len,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/comments/shebang.rs
|
||||
expression: "ShebangDirective::try_extract(source)"
|
||||
---
|
||||
None
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/comments/shebang.rs
|
||||
expression: "ShebangDirective::try_extract(source)"
|
||||
---
|
||||
None
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/comments/shebang.rs
|
||||
expression: "ShebangDirective::try_extract(source)"
|
||||
---
|
||||
Some(
|
||||
ShebangDirective(
|
||||
"/usr/bin/env python",
|
||||
),
|
||||
)
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/comments/shebang.rs
|
||||
expression: "ShebangDirective::try_extract(source)"
|
||||
---
|
||||
Some(
|
||||
ShebangDirective(
|
||||
"/usr/bin/env python # trailing comment",
|
||||
),
|
||||
)
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/comments/shebang.rs
|
||||
expression: "ShebangDirective::try_extract(source)"
|
||||
---
|
||||
None
|
||||
@@ -1,52 +0,0 @@
|
||||
use libcst_native::{Expression, NameOrAttribute, ParenthesizableWhitespace, SimpleWhitespace};
|
||||
|
||||
fn compose_call_path_inner<'a>(expr: &'a Expression, parts: &mut Vec<&'a str>) {
|
||||
match expr {
|
||||
Expression::Call(expr) => {
|
||||
compose_call_path_inner(&expr.func, parts);
|
||||
}
|
||||
Expression::Attribute(expr) => {
|
||||
compose_call_path_inner(&expr.value, parts);
|
||||
parts.push(expr.attr.value);
|
||||
}
|
||||
Expression::Name(expr) => {
|
||||
parts.push(expr.value);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compose_call_path(expr: &Expression) -> Option<String> {
|
||||
let mut segments = vec![];
|
||||
compose_call_path_inner(expr, &mut segments);
|
||||
if segments.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(segments.join("."))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compose_module_path(module: &NameOrAttribute) -> String {
|
||||
match module {
|
||||
NameOrAttribute::N(name) => name.value.to_string(),
|
||||
NameOrAttribute::A(attr) => {
|
||||
let name = attr.attr.value;
|
||||
let prefix = compose_call_path(&attr.value);
|
||||
prefix.map_or_else(|| name.to_string(), |prefix| format!("{prefix}.{name}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a [`ParenthesizableWhitespace`] containing a single space.
|
||||
pub(crate) fn space() -> ParenthesizableWhitespace<'static> {
|
||||
ParenthesizableWhitespace::SimpleWhitespace(SimpleWhitespace(" "))
|
||||
}
|
||||
|
||||
/// Ensure that a [`ParenthesizableWhitespace`] contains at least one space.
|
||||
pub(crate) fn or_space(whitespace: ParenthesizableWhitespace) -> ParenthesizableWhitespace {
|
||||
if whitespace == ParenthesizableWhitespace::default() {
|
||||
space()
|
||||
} else {
|
||||
whitespace
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::ops::Deref;
|
||||
|
||||
use ruff_python_ast::Expr;
|
||||
use ruff_python_semantic::Definition;
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
pub(crate) mod extraction;
|
||||
pub(crate) mod google;
|
||||
pub(crate) mod numpy;
|
||||
pub(crate) mod sections;
|
||||
pub(crate) mod styles;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Docstring<'a> {
|
||||
pub(crate) definition: &'a Definition<'a>,
|
||||
pub(crate) expr: &'a Expr,
|
||||
/// The content of the docstring, including the leading and trailing quotes.
|
||||
pub(crate) contents: &'a str,
|
||||
/// The range of the docstring body (without the quotes). The range is relative to [`Self::contents`].
|
||||
pub(crate) body_range: TextRange,
|
||||
pub(crate) indentation: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> Docstring<'a> {
|
||||
pub(crate) fn body(&self) -> DocstringBody {
|
||||
DocstringBody { docstring: self }
|
||||
}
|
||||
|
||||
pub(crate) fn leading_quote(&self) -> &'a str {
|
||||
&self.contents[TextRange::up_to(self.body_range.start())]
|
||||
}
|
||||
}
|
||||
|
||||
impl Ranged for Docstring<'_> {
|
||||
fn range(&self) -> TextRange {
|
||||
self.expr.range()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) struct DocstringBody<'a> {
|
||||
docstring: &'a Docstring<'a>,
|
||||
}
|
||||
|
||||
impl<'a> DocstringBody<'a> {
|
||||
pub(crate) fn as_str(self) -> &'a str {
|
||||
&self.docstring.contents[self.docstring.body_range]
|
||||
}
|
||||
}
|
||||
|
||||
impl Ranged for DocstringBody<'_> {
|
||||
fn range(&self) -> TextRange {
|
||||
self.docstring.body_range + self.docstring.start()
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for DocstringBody<'_> {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for DocstringBody<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("DocstringBody")
|
||||
.field("text", &self.as_str())
|
||||
.field("range", &self.range())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/azure.rs
|
||||
expression: content
|
||||
---
|
||||
##vso[task.logissue type=error;sourcepath=fib.py;linenumber=1;columnnumber=8;code=F401;]`os` imported but unused
|
||||
##vso[task.logissue type=error;sourcepath=fib.py;linenumber=6;columnnumber=5;code=F841;]Local variable `x` is assigned to but never used
|
||||
##vso[task.logissue type=error;sourcepath=undef.py;linenumber=1;columnnumber=4;code=F821;]Undefined name `a`
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/github.rs
|
||||
expression: content
|
||||
---
|
||||
::error title=Ruff (F401),file=fib.py,line=1,col=8,endLine=1,endColumn=10::fib.py:1:8: F401 `os` imported but unused
|
||||
::error title=Ruff (F841),file=fib.py,line=6,col=5,endLine=6,endColumn=6::fib.py:6:5: F841 Local variable `x` is assigned to but never used
|
||||
::error title=Ruff (F821),file=undef.py,line=1,col=4,endLine=1,endColumn=5::undef.py:1:4: F821 Undefined name `a`
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/gitlab.rs
|
||||
expression: redact_fingerprint(&content)
|
||||
---
|
||||
[
|
||||
{
|
||||
"description": "(F401) `os` imported but unused",
|
||||
"fingerprint": "<redacted>",
|
||||
"location": {
|
||||
"lines": {
|
||||
"begin": 1,
|
||||
"end": 1
|
||||
},
|
||||
"path": "fib.py"
|
||||
},
|
||||
"severity": "major"
|
||||
},
|
||||
{
|
||||
"description": "(F841) Local variable `x` is assigned to but never used",
|
||||
"fingerprint": "<redacted>",
|
||||
"location": {
|
||||
"lines": {
|
||||
"begin": 6,
|
||||
"end": 6
|
||||
},
|
||||
"path": "fib.py"
|
||||
},
|
||||
"severity": "major"
|
||||
},
|
||||
{
|
||||
"description": "(F821) Undefined name `a`",
|
||||
"fingerprint": "<redacted>",
|
||||
"location": {
|
||||
"lines": {
|
||||
"begin": 1,
|
||||
"end": 1
|
||||
},
|
||||
"path": "undef.py"
|
||||
},
|
||||
"severity": "major"
|
||||
}
|
||||
]
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/grouped.rs
|
||||
expression: content
|
||||
---
|
||||
fib.py:
|
||||
1:8 F401 `os` imported but unused
|
||||
6:5 F841 Local variable `x` is assigned to but never used
|
||||
|
||||
undef.py:
|
||||
1:4 F821 Undefined name `a`
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/grouped.rs
|
||||
expression: content
|
||||
---
|
||||
fib.py:
|
||||
1:8 F401 [*] `os` imported but unused
|
||||
|
|
||||
1 | import os
|
||||
| ^^ F401
|
||||
|
|
||||
= help: Remove unused import: `os`
|
||||
|
||||
6:5 F841 [*] Local variable `x` is assigned to but never used
|
||||
|
|
||||
4 | def fibonacci(n):
|
||||
5 | """Compute the nth number in the Fibonacci sequence."""
|
||||
6 | x = 1
|
||||
| ^ F841
|
||||
7 | if n == 0:
|
||||
8 | return 0
|
||||
|
|
||||
= help: Remove assignment to unused variable `x`
|
||||
|
||||
undef.py:
|
||||
1:4 F821 Undefined name `a`
|
||||
|
|
||||
1 | if a == 1: pass
|
||||
| ^ F821
|
||||
|
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/grouped.rs
|
||||
expression: content
|
||||
---
|
||||
fib.py:
|
||||
1:8 F401 `os` imported but unused
|
||||
|
|
||||
1 | import os
|
||||
| ^^ F401
|
||||
|
|
||||
= help: Remove unused import: `os`
|
||||
|
||||
6:5 F841 Local variable `x` is assigned to but never used
|
||||
|
|
||||
4 | def fibonacci(n):
|
||||
5 | """Compute the nth number in the Fibonacci sequence."""
|
||||
6 | x = 1
|
||||
| ^ F841
|
||||
7 | if n == 0:
|
||||
8 | return 0
|
||||
|
|
||||
= help: Remove assignment to unused variable `x`
|
||||
|
||||
undef.py:
|
||||
1:4 F821 Undefined name `a`
|
||||
|
|
||||
1 | if a == 1: pass
|
||||
| ^ F821
|
||||
|
|
||||
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/json.rs
|
||||
expression: content
|
||||
---
|
||||
[
|
||||
{
|
||||
"code": "F401",
|
||||
"end_location": {
|
||||
"column": 10,
|
||||
"row": 1
|
||||
},
|
||||
"filename": "fib.py",
|
||||
"fix": {
|
||||
"applicability": "Suggested",
|
||||
"edits": [
|
||||
{
|
||||
"content": "",
|
||||
"end_location": {
|
||||
"column": 1,
|
||||
"row": 2
|
||||
},
|
||||
"location": {
|
||||
"column": 1,
|
||||
"row": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"message": "Remove unused import: `os`"
|
||||
},
|
||||
"location": {
|
||||
"column": 8,
|
||||
"row": 1
|
||||
},
|
||||
"message": "`os` imported but unused",
|
||||
"noqa_row": 1,
|
||||
"url": "https://beta.ruff.rs/docs/rules/unused-import"
|
||||
},
|
||||
{
|
||||
"code": "F841",
|
||||
"end_location": {
|
||||
"column": 6,
|
||||
"row": 6
|
||||
},
|
||||
"filename": "fib.py",
|
||||
"fix": {
|
||||
"applicability": "Suggested",
|
||||
"edits": [
|
||||
{
|
||||
"content": "",
|
||||
"end_location": {
|
||||
"column": 10,
|
||||
"row": 6
|
||||
},
|
||||
"location": {
|
||||
"column": 5,
|
||||
"row": 6
|
||||
}
|
||||
}
|
||||
],
|
||||
"message": "Remove assignment to unused variable `x`"
|
||||
},
|
||||
"location": {
|
||||
"column": 5,
|
||||
"row": 6
|
||||
},
|
||||
"message": "Local variable `x` is assigned to but never used",
|
||||
"noqa_row": 6,
|
||||
"url": "https://beta.ruff.rs/docs/rules/unused-variable"
|
||||
},
|
||||
{
|
||||
"code": "F821",
|
||||
"end_location": {
|
||||
"column": 5,
|
||||
"row": 1
|
||||
},
|
||||
"filename": "undef.py",
|
||||
"fix": null,
|
||||
"location": {
|
||||
"column": 4,
|
||||
"row": 1
|
||||
},
|
||||
"message": "Undefined name `a`",
|
||||
"noqa_row": 1,
|
||||
"url": "https://beta.ruff.rs/docs/rules/undefined-name"
|
||||
}
|
||||
]
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/json_lines.rs
|
||||
expression: content
|
||||
---
|
||||
{"code":"F401","end_location":{"column":10,"row":1},"filename":"fib.py","fix":{"applicability":"Suggested","edits":[{"content":"","end_location":{"column":1,"row":2},"location":{"column":1,"row":1}}],"message":"Remove unused import: `os`"},"location":{"column":8,"row":1},"message":"`os` imported but unused","noqa_row":1,"url":"https://beta.ruff.rs/docs/rules/unused-import"}
|
||||
{"code":"F841","end_location":{"column":6,"row":6},"filename":"fib.py","fix":{"applicability":"Suggested","edits":[{"content":"","end_location":{"column":10,"row":6},"location":{"column":5,"row":6}}],"message":"Remove assignment to unused variable `x`"},"location":{"column":5,"row":6},"message":"Local variable `x` is assigned to but never used","noqa_row":6,"url":"https://beta.ruff.rs/docs/rules/unused-variable"}
|
||||
{"code":"F821","end_location":{"column":5,"row":1},"filename":"undef.py","fix":null,"location":{"column":4,"row":1},"message":"Undefined name `a`","noqa_row":1,"url":"https://beta.ruff.rs/docs/rules/undefined-name"}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/junit.rs
|
||||
expression: content
|
||||
---
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites name="ruff" tests="3" failures="3" errors="0">
|
||||
<testsuite name="fib.py" tests="2" disabled="0" errors="0" failures="2" package="org.ruff">
|
||||
<testcase name="org.ruff.F401" classname="fib" line="1" column="8">
|
||||
<failure message="`os` imported but unused">line 1, col 8, `os` imported but unused</failure>
|
||||
</testcase>
|
||||
<testcase name="org.ruff.F841" classname="fib" line="6" column="5">
|
||||
<failure message="Local variable `x` is assigned to but never used">line 6, col 5, Local variable `x` is assigned to but never used</failure>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
<testsuite name="undef.py" tests="1" disabled="0" errors="0" failures="1" package="org.ruff">
|
||||
<testcase name="org.ruff.F821" classname="undef" line="1" column="4">
|
||||
<failure message="Undefined name `a`">line 1, col 4, Undefined name `a`</failure>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/pylint.rs
|
||||
expression: content
|
||||
---
|
||||
fib.py:1: [F401] `os` imported but unused
|
||||
fib.py:6: [F841] Local variable `x` is assigned to but never used
|
||||
undef.py:1: [F821] Undefined name `a`
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/text.rs
|
||||
expression: content
|
||||
---
|
||||
fib.py:1:8: F401 `os` imported but unused
|
||||
|
|
||||
1 | import os
|
||||
| ^^ F401
|
||||
|
|
||||
= help: Remove unused import: `os`
|
||||
|
||||
fib.py:6:5: F841 Local variable `x` is assigned to but never used
|
||||
|
|
||||
4 | def fibonacci(n):
|
||||
5 | """Compute the nth number in the Fibonacci sequence."""
|
||||
6 | x = 1
|
||||
| ^ F841
|
||||
7 | if n == 0:
|
||||
8 | return 0
|
||||
|
|
||||
= help: Remove assignment to unused variable `x`
|
||||
|
||||
undef.py:1:4: F821 Undefined name `a`
|
||||
|
|
||||
1 | if a == 1: pass
|
||||
| ^ F821
|
||||
|
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/message/text.rs
|
||||
expression: content
|
||||
---
|
||||
fib.py:1:8: F401 [*] `os` imported but unused
|
||||
|
|
||||
1 | import os
|
||||
| ^^ F401
|
||||
|
|
||||
= help: Remove unused import: `os`
|
||||
|
||||
fib.py:6:5: F841 [*] Local variable `x` is assigned to but never used
|
||||
|
|
||||
4 | def fibonacci(n):
|
||||
5 | """Compute the nth number in the Fibonacci sequence."""
|
||||
6 | x = 1
|
||||
| ^ F841
|
||||
7 | if n == 0:
|
||||
8 | return 0
|
||||
|
|
||||
= help: Remove assignment to unused variable `x`
|
||||
|
||||
undef.py:1:4: F821 Undefined name `a`
|
||||
|
|
||||
1 | if a == 1: pass
|
||||
| ^ F821
|
||||
|
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,25 +0,0 @@
|
||||
//! Airflow-specific rules.
|
||||
pub(crate) mod rules;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_messages, settings};
|
||||
|
||||
#[test_case(Rule::AirflowVariableNameTaskIdMismatch, Path::new("AIR001.py"))]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("airflow").join(path).as_path(),
|
||||
&settings::Settings::for_rule(rule_code),
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/airflow/mod.rs
|
||||
---
|
||||
AIR001.py:11:1: AIR001 Task variable name should match the `task_id`: "my_task"
|
||||
|
|
||||
9 | my_task_2 = PythonOperator(callable=my_callable, task_id="my_task_2")
|
||||
10 |
|
||||
11 | incorrect_name = PythonOperator(task_id="my_task")
|
||||
| ^^^^^^^^^^^^^^ AIR001
|
||||
12 | incorrect_name_2 = PythonOperator(callable=my_callable, task_id="my_task_2")
|
||||
|
|
||||
|
||||
AIR001.py:12:1: AIR001 Task variable name should match the `task_id`: "my_task_2"
|
||||
|
|
||||
11 | incorrect_name = PythonOperator(task_id="my_task")
|
||||
12 | incorrect_name_2 = PythonOperator(callable=my_callable, task_id="my_task_2")
|
||||
| ^^^^^^^^^^^^^^^^ AIR001
|
||||
13 |
|
||||
14 | from my_module import MyClass
|
||||
|
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
//! Rules from [eradicate](https://pypi.org/project/eradicate/).
|
||||
pub(crate) mod detection;
|
||||
pub(crate) mod rules;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_messages, settings};
|
||||
|
||||
#[test_case(Rule::CommentedOutCode, Path::new("ERA001.py"))]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("eradicate").join(path).as_path(),
|
||||
&settings::Settings::for_rule(rule_code),
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/eradicate/mod.rs
|
||||
---
|
||||
ERA001.py:1:1: ERA001 [*] Found commented-out code
|
||||
|
|
||||
1 | #import os
|
||||
| ^^^^^^^^^^ ERA001
|
||||
2 | # from foo import junk
|
||||
3 | #a = 3
|
||||
|
|
||||
= help: Remove commented-out code
|
||||
|
||||
ℹ Possible fix
|
||||
1 |-#import os
|
||||
2 1 | # from foo import junk
|
||||
3 2 | #a = 3
|
||||
4 3 | a = 4
|
||||
|
||||
ERA001.py:2:1: ERA001 [*] Found commented-out code
|
||||
|
|
||||
1 | #import os
|
||||
2 | # from foo import junk
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ ERA001
|
||||
3 | #a = 3
|
||||
4 | a = 4
|
||||
|
|
||||
= help: Remove commented-out code
|
||||
|
||||
ℹ Possible fix
|
||||
1 1 | #import os
|
||||
2 |-# from foo import junk
|
||||
3 2 | #a = 3
|
||||
4 3 | a = 4
|
||||
5 4 | #foo(1, 2, 3)
|
||||
|
||||
ERA001.py:3:1: ERA001 [*] Found commented-out code
|
||||
|
|
||||
1 | #import os
|
||||
2 | # from foo import junk
|
||||
3 | #a = 3
|
||||
| ^^^^^^ ERA001
|
||||
4 | a = 4
|
||||
5 | #foo(1, 2, 3)
|
||||
|
|
||||
= help: Remove commented-out code
|
||||
|
||||
ℹ Possible fix
|
||||
1 1 | #import os
|
||||
2 2 | # from foo import junk
|
||||
3 |-#a = 3
|
||||
4 3 | a = 4
|
||||
5 4 | #foo(1, 2, 3)
|
||||
6 5 |
|
||||
|
||||
ERA001.py:5:1: ERA001 [*] Found commented-out code
|
||||
|
|
||||
3 | #a = 3
|
||||
4 | a = 4
|
||||
5 | #foo(1, 2, 3)
|
||||
| ^^^^^^^^^^^^^ ERA001
|
||||
6 |
|
||||
7 | def foo(x, y, z):
|
||||
|
|
||||
= help: Remove commented-out code
|
||||
|
||||
ℹ Possible fix
|
||||
2 2 | # from foo import junk
|
||||
3 3 | #a = 3
|
||||
4 4 | a = 4
|
||||
5 |-#foo(1, 2, 3)
|
||||
6 5 |
|
||||
7 6 | def foo(x, y, z):
|
||||
8 7 | content = 1 # print('hello')
|
||||
|
||||
ERA001.py:13:5: ERA001 [*] Found commented-out code
|
||||
|
|
||||
11 | # This is a real comment.
|
||||
12 | # # This is a (nested) comment.
|
||||
13 | #return True
|
||||
| ^^^^^^^^^^^^ ERA001
|
||||
14 | return False
|
||||
|
|
||||
= help: Remove commented-out code
|
||||
|
||||
ℹ Possible fix
|
||||
10 10 |
|
||||
11 11 | # This is a real comment.
|
||||
12 12 | # # This is a (nested) comment.
|
||||
13 |- #return True
|
||||
14 13 | return False
|
||||
15 14 |
|
||||
16 15 | #import os # noqa: ERA001
|
||||
|
||||
ERA001.py:21:5: ERA001 [*] Found commented-out code
|
||||
|
|
||||
19 | class A():
|
||||
20 | pass
|
||||
21 | # b = c
|
||||
| ^^^^^^^ ERA001
|
||||
|
|
||||
= help: Remove commented-out code
|
||||
|
||||
ℹ Possible fix
|
||||
18 18 |
|
||||
19 19 | class A():
|
||||
20 20 | pass
|
||||
21 |- # b = c
|
||||
22 21 |
|
||||
23 22 |
|
||||
24 23 | dictionary = {
|
||||
|
||||
ERA001.py:26:5: ERA001 [*] Found commented-out code
|
||||
|
|
||||
24 | dictionary = {
|
||||
25 | # "key1": 123, # noqa: ERA001
|
||||
26 | # "key2": 456,
|
||||
| ^^^^^^^^^^^^^^ ERA001
|
||||
27 | # "key3": 789, # test
|
||||
28 | }
|
||||
|
|
||||
= help: Remove commented-out code
|
||||
|
||||
ℹ Possible fix
|
||||
23 23 |
|
||||
24 24 | dictionary = {
|
||||
25 25 | # "key1": 123, # noqa: ERA001
|
||||
26 |- # "key2": 456,
|
||||
27 26 | # "key3": 789, # test
|
||||
28 27 | }
|
||||
29 28 |
|
||||
|
||||
ERA001.py:27:5: ERA001 [*] Found commented-out code
|
||||
|
|
||||
25 | # "key1": 123, # noqa: ERA001
|
||||
26 | # "key2": 456,
|
||||
27 | # "key3": 789, # test
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ ERA001
|
||||
28 | }
|
||||
|
|
||||
= help: Remove commented-out code
|
||||
|
||||
ℹ Possible fix
|
||||
24 24 | dictionary = {
|
||||
25 25 | # "key1": 123, # noqa: ERA001
|
||||
26 26 | # "key2": 456,
|
||||
27 |- # "key3": 789, # test
|
||||
28 27 | }
|
||||
29 28 |
|
||||
30 29 | #import os # noqa
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
//! Rules from [flake8-2020](https://pypi.org/project/flake8-2020/).
|
||||
mod helpers;
|
||||
pub(crate) mod rules;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_messages, settings};
|
||||
|
||||
#[test_case(Rule::SysVersionSlice3, Path::new("YTT101.py"))]
|
||||
#[test_case(Rule::SysVersion2, Path::new("YTT102.py"))]
|
||||
#[test_case(Rule::SysVersionCmpStr3, Path::new("YTT103.py"))]
|
||||
#[test_case(Rule::SysVersionInfo0Eq3, Path::new("YTT201.py"))]
|
||||
#[test_case(Rule::SixPY3, Path::new("YTT202.py"))]
|
||||
#[test_case(Rule::SysVersionInfo1CmpInt, Path::new("YTT203.py"))]
|
||||
#[test_case(Rule::SysVersionInfoMinorCmpInt, Path::new("YTT204.py"))]
|
||||
#[test_case(Rule::SysVersion0, Path::new("YTT301.py"))]
|
||||
#[test_case(Rule::SysVersionCmpStr10, Path::new("YTT302.py"))]
|
||||
#[test_case(Rule::SysVersionSlice1, Path::new("YTT303.py"))]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_2020").join(path).as_path(),
|
||||
&settings::Settings::for_rule(rule_code),
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
---
|
||||
YTT101.py:6:7: YTT101 `sys.version[:3]` referenced (python3.10), use `sys.version_info`
|
||||
|
|
||||
4 | print(sys.version)
|
||||
5 |
|
||||
6 | print(sys.version[:3])
|
||||
| ^^^^^^^^^^^ YTT101
|
||||
7 | print(version[:3])
|
||||
8 | print(v[:3])
|
||||
|
|
||||
|
||||
YTT101.py:7:7: YTT101 `sys.version[:3]` referenced (python3.10), use `sys.version_info`
|
||||
|
|
||||
6 | print(sys.version[:3])
|
||||
7 | print(version[:3])
|
||||
| ^^^^^^^ YTT101
|
||||
8 | print(v[:3])
|
||||
|
|
||||
|
||||
YTT101.py:8:7: YTT101 `sys.version[:3]` referenced (python3.10), use `sys.version_info`
|
||||
|
|
||||
6 | print(sys.version[:3])
|
||||
7 | print(version[:3])
|
||||
8 | print(v[:3])
|
||||
| ^ YTT101
|
||||
9 |
|
||||
10 | # the tool is timid and only flags certain numeric slices
|
||||
|
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
---
|
||||
YTT102.py:4:12: YTT102 `sys.version[2]` referenced (python3.10), use `sys.version_info`
|
||||
|
|
||||
2 | from sys import version
|
||||
3 |
|
||||
4 | py_minor = sys.version[2]
|
||||
| ^^^^^^^^^^^ YTT102
|
||||
5 | py_minor = version[2]
|
||||
|
|
||||
|
||||
YTT102.py:5:12: YTT102 `sys.version[2]` referenced (python3.10), use `sys.version_info`
|
||||
|
|
||||
4 | py_minor = sys.version[2]
|
||||
5 | py_minor = version[2]
|
||||
| ^^^^^^^ YTT102
|
||||
|
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
---
|
||||
YTT103.py:4:1: YTT103 `sys.version` compared to string (python3.10), use `sys.version_info`
|
||||
|
|
||||
2 | from sys import version
|
||||
3 |
|
||||
4 | version < "3.5"
|
||||
| ^^^^^^^ YTT103
|
||||
5 | sys.version < "3.5"
|
||||
6 | sys.version <= "3.5"
|
||||
|
|
||||
|
||||
YTT103.py:5:1: YTT103 `sys.version` compared to string (python3.10), use `sys.version_info`
|
||||
|
|
||||
4 | version < "3.5"
|
||||
5 | sys.version < "3.5"
|
||||
| ^^^^^^^^^^^ YTT103
|
||||
6 | sys.version <= "3.5"
|
||||
7 | sys.version > "3.5"
|
||||
|
|
||||
|
||||
YTT103.py:6:1: YTT103 `sys.version` compared to string (python3.10), use `sys.version_info`
|
||||
|
|
||||
4 | version < "3.5"
|
||||
5 | sys.version < "3.5"
|
||||
6 | sys.version <= "3.5"
|
||||
| ^^^^^^^^^^^ YTT103
|
||||
7 | sys.version > "3.5"
|
||||
8 | sys.version >= "3.5"
|
||||
|
|
||||
|
||||
YTT103.py:7:1: YTT103 `sys.version` compared to string (python3.10), use `sys.version_info`
|
||||
|
|
||||
5 | sys.version < "3.5"
|
||||
6 | sys.version <= "3.5"
|
||||
7 | sys.version > "3.5"
|
||||
| ^^^^^^^^^^^ YTT103
|
||||
8 | sys.version >= "3.5"
|
||||
|
|
||||
|
||||
YTT103.py:8:1: YTT103 `sys.version` compared to string (python3.10), use `sys.version_info`
|
||||
|
|
||||
6 | sys.version <= "3.5"
|
||||
7 | sys.version > "3.5"
|
||||
8 | sys.version >= "3.5"
|
||||
| ^^^^^^^^^^^ YTT103
|
||||
|
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
---
|
||||
YTT201.py:7:7: YTT201 `sys.version_info[0] == 3` referenced (python4), use `>=`
|
||||
|
|
||||
5 | PY3 = sys.version_info[0] >= 3
|
||||
6 |
|
||||
7 | PY3 = sys.version_info[0] == 3
|
||||
| ^^^^^^^^^^^^^^^^^^^ YTT201
|
||||
8 | PY3 = version_info[0] == 3
|
||||
9 | PY2 = sys.version_info[0] != 3
|
||||
|
|
||||
|
||||
YTT201.py:8:7: YTT201 `sys.version_info[0] == 3` referenced (python4), use `>=`
|
||||
|
|
||||
7 | PY3 = sys.version_info[0] == 3
|
||||
8 | PY3 = version_info[0] == 3
|
||||
| ^^^^^^^^^^^^^^^ YTT201
|
||||
9 | PY2 = sys.version_info[0] != 3
|
||||
10 | PY2 = version_info[0] != 3
|
||||
|
|
||||
|
||||
YTT201.py:9:7: YTT201 `sys.version_info[0] == 3` referenced (python4), use `>=`
|
||||
|
|
||||
7 | PY3 = sys.version_info[0] == 3
|
||||
8 | PY3 = version_info[0] == 3
|
||||
9 | PY2 = sys.version_info[0] != 3
|
||||
| ^^^^^^^^^^^^^^^^^^^ YTT201
|
||||
10 | PY2 = version_info[0] != 3
|
||||
|
|
||||
|
||||
YTT201.py:10:7: YTT201 `sys.version_info[0] == 3` referenced (python4), use `>=`
|
||||
|
|
||||
8 | PY3 = version_info[0] == 3
|
||||
9 | PY2 = sys.version_info[0] != 3
|
||||
10 | PY2 = version_info[0] != 3
|
||||
| ^^^^^^^^^^^^^^^ YTT201
|
||||
|
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
---
|
||||
YTT202.py:4:4: YTT202 `six.PY3` referenced (python4), use `not six.PY2`
|
||||
|
|
||||
2 | from six import PY3
|
||||
3 |
|
||||
4 | if six.PY3:
|
||||
| ^^^^^^^ YTT202
|
||||
5 | print("3")
|
||||
6 | if PY3:
|
||||
|
|
||||
|
||||
YTT202.py:6:4: YTT202 `six.PY3` referenced (python4), use `not six.PY2`
|
||||
|
|
||||
4 | if six.PY3:
|
||||
5 | print("3")
|
||||
6 | if PY3:
|
||||
| ^^^ YTT202
|
||||
7 | print("3")
|
||||
|
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
---
|
||||
YTT203.py:4:1: YTT203 `sys.version_info[1]` compared to integer (python4), compare `sys.version_info` to tuple
|
||||
|
|
||||
2 | from sys import version_info
|
||||
3 |
|
||||
4 | sys.version_info[1] >= 5
|
||||
| ^^^^^^^^^^^^^^^^^^^ YTT203
|
||||
5 | version_info[1] < 6
|
||||
|
|
||||
|
||||
YTT203.py:5:1: YTT203 `sys.version_info[1]` compared to integer (python4), compare `sys.version_info` to tuple
|
||||
|
|
||||
4 | sys.version_info[1] >= 5
|
||||
5 | version_info[1] < 6
|
||||
| ^^^^^^^^^^^^^^^ YTT203
|
||||
|
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
---
|
||||
YTT204.py:4:1: YTT204 `sys.version_info.minor` compared to integer (python4), compare `sys.version_info` to tuple
|
||||
|
|
||||
2 | from sys import version_info
|
||||
3 |
|
||||
4 | sys.version_info.minor <= 7
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ YTT204
|
||||
5 | version_info.minor > 8
|
||||
|
|
||||
|
||||
YTT204.py:5:1: YTT204 `sys.version_info.minor` compared to integer (python4), compare `sys.version_info` to tuple
|
||||
|
|
||||
4 | sys.version_info.minor <= 7
|
||||
5 | version_info.minor > 8
|
||||
| ^^^^^^^^^^^^^^^^^^ YTT204
|
||||
|
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
---
|
||||
YTT301.py:4:12: YTT301 `sys.version[0]` referenced (python10), use `sys.version_info`
|
||||
|
|
||||
2 | from sys import version
|
||||
3 |
|
||||
4 | py_major = sys.version[0]
|
||||
| ^^^^^^^^^^^ YTT301
|
||||
5 | py_major = version[0]
|
||||
|
|
||||
|
||||
YTT301.py:5:12: YTT301 `sys.version[0]` referenced (python10), use `sys.version_info`
|
||||
|
|
||||
4 | py_major = sys.version[0]
|
||||
5 | py_major = version[0]
|
||||
| ^^^^^^^ YTT301
|
||||
|
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
---
|
||||
YTT302.py:4:1: YTT302 `sys.version` compared to string (python10), use `sys.version_info`
|
||||
|
|
||||
2 | from sys import version
|
||||
3 |
|
||||
4 | version < "3"
|
||||
| ^^^^^^^ YTT302
|
||||
5 | sys.version < "3"
|
||||
6 | sys.version <= "3"
|
||||
|
|
||||
|
||||
YTT302.py:5:1: YTT302 `sys.version` compared to string (python10), use `sys.version_info`
|
||||
|
|
||||
4 | version < "3"
|
||||
5 | sys.version < "3"
|
||||
| ^^^^^^^^^^^ YTT302
|
||||
6 | sys.version <= "3"
|
||||
7 | sys.version > "3"
|
||||
|
|
||||
|
||||
YTT302.py:6:1: YTT302 `sys.version` compared to string (python10), use `sys.version_info`
|
||||
|
|
||||
4 | version < "3"
|
||||
5 | sys.version < "3"
|
||||
6 | sys.version <= "3"
|
||||
| ^^^^^^^^^^^ YTT302
|
||||
7 | sys.version > "3"
|
||||
8 | sys.version >= "3"
|
||||
|
|
||||
|
||||
YTT302.py:7:1: YTT302 `sys.version` compared to string (python10), use `sys.version_info`
|
||||
|
|
||||
5 | sys.version < "3"
|
||||
6 | sys.version <= "3"
|
||||
7 | sys.version > "3"
|
||||
| ^^^^^^^^^^^ YTT302
|
||||
8 | sys.version >= "3"
|
||||
|
|
||||
|
||||
YTT302.py:8:1: YTT302 `sys.version` compared to string (python10), use `sys.version_info`
|
||||
|
|
||||
6 | sys.version <= "3"
|
||||
7 | sys.version > "3"
|
||||
8 | sys.version >= "3"
|
||||
| ^^^^^^^^^^^ YTT302
|
||||
|
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
---
|
||||
YTT303.py:4:7: YTT303 `sys.version[:1]` referenced (python10), use `sys.version_info`
|
||||
|
|
||||
2 | from sys import version
|
||||
3 |
|
||||
4 | print(sys.version[:1])
|
||||
| ^^^^^^^^^^^ YTT303
|
||||
5 | print(version[:1])
|
||||
|
|
||||
|
||||
YTT303.py:5:7: YTT303 `sys.version[:1]` referenced (python10), use `sys.version_info`
|
||||
|
|
||||
4 | print(sys.version[:1])
|
||||
5 | print(version[:1])
|
||||
| ^^^^^^^ YTT303
|
||||
|
|
||||
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
//! Rules from [flake8-annotations](https://pypi.org/project/flake8-annotations/).
|
||||
pub(crate) mod helpers;
|
||||
pub(crate) mod rules;
|
||||
pub mod settings;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::assert_messages;
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::Settings;
|
||||
use crate::test::test_path;
|
||||
|
||||
#[test]
|
||||
fn defaults() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_annotations/annotation_presence.py"),
|
||||
&Settings {
|
||||
..Settings::for_rules(vec![
|
||||
Rule::MissingTypeFunctionArgument,
|
||||
Rule::MissingTypeArgs,
|
||||
Rule::MissingTypeKwargs,
|
||||
Rule::MissingTypeSelf,
|
||||
Rule::MissingTypeCls,
|
||||
Rule::MissingReturnTypeUndocumentedPublicFunction,
|
||||
Rule::MissingReturnTypePrivateFunction,
|
||||
Rule::MissingReturnTypeSpecialMethod,
|
||||
Rule::MissingReturnTypeStaticMethod,
|
||||
Rule::MissingReturnTypeClassMethod,
|
||||
Rule::AnyType,
|
||||
])
|
||||
},
|
||||
)?;
|
||||
assert_messages!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_fully_untyped() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_annotations/ignore_fully_untyped.py"),
|
||||
&Settings {
|
||||
flake8_annotations: super::settings::Settings {
|
||||
ignore_fully_untyped: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Settings::for_rules(vec![
|
||||
Rule::MissingTypeFunctionArgument,
|
||||
Rule::MissingTypeArgs,
|
||||
Rule::MissingTypeKwargs,
|
||||
Rule::MissingTypeSelf,
|
||||
Rule::MissingTypeCls,
|
||||
Rule::MissingReturnTypeUndocumentedPublicFunction,
|
||||
Rule::MissingReturnTypePrivateFunction,
|
||||
Rule::MissingReturnTypeSpecialMethod,
|
||||
Rule::MissingReturnTypeStaticMethod,
|
||||
Rule::MissingReturnTypeClassMethod,
|
||||
Rule::AnyType,
|
||||
])
|
||||
},
|
||||
)?;
|
||||
assert_messages!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn suppress_dummy_args() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_annotations/suppress_dummy_args.py"),
|
||||
&Settings {
|
||||
flake8_annotations: super::settings::Settings {
|
||||
suppress_dummy_args: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Settings::for_rules(vec![
|
||||
Rule::MissingTypeFunctionArgument,
|
||||
Rule::MissingTypeArgs,
|
||||
Rule::MissingTypeKwargs,
|
||||
Rule::MissingTypeSelf,
|
||||
Rule::MissingTypeCls,
|
||||
])
|
||||
},
|
||||
)?;
|
||||
assert_messages!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mypy_init_return() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_annotations/mypy_init_return.py"),
|
||||
&Settings {
|
||||
flake8_annotations: super::settings::Settings {
|
||||
mypy_init_return: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Settings::for_rules(vec![
|
||||
Rule::MissingReturnTypeUndocumentedPublicFunction,
|
||||
Rule::MissingReturnTypePrivateFunction,
|
||||
Rule::MissingReturnTypeSpecialMethod,
|
||||
Rule::MissingReturnTypeStaticMethod,
|
||||
Rule::MissingReturnTypeClassMethod,
|
||||
])
|
||||
},
|
||||
)?;
|
||||
assert_messages!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn suppress_none_returning() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_annotations/suppress_none_returning.py"),
|
||||
&Settings {
|
||||
flake8_annotations: super::settings::Settings {
|
||||
suppress_none_returning: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Settings::for_rules(vec![
|
||||
Rule::MissingTypeFunctionArgument,
|
||||
Rule::MissingTypeArgs,
|
||||
Rule::MissingTypeKwargs,
|
||||
Rule::MissingTypeSelf,
|
||||
Rule::MissingTypeCls,
|
||||
Rule::MissingReturnTypeUndocumentedPublicFunction,
|
||||
Rule::MissingReturnTypePrivateFunction,
|
||||
Rule::MissingReturnTypeSpecialMethod,
|
||||
Rule::MissingReturnTypeStaticMethod,
|
||||
Rule::MissingReturnTypeClassMethod,
|
||||
Rule::AnyType,
|
||||
])
|
||||
},
|
||||
)?;
|
||||
assert_messages!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_star_arg_any() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_annotations/allow_star_arg_any.py"),
|
||||
&Settings {
|
||||
flake8_annotations: super::settings::Settings {
|
||||
allow_star_arg_any: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Settings::for_rules(vec![Rule::AnyType])
|
||||
},
|
||||
)?;
|
||||
assert_messages!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_overload() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_annotations/allow_overload.py"),
|
||||
&Settings {
|
||||
..Settings::for_rules(vec![
|
||||
Rule::MissingReturnTypeUndocumentedPublicFunction,
|
||||
Rule::MissingReturnTypePrivateFunction,
|
||||
Rule::MissingReturnTypeSpecialMethod,
|
||||
Rule::MissingReturnTypeStaticMethod,
|
||||
Rule::MissingReturnTypeClassMethod,
|
||||
])
|
||||
},
|
||||
)?;
|
||||
assert_messages!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_nested_overload() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_annotations/allow_nested_overload.py"),
|
||||
&Settings {
|
||||
..Settings::for_rules(vec![
|
||||
Rule::MissingReturnTypeUndocumentedPublicFunction,
|
||||
Rule::MissingReturnTypePrivateFunction,
|
||||
Rule::MissingReturnTypeSpecialMethod,
|
||||
Rule::MissingReturnTypeStaticMethod,
|
||||
Rule::MissingReturnTypeClassMethod,
|
||||
])
|
||||
},
|
||||
)?;
|
||||
assert_messages!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_magic_methods() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_annotations/simple_magic_methods.py"),
|
||||
&Settings::for_rule(Rule::MissingReturnTypeSpecialMethod),
|
||||
)?;
|
||||
assert_messages!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
---
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
---
|
||||
allow_overload.py:29:9: ANN201 Missing return type annotation for public function `bar`
|
||||
|
|
||||
28 | class X:
|
||||
29 | def bar(i):
|
||||
| ^^^ ANN201
|
||||
30 | return i
|
||||
|
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
---
|
||||
allow_star_arg_any.py:10:12: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a`
|
||||
|
|
||||
9 | # ANN401
|
||||
10 | def foo(a: Any, *args: str, **kwargs: str) -> int:
|
||||
| ^^^ ANN401
|
||||
11 | pass
|
||||
|
|
||||
|
||||
allow_star_arg_any.py:15:47: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `foo`
|
||||
|
|
||||
14 | # ANN401
|
||||
15 | def foo(a: int, *args: str, **kwargs: str) -> Any:
|
||||
| ^^^ ANN401
|
||||
16 | pass
|
||||
|
|
||||
|
||||
allow_star_arg_any.py:40:29: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a`
|
||||
|
|
||||
39 | # ANN401
|
||||
40 | def foo_method(self, a: Any, *params: str, **options: str) -> int:
|
||||
| ^^^ ANN401
|
||||
41 | pass
|
||||
|
|
||||
|
||||
allow_star_arg_any.py:44:67: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `foo_method`
|
||||
|
|
||||
43 | # ANN401
|
||||
44 | def foo_method(self, a: int, *params: str, **options: str) -> Any:
|
||||
| ^^^ ANN401
|
||||
45 | pass
|
||||
|
|
||||
|
||||
|
||||
@@ -1,263 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
---
|
||||
annotation_presence.py:5:5: ANN201 Missing return type annotation for public function `foo`
|
||||
|
|
||||
4 | # Error
|
||||
5 | def foo(a, b):
|
||||
| ^^^ ANN201
|
||||
6 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:5:9: ANN001 Missing type annotation for function argument `a`
|
||||
|
|
||||
4 | # Error
|
||||
5 | def foo(a, b):
|
||||
| ^ ANN001
|
||||
6 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:5:12: ANN001 Missing type annotation for function argument `b`
|
||||
|
|
||||
4 | # Error
|
||||
5 | def foo(a, b):
|
||||
| ^ ANN001
|
||||
6 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:10:5: ANN201 Missing return type annotation for public function `foo`
|
||||
|
|
||||
9 | # Error
|
||||
10 | def foo(a: int, b):
|
||||
| ^^^ ANN201
|
||||
11 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:10:17: ANN001 Missing type annotation for function argument `b`
|
||||
|
|
||||
9 | # Error
|
||||
10 | def foo(a: int, b):
|
||||
| ^ ANN001
|
||||
11 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:15:17: ANN001 Missing type annotation for function argument `b`
|
||||
|
|
||||
14 | # Error
|
||||
15 | def foo(a: int, b) -> int:
|
||||
| ^ ANN001
|
||||
16 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:20:5: ANN201 Missing return type annotation for public function `foo`
|
||||
|
|
||||
19 | # Error
|
||||
20 | def foo(a: int, b: int):
|
||||
| ^^^ ANN201
|
||||
21 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:25:5: ANN201 Missing return type annotation for public function `foo`
|
||||
|
|
||||
24 | # Error
|
||||
25 | def foo():
|
||||
| ^^^ ANN201
|
||||
26 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:45:12: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a`
|
||||
|
|
||||
44 | # ANN401
|
||||
45 | def foo(a: Any, *args: str, **kwargs: str) -> int:
|
||||
| ^^^ ANN401
|
||||
46 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:50:47: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `foo`
|
||||
|
|
||||
49 | # ANN401
|
||||
50 | def foo(a: int, *args: str, **kwargs: str) -> Any:
|
||||
| ^^^ ANN401
|
||||
51 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:55:24: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `*args`
|
||||
|
|
||||
54 | # ANN401
|
||||
55 | def foo(a: int, *args: Any, **kwargs: Any) -> int:
|
||||
| ^^^ ANN401
|
||||
56 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:55:39: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `**kwargs`
|
||||
|
|
||||
54 | # ANN401
|
||||
55 | def foo(a: int, *args: Any, **kwargs: Any) -> int:
|
||||
| ^^^ ANN401
|
||||
56 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:60:24: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `*args`
|
||||
|
|
||||
59 | # ANN401
|
||||
60 | def foo(a: int, *args: Any, **kwargs: str) -> int:
|
||||
| ^^^ ANN401
|
||||
61 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:65:39: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `**kwargs`
|
||||
|
|
||||
64 | # ANN401
|
||||
65 | def foo(a: int, *args: str, **kwargs: Any) -> int:
|
||||
| ^^^ ANN401
|
||||
66 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:75:13: ANN101 Missing type annotation for `self` in method
|
||||
|
|
||||
74 | # ANN101
|
||||
75 | def foo(self, a: int, b: int) -> int:
|
||||
| ^^^^ ANN101
|
||||
76 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:79:29: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a`
|
||||
|
|
||||
78 | # ANN401
|
||||
79 | def foo(self: "Foo", a: Any, *params: str, **options: str) -> int:
|
||||
| ^^^ ANN401
|
||||
80 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:83:67: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `foo`
|
||||
|
|
||||
82 | # ANN401
|
||||
83 | def foo(self: "Foo", a: int, *params: str, **options: str) -> Any:
|
||||
| ^^^ ANN401
|
||||
84 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:87:43: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `*params`
|
||||
|
|
||||
86 | # ANN401
|
||||
87 | def foo(self: "Foo", a: int, *params: Any, **options: Any) -> int:
|
||||
| ^^^ ANN401
|
||||
88 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:87:59: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `**options`
|
||||
|
|
||||
86 | # ANN401
|
||||
87 | def foo(self: "Foo", a: int, *params: Any, **options: Any) -> int:
|
||||
| ^^^ ANN401
|
||||
88 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:91:43: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `*params`
|
||||
|
|
||||
90 | # ANN401
|
||||
91 | def foo(self: "Foo", a: int, *params: Any, **options: str) -> int:
|
||||
| ^^^ ANN401
|
||||
92 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:95:59: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `**options`
|
||||
|
|
||||
94 | # ANN401
|
||||
95 | def foo(self: "Foo", a: int, *params: str, **options: Any) -> int:
|
||||
| ^^^ ANN401
|
||||
96 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:130:13: ANN102 Missing type annotation for `cls` in classmethod
|
||||
|
|
||||
128 | # ANN102
|
||||
129 | @classmethod
|
||||
130 | def foo(cls, a: int, b: int) -> int:
|
||||
| ^^^ ANN102
|
||||
131 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:134:13: ANN101 Missing type annotation for `self` in method
|
||||
|
|
||||
133 | # ANN101
|
||||
134 | def foo(self, /, a: int, b: int) -> int:
|
||||
| ^^^^ ANN101
|
||||
135 | pass
|
||||
|
|
||||
|
||||
annotation_presence.py:149:10: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a`
|
||||
|
|
||||
148 | # ANN401
|
||||
149 | def f(a: Any | int) -> None: ...
|
||||
| ^^^^^^^^^ ANN401
|
||||
150 | def f(a: int | Any) -> None: ...
|
||||
151 | def f(a: Union[str, bytes, Any]) -> None: ...
|
||||
|
|
||||
|
||||
annotation_presence.py:150:10: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a`
|
||||
|
|
||||
148 | # ANN401
|
||||
149 | def f(a: Any | int) -> None: ...
|
||||
150 | def f(a: int | Any) -> None: ...
|
||||
| ^^^^^^^^^ ANN401
|
||||
151 | def f(a: Union[str, bytes, Any]) -> None: ...
|
||||
152 | def f(a: Optional[Any]) -> None: ...
|
||||
|
|
||||
|
||||
annotation_presence.py:151:10: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a`
|
||||
|
|
||||
149 | def f(a: Any | int) -> None: ...
|
||||
150 | def f(a: int | Any) -> None: ...
|
||||
151 | def f(a: Union[str, bytes, Any]) -> None: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ ANN401
|
||||
152 | def f(a: Optional[Any]) -> None: ...
|
||||
153 | def f(a: Annotated[Any, ...]) -> None: ...
|
||||
|
|
||||
|
||||
annotation_presence.py:152:10: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a`
|
||||
|
|
||||
150 | def f(a: int | Any) -> None: ...
|
||||
151 | def f(a: Union[str, bytes, Any]) -> None: ...
|
||||
152 | def f(a: Optional[Any]) -> None: ...
|
||||
| ^^^^^^^^^^^^^ ANN401
|
||||
153 | def f(a: Annotated[Any, ...]) -> None: ...
|
||||
154 | def f(a: "Union[str, bytes, Any]") -> None: ...
|
||||
|
|
||||
|
||||
annotation_presence.py:153:10: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a`
|
||||
|
|
||||
151 | def f(a: Union[str, bytes, Any]) -> None: ...
|
||||
152 | def f(a: Optional[Any]) -> None: ...
|
||||
153 | def f(a: Annotated[Any, ...]) -> None: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^ ANN401
|
||||
154 | def f(a: "Union[str, bytes, Any]") -> None: ...
|
||||
|
|
||||
|
||||
annotation_presence.py:154:10: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a`
|
||||
|
|
||||
152 | def f(a: Optional[Any]) -> None: ...
|
||||
153 | def f(a: Annotated[Any, ...]) -> None: ...
|
||||
154 | def f(a: "Union[str, bytes, Any]") -> None: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ ANN401
|
||||
|
|
||||
|
||||
annotation_presence.py:159:9: ANN204 [*] Missing return type annotation for special method `__init__`
|
||||
|
|
||||
157 | class Foo:
|
||||
158 | @decorator()
|
||||
159 | def __init__(self: "Foo", foo: int):
|
||||
| ^^^^^^^^ ANN204
|
||||
160 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
156 156 |
|
||||
157 157 | class Foo:
|
||||
158 158 | @decorator()
|
||||
159 |- def __init__(self: "Foo", foo: int):
|
||||
159 |+ def __init__(self: "Foo", foo: int) -> None:
|
||||
160 160 | ...
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
---
|
||||
ignore_fully_untyped.py:24:5: ANN201 Missing return type annotation for public function `error_partially_typed_1`
|
||||
|
|
||||
24 | def error_partially_typed_1(a: int, b):
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ ANN201
|
||||
25 | pass
|
||||
|
|
||||
|
||||
ignore_fully_untyped.py:24:37: ANN001 Missing type annotation for function argument `b`
|
||||
|
|
||||
24 | def error_partially_typed_1(a: int, b):
|
||||
| ^ ANN001
|
||||
25 | pass
|
||||
|
|
||||
|
||||
ignore_fully_untyped.py:28:37: ANN001 Missing type annotation for function argument `b`
|
||||
|
|
||||
28 | def error_partially_typed_2(a: int, b) -> int:
|
||||
| ^ ANN001
|
||||
29 | pass
|
||||
|
|
||||
|
||||
ignore_fully_untyped.py:32:5: ANN201 Missing return type annotation for public function `error_partially_typed_3`
|
||||
|
|
||||
32 | def error_partially_typed_3(a: int, b: int):
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ ANN201
|
||||
33 | pass
|
||||
|
|
||||
|
||||
ignore_fully_untyped.py:43:9: ANN201 Missing return type annotation for public function `error_typed_self`
|
||||
|
|
||||
41 | pass
|
||||
42 |
|
||||
43 | def error_typed_self(self: X):
|
||||
| ^^^^^^^^^^^^^^^^ ANN201
|
||||
44 | pass
|
||||
|
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
---
|
||||
mypy_init_return.py:5:9: ANN204 [*] Missing return type annotation for special method `__init__`
|
||||
|
|
||||
3 | # Error
|
||||
4 | class Foo:
|
||||
5 | def __init__(self):
|
||||
| ^^^^^^^^ ANN204
|
||||
6 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
2 2 |
|
||||
3 3 | # Error
|
||||
4 4 | class Foo:
|
||||
5 |- def __init__(self):
|
||||
5 |+ def __init__(self) -> None:
|
||||
6 6 | ...
|
||||
7 7 |
|
||||
8 8 |
|
||||
|
||||
mypy_init_return.py:11:9: ANN204 [*] Missing return type annotation for special method `__init__`
|
||||
|
|
||||
9 | # Error
|
||||
10 | class Foo:
|
||||
11 | def __init__(self, foo):
|
||||
| ^^^^^^^^ ANN204
|
||||
12 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
8 8 |
|
||||
9 9 | # Error
|
||||
10 10 | class Foo:
|
||||
11 |- def __init__(self, foo):
|
||||
11 |+ def __init__(self, foo) -> None:
|
||||
12 12 | ...
|
||||
13 13 |
|
||||
14 14 |
|
||||
|
||||
mypy_init_return.py:40:5: ANN202 Missing return type annotation for private function `__init__`
|
||||
|
|
||||
39 | # Error
|
||||
40 | def __init__(self, foo: int):
|
||||
| ^^^^^^^^ ANN202
|
||||
41 | ...
|
||||
|
|
||||
|
||||
mypy_init_return.py:47:9: ANN204 [*] Missing return type annotation for special method `__init__`
|
||||
|
|
||||
45 | # of a vararg falsely indicated that the function has a typed argument.
|
||||
46 | class Foo:
|
||||
47 | def __init__(self, *arg):
|
||||
| ^^^^^^^^ ANN204
|
||||
48 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
44 44 | # Error – used to be ok for a moment since the mere presence
|
||||
45 45 | # of a vararg falsely indicated that the function has a typed argument.
|
||||
46 46 | class Foo:
|
||||
47 |- def __init__(self, *arg):
|
||||
47 |+ def __init__(self, *arg) -> None:
|
||||
48 48 | ...
|
||||
|
||||
|
||||
@@ -1,279 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
---
|
||||
simple_magic_methods.py:2:9: ANN204 [*] Missing return type annotation for special method `__str__`
|
||||
|
|
||||
1 | class Foo:
|
||||
2 | def __str__(self):
|
||||
| ^^^^^^^ ANN204
|
||||
3 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
1 1 | class Foo:
|
||||
2 |- def __str__(self):
|
||||
2 |+ def __str__(self) -> str:
|
||||
3 3 | ...
|
||||
4 4 |
|
||||
5 5 | def __repr__(self):
|
||||
|
||||
simple_magic_methods.py:5:9: ANN204 [*] Missing return type annotation for special method `__repr__`
|
||||
|
|
||||
3 | ...
|
||||
4 |
|
||||
5 | def __repr__(self):
|
||||
| ^^^^^^^^ ANN204
|
||||
6 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
2 2 | def __str__(self):
|
||||
3 3 | ...
|
||||
4 4 |
|
||||
5 |- def __repr__(self):
|
||||
5 |+ def __repr__(self) -> str:
|
||||
6 6 | ...
|
||||
7 7 |
|
||||
8 8 | def __len__(self):
|
||||
|
||||
simple_magic_methods.py:8:9: ANN204 [*] Missing return type annotation for special method `__len__`
|
||||
|
|
||||
6 | ...
|
||||
7 |
|
||||
8 | def __len__(self):
|
||||
| ^^^^^^^ ANN204
|
||||
9 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
5 5 | def __repr__(self):
|
||||
6 6 | ...
|
||||
7 7 |
|
||||
8 |- def __len__(self):
|
||||
8 |+ def __len__(self) -> int:
|
||||
9 9 | ...
|
||||
10 10 |
|
||||
11 11 | def __length_hint__(self):
|
||||
|
||||
simple_magic_methods.py:11:9: ANN204 [*] Missing return type annotation for special method `__length_hint__`
|
||||
|
|
||||
9 | ...
|
||||
10 |
|
||||
11 | def __length_hint__(self):
|
||||
| ^^^^^^^^^^^^^^^ ANN204
|
||||
12 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
8 8 | def __len__(self):
|
||||
9 9 | ...
|
||||
10 10 |
|
||||
11 |- def __length_hint__(self):
|
||||
11 |+ def __length_hint__(self) -> int:
|
||||
12 12 | ...
|
||||
13 13 |
|
||||
14 14 | def __init__(self):
|
||||
|
||||
simple_magic_methods.py:14:9: ANN204 [*] Missing return type annotation for special method `__init__`
|
||||
|
|
||||
12 | ...
|
||||
13 |
|
||||
14 | def __init__(self):
|
||||
| ^^^^^^^^ ANN204
|
||||
15 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
11 11 | def __length_hint__(self):
|
||||
12 12 | ...
|
||||
13 13 |
|
||||
14 |- def __init__(self):
|
||||
14 |+ def __init__(self) -> None:
|
||||
15 15 | ...
|
||||
16 16 |
|
||||
17 17 | def __del__(self):
|
||||
|
||||
simple_magic_methods.py:17:9: ANN204 [*] Missing return type annotation for special method `__del__`
|
||||
|
|
||||
15 | ...
|
||||
16 |
|
||||
17 | def __del__(self):
|
||||
| ^^^^^^^ ANN204
|
||||
18 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
14 14 | def __init__(self):
|
||||
15 15 | ...
|
||||
16 16 |
|
||||
17 |- def __del__(self):
|
||||
17 |+ def __del__(self) -> None:
|
||||
18 18 | ...
|
||||
19 19 |
|
||||
20 20 | def __bool__(self):
|
||||
|
||||
simple_magic_methods.py:20:9: ANN204 [*] Missing return type annotation for special method `__bool__`
|
||||
|
|
||||
18 | ...
|
||||
19 |
|
||||
20 | def __bool__(self):
|
||||
| ^^^^^^^^ ANN204
|
||||
21 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
17 17 | def __del__(self):
|
||||
18 18 | ...
|
||||
19 19 |
|
||||
20 |- def __bool__(self):
|
||||
20 |+ def __bool__(self) -> bool:
|
||||
21 21 | ...
|
||||
22 22 |
|
||||
23 23 | def __bytes__(self):
|
||||
|
||||
simple_magic_methods.py:23:9: ANN204 [*] Missing return type annotation for special method `__bytes__`
|
||||
|
|
||||
21 | ...
|
||||
22 |
|
||||
23 | def __bytes__(self):
|
||||
| ^^^^^^^^^ ANN204
|
||||
24 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
20 20 | def __bool__(self):
|
||||
21 21 | ...
|
||||
22 22 |
|
||||
23 |- def __bytes__(self):
|
||||
23 |+ def __bytes__(self) -> bytes:
|
||||
24 24 | ...
|
||||
25 25 |
|
||||
26 26 | def __format__(self, format_spec):
|
||||
|
||||
simple_magic_methods.py:26:9: ANN204 [*] Missing return type annotation for special method `__format__`
|
||||
|
|
||||
24 | ...
|
||||
25 |
|
||||
26 | def __format__(self, format_spec):
|
||||
| ^^^^^^^^^^ ANN204
|
||||
27 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
23 23 | def __bytes__(self):
|
||||
24 24 | ...
|
||||
25 25 |
|
||||
26 |- def __format__(self, format_spec):
|
||||
26 |+ def __format__(self, format_spec) -> str:
|
||||
27 27 | ...
|
||||
28 28 |
|
||||
29 29 | def __contains__(self, item):
|
||||
|
||||
simple_magic_methods.py:29:9: ANN204 [*] Missing return type annotation for special method `__contains__`
|
||||
|
|
||||
27 | ...
|
||||
28 |
|
||||
29 | def __contains__(self, item):
|
||||
| ^^^^^^^^^^^^ ANN204
|
||||
30 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
26 26 | def __format__(self, format_spec):
|
||||
27 27 | ...
|
||||
28 28 |
|
||||
29 |- def __contains__(self, item):
|
||||
29 |+ def __contains__(self, item) -> bool:
|
||||
30 30 | ...
|
||||
31 31 |
|
||||
32 32 | def __complex__(self):
|
||||
|
||||
simple_magic_methods.py:32:9: ANN204 [*] Missing return type annotation for special method `__complex__`
|
||||
|
|
||||
30 | ...
|
||||
31 |
|
||||
32 | def __complex__(self):
|
||||
| ^^^^^^^^^^^ ANN204
|
||||
33 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
29 29 | def __contains__(self, item):
|
||||
30 30 | ...
|
||||
31 31 |
|
||||
32 |- def __complex__(self):
|
||||
32 |+ def __complex__(self) -> complex:
|
||||
33 33 | ...
|
||||
34 34 |
|
||||
35 35 | def __int__(self):
|
||||
|
||||
simple_magic_methods.py:35:9: ANN204 [*] Missing return type annotation for special method `__int__`
|
||||
|
|
||||
33 | ...
|
||||
34 |
|
||||
35 | def __int__(self):
|
||||
| ^^^^^^^ ANN204
|
||||
36 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
32 32 | def __complex__(self):
|
||||
33 33 | ...
|
||||
34 34 |
|
||||
35 |- def __int__(self):
|
||||
35 |+ def __int__(self) -> int:
|
||||
36 36 | ...
|
||||
37 37 |
|
||||
38 38 | def __float__(self):
|
||||
|
||||
simple_magic_methods.py:38:9: ANN204 [*] Missing return type annotation for special method `__float__`
|
||||
|
|
||||
36 | ...
|
||||
37 |
|
||||
38 | def __float__(self):
|
||||
| ^^^^^^^^^ ANN204
|
||||
39 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
35 35 | def __int__(self):
|
||||
36 36 | ...
|
||||
37 37 |
|
||||
38 |- def __float__(self):
|
||||
38 |+ def __float__(self) -> float:
|
||||
39 39 | ...
|
||||
40 40 |
|
||||
41 41 | def __index__(self):
|
||||
|
||||
simple_magic_methods.py:41:9: ANN204 [*] Missing return type annotation for special method `__index__`
|
||||
|
|
||||
39 | ...
|
||||
40 |
|
||||
41 | def __index__(self):
|
||||
| ^^^^^^^^^ ANN204
|
||||
42 | ...
|
||||
|
|
||||
= help: Add `None` return type
|
||||
|
||||
ℹ Suggested fix
|
||||
38 38 | def __float__(self):
|
||||
39 39 | ...
|
||||
40 40 |
|
||||
41 |- def __index__(self):
|
||||
41 |+ def __index__(self) -> int:
|
||||
42 42 | ...
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
---
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
---
|
||||
suppress_none_returning.py:45:5: ANN201 Missing return type annotation for public function `foo`
|
||||
|
|
||||
44 | # Error
|
||||
45 | def foo():
|
||||
| ^^^ ANN201
|
||||
46 | return True
|
||||
|
|
||||
|
||||
suppress_none_returning.py:50:5: ANN201 Missing return type annotation for public function `foo`
|
||||
|
|
||||
49 | # Error
|
||||
50 | def foo():
|
||||
| ^^^ ANN201
|
||||
51 | a = 2 + 2
|
||||
52 | if a == 4:
|
||||
|
|
||||
|
||||
suppress_none_returning.py:59:9: ANN001 Missing type annotation for function argument `a`
|
||||
|
|
||||
58 | # Error (on the argument, but not the return type)
|
||||
59 | def foo(a):
|
||||
| ^ ANN001
|
||||
60 | a = 2 + 2
|
||||
|
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
//! Rules from [flake8-async](https://pypi.org/project/flake8-async/).
|
||||
pub(crate) mod rules;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::assert_messages;
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::Settings;
|
||||
use crate::test::test_path;
|
||||
|
||||
#[test_case(Rule::BlockingHttpCallInAsyncFunction, Path::new("ASYNC100.py"))]
|
||||
#[test_case(Rule::OpenSleepOrSubprocessInAsyncFunction, Path::new("ASYNC101.py"))]
|
||||
#[test_case(Rule::BlockingOsCallInAsyncFunction, Path::new("ASYNC102.py"))]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_async").join(path).as_path(),
|
||||
&Settings::for_rule(rule_code),
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC100.py:7:5: ASYNC100 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
6 | async def foo():
|
||||
7 | urllib.request.urlopen("http://example.com/foo/bar").read()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ ASYNC100
|
||||
|
|
||||
|
||||
ASYNC100.py:11:5: ASYNC100 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
10 | async def foo():
|
||||
11 | requests.get()
|
||||
| ^^^^^^^^^^^^ ASYNC100
|
||||
|
|
||||
|
||||
ASYNC100.py:15:5: ASYNC100 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
14 | async def foo():
|
||||
15 | httpx.get()
|
||||
| ^^^^^^^^^ ASYNC100
|
||||
|
|
||||
|
||||
ASYNC100.py:19:5: ASYNC100 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
18 | async def foo():
|
||||
19 | requests.post()
|
||||
| ^^^^^^^^^^^^^ ASYNC100
|
||||
|
|
||||
|
||||
ASYNC100.py:23:5: ASYNC100 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
22 | async def foo():
|
||||
23 | httpx.post()
|
||||
| ^^^^^^^^^^ ASYNC100
|
||||
|
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC101.py:7:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
6 | async def foo():
|
||||
7 | open("foo")
|
||||
| ^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:11:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
10 | async def foo():
|
||||
11 | time.sleep(1)
|
||||
| ^^^^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:15:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
14 | async def foo():
|
||||
15 | subprocess.run("foo")
|
||||
| ^^^^^^^^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:19:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
18 | async def foo():
|
||||
19 | subprocess.call("foo")
|
||||
| ^^^^^^^^^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:27:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
26 | async def foo():
|
||||
27 | os.wait4(10)
|
||||
| ^^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:31:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
30 | async def foo():
|
||||
31 | os.wait(12)
|
||||
| ^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC102.py:5:5: ASYNC102 Async functions should not call synchronous `os` methods
|
||||
|
|
||||
4 | async def foo():
|
||||
5 | os.popen()
|
||||
| ^^^^^^^^ ASYNC102
|
||||
|
|
||||
|
||||
ASYNC102.py:9:5: ASYNC102 Async functions should not call synchronous `os` methods
|
||||
|
|
||||
8 | async def foo():
|
||||
9 | os.spawnl()
|
||||
| ^^^^^^^^^ ASYNC102
|
||||
|
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
//! Rules from [flake8-bandit](https://pypi.org/project/flake8-bandit/).
|
||||
mod helpers;
|
||||
pub(crate) mod rules;
|
||||
pub mod settings;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::assert_messages;
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::Settings;
|
||||
use crate::test::test_path;
|
||||
|
||||
#[test_case(Rule::Assert, Path::new("S101.py"))]
|
||||
#[test_case(Rule::BadFilePermissions, Path::new("S103.py"))]
|
||||
#[test_case(Rule::CallWithShellEqualsTrue, Path::new("S604.py"))]
|
||||
#[test_case(Rule::ExecBuiltin, Path::new("S102.py"))]
|
||||
#[test_case(Rule::HardcodedBindAllInterfaces, Path::new("S104.py"))]
|
||||
#[test_case(Rule::HardcodedPasswordDefault, Path::new("S107.py"))]
|
||||
#[test_case(Rule::HardcodedPasswordFuncArg, Path::new("S106.py"))]
|
||||
#[test_case(Rule::HardcodedPasswordString, Path::new("S105.py"))]
|
||||
#[test_case(Rule::HardcodedSQLExpression, Path::new("S608.py"))]
|
||||
#[test_case(Rule::HardcodedTempFile, Path::new("S108.py"))]
|
||||
#[test_case(Rule::HashlibInsecureHashFunction, Path::new("S324.py"))]
|
||||
#[test_case(Rule::Jinja2AutoescapeFalse, Path::new("S701.py"))]
|
||||
#[test_case(Rule::LoggingConfigInsecureListen, Path::new("S612.py"))]
|
||||
#[test_case(Rule::ParamikoCall, Path::new("S601.py"))]
|
||||
#[test_case(Rule::RequestWithNoCertValidation, Path::new("S501.py"))]
|
||||
#[test_case(Rule::RequestWithoutTimeout, Path::new("S113.py"))]
|
||||
#[test_case(Rule::SnmpInsecureVersion, Path::new("S508.py"))]
|
||||
#[test_case(Rule::SnmpWeakCryptography, Path::new("S509.py"))]
|
||||
#[test_case(Rule::StartProcessWithAShell, Path::new("S605.py"))]
|
||||
#[test_case(Rule::StartProcessWithNoShell, Path::new("S606.py"))]
|
||||
#[test_case(Rule::StartProcessWithPartialPath, Path::new("S607.py"))]
|
||||
#[test_case(Rule::SubprocessPopenWithShellEqualsTrue, Path::new("S602.py"))]
|
||||
#[test_case(Rule::SubprocessWithoutShellEqualsTrue, Path::new("S603.py"))]
|
||||
#[test_case(Rule::SuspiciousPickleUsage, Path::new("S301.py"))]
|
||||
#[test_case(Rule::SuspiciousEvalUsage, Path::new("S307.py"))]
|
||||
#[test_case(Rule::SuspiciousTelnetUsage, Path::new("S312.py"))]
|
||||
#[test_case(Rule::TryExceptContinue, Path::new("S112.py"))]
|
||||
#[test_case(Rule::TryExceptPass, Path::new("S110.py"))]
|
||||
#[test_case(Rule::UnixCommandWildcardInjection, Path::new("S609.py"))]
|
||||
#[test_case(Rule::UnsafeYAMLLoad, Path::new("S506.py"))]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_bandit").join(path).as_path(),
|
||||
&Settings::for_rule(rule_code),
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_hardcoded_tmp_additional_dirs() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_bandit/S108.py"),
|
||||
&Settings {
|
||||
flake8_bandit: super::settings::Settings {
|
||||
hardcoded_tmp_directory: vec![
|
||||
"/tmp".to_string(),
|
||||
"/var/tmp".to_string(),
|
||||
"/dev/shm".to_string(),
|
||||
"/foo".to_string(),
|
||||
],
|
||||
check_typed_exception: false,
|
||||
},
|
||||
..Settings::for_rule(Rule::HardcodedTempFile)
|
||||
},
|
||||
)?;
|
||||
assert_messages!("S108_extend", diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_typed_exception() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_bandit/S110.py"),
|
||||
&Settings {
|
||||
flake8_bandit: super::settings::Settings {
|
||||
check_typed_exception: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Settings::for_rule(Rule::TryExceptPass)
|
||||
},
|
||||
)?;
|
||||
assert_messages!("S110_typed", diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
pub(crate) use assert_used::*;
|
||||
pub(crate) use bad_file_permissions::*;
|
||||
pub(crate) use exec_used::*;
|
||||
pub(crate) use hardcoded_bind_all_interfaces::*;
|
||||
pub(crate) use hardcoded_password_default::*;
|
||||
pub(crate) use hardcoded_password_func_arg::*;
|
||||
pub(crate) use hardcoded_password_string::*;
|
||||
pub(crate) use hardcoded_sql_expression::*;
|
||||
pub(crate) use hardcoded_tmp_directory::*;
|
||||
pub(crate) use hashlib_insecure_hash_functions::*;
|
||||
pub(crate) use jinja2_autoescape_false::*;
|
||||
pub(crate) use logging_config_insecure_listen::*;
|
||||
pub(crate) use paramiko_calls::*;
|
||||
pub(crate) use request_with_no_cert_validation::*;
|
||||
pub(crate) use request_without_timeout::*;
|
||||
pub(crate) use shell_injection::*;
|
||||
pub(crate) use snmp_insecure_version::*;
|
||||
pub(crate) use snmp_weak_cryptography::*;
|
||||
pub(crate) use suspicious_function_call::*;
|
||||
pub(crate) use try_except_continue::*;
|
||||
pub(crate) use try_except_pass::*;
|
||||
pub(crate) use unsafe_yaml_load::*;
|
||||
|
||||
mod assert_used;
|
||||
mod bad_file_permissions;
|
||||
mod exec_used;
|
||||
mod hardcoded_bind_all_interfaces;
|
||||
mod hardcoded_password_default;
|
||||
mod hardcoded_password_func_arg;
|
||||
mod hardcoded_password_string;
|
||||
mod hardcoded_sql_expression;
|
||||
mod hardcoded_tmp_directory;
|
||||
mod hashlib_insecure_hash_functions;
|
||||
mod jinja2_autoescape_false;
|
||||
mod logging_config_insecure_listen;
|
||||
mod paramiko_calls;
|
||||
mod request_with_no_cert_validation;
|
||||
mod request_without_timeout;
|
||||
mod shell_injection;
|
||||
mod snmp_insecure_version;
|
||||
mod snmp_weak_cryptography;
|
||||
mod suspicious_function_call;
|
||||
mod try_except_continue;
|
||||
mod try_except_pass;
|
||||
mod unsafe_yaml_load;
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S101.py:1:1: S101 Use of `assert` detected
|
||||
|
|
||||
1 | assert True # S101
|
||||
| ^^^^^^ S101
|
||||
|
|
||||
|
||||
S101.py:6:5: S101 Use of `assert` detected
|
||||
|
|
||||
4 | def fn():
|
||||
5 | x = 1
|
||||
6 | assert x == 1 # S101
|
||||
| ^^^^^^ S101
|
||||
7 | assert x == 2 # S101
|
||||
|
|
||||
|
||||
S101.py:7:5: S101 Use of `assert` detected
|
||||
|
|
||||
5 | x = 1
|
||||
6 | assert x == 1 # S101
|
||||
7 | assert x == 2 # S101
|
||||
| ^^^^^^ S101
|
||||
|
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S102.py:3:5: S102 Use of `exec` detected
|
||||
|
|
||||
1 | def fn():
|
||||
2 | # Error
|
||||
3 | exec('x = 2')
|
||||
| ^^^^ S102
|
||||
4 |
|
||||
5 | exec('y = 3')
|
||||
|
|
||||
|
||||
S102.py:5:1: S102 Use of `exec` detected
|
||||
|
|
||||
3 | exec('x = 2')
|
||||
4 |
|
||||
5 | exec('y = 3')
|
||||
| ^^^^ S102
|
||||
|
|
||||
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S103.py:6:25: S103 `os.chmod` setting a permissive mask `0o227` on file or directory
|
||||
|
|
||||
4 | keyfile = "foo"
|
||||
5 |
|
||||
6 | os.chmod("/etc/passwd", 0o227) # Error
|
||||
| ^^^^^ S103
|
||||
7 | os.chmod("/etc/passwd", 0o7) # Error
|
||||
8 | os.chmod("/etc/passwd", 0o664) # OK
|
||||
|
|
||||
|
||||
S103.py:7:25: S103 `os.chmod` setting a permissive mask `0o7` on file or directory
|
||||
|
|
||||
6 | os.chmod("/etc/passwd", 0o227) # Error
|
||||
7 | os.chmod("/etc/passwd", 0o7) # Error
|
||||
| ^^^ S103
|
||||
8 | os.chmod("/etc/passwd", 0o664) # OK
|
||||
9 | os.chmod("/etc/passwd", 0o777) # Error
|
||||
|
|
||||
|
||||
S103.py:9:25: S103 `os.chmod` setting a permissive mask `0o777` on file or directory
|
||||
|
|
||||
7 | os.chmod("/etc/passwd", 0o7) # Error
|
||||
8 | os.chmod("/etc/passwd", 0o664) # OK
|
||||
9 | os.chmod("/etc/passwd", 0o777) # Error
|
||||
| ^^^^^ S103
|
||||
10 | os.chmod("/etc/passwd", 0o770) # Error
|
||||
11 | os.chmod("/etc/passwd", 0o776) # Error
|
||||
|
|
||||
|
||||
S103.py:10:25: S103 `os.chmod` setting a permissive mask `0o770` on file or directory
|
||||
|
|
||||
8 | os.chmod("/etc/passwd", 0o664) # OK
|
||||
9 | os.chmod("/etc/passwd", 0o777) # Error
|
||||
10 | os.chmod("/etc/passwd", 0o770) # Error
|
||||
| ^^^^^ S103
|
||||
11 | os.chmod("/etc/passwd", 0o776) # Error
|
||||
12 | os.chmod("/etc/passwd", 0o760) # OK
|
||||
|
|
||||
|
||||
S103.py:11:25: S103 `os.chmod` setting a permissive mask `0o776` on file or directory
|
||||
|
|
||||
9 | os.chmod("/etc/passwd", 0o777) # Error
|
||||
10 | os.chmod("/etc/passwd", 0o770) # Error
|
||||
11 | os.chmod("/etc/passwd", 0o776) # Error
|
||||
| ^^^^^ S103
|
||||
12 | os.chmod("/etc/passwd", 0o760) # OK
|
||||
13 | os.chmod("~/.bashrc", 511) # Error
|
||||
|
|
||||
|
||||
S103.py:13:23: S103 `os.chmod` setting a permissive mask `0o777` on file or directory
|
||||
|
|
||||
11 | os.chmod("/etc/passwd", 0o776) # Error
|
||||
12 | os.chmod("/etc/passwd", 0o760) # OK
|
||||
13 | os.chmod("~/.bashrc", 511) # Error
|
||||
| ^^^ S103
|
||||
14 | os.chmod("/etc/hosts", 0o777) # Error
|
||||
15 | os.chmod("/tmp/oh_hai", 0x1FF) # Error
|
||||
|
|
||||
|
||||
S103.py:14:24: S103 `os.chmod` setting a permissive mask `0o777` on file or directory
|
||||
|
|
||||
12 | os.chmod("/etc/passwd", 0o760) # OK
|
||||
13 | os.chmod("~/.bashrc", 511) # Error
|
||||
14 | os.chmod("/etc/hosts", 0o777) # Error
|
||||
| ^^^^^ S103
|
||||
15 | os.chmod("/tmp/oh_hai", 0x1FF) # Error
|
||||
16 | os.chmod("/etc/passwd", stat.S_IRWXU) # OK
|
||||
|
|
||||
|
||||
S103.py:15:25: S103 `os.chmod` setting a permissive mask `0o777` on file or directory
|
||||
|
|
||||
13 | os.chmod("~/.bashrc", 511) # Error
|
||||
14 | os.chmod("/etc/hosts", 0o777) # Error
|
||||
15 | os.chmod("/tmp/oh_hai", 0x1FF) # Error
|
||||
| ^^^^^ S103
|
||||
16 | os.chmod("/etc/passwd", stat.S_IRWXU) # OK
|
||||
17 | os.chmod(keyfile, 0o777) # Error
|
||||
|
|
||||
|
||||
S103.py:17:19: S103 `os.chmod` setting a permissive mask `0o777` on file or directory
|
||||
|
|
||||
15 | os.chmod("/tmp/oh_hai", 0x1FF) # Error
|
||||
16 | os.chmod("/etc/passwd", stat.S_IRWXU) # OK
|
||||
17 | os.chmod(keyfile, 0o777) # Error
|
||||
| ^^^^^ S103
|
||||
18 | os.chmod(keyfile, 0o7 | 0o70 | 0o700) # Error
|
||||
19 | os.chmod(keyfile, stat.S_IRWXO | stat.S_IRWXG | stat.S_IRWXU) # Error
|
||||
|
|
||||
|
||||
S103.py:18:19: S103 `os.chmod` setting a permissive mask `0o777` on file or directory
|
||||
|
|
||||
16 | os.chmod("/etc/passwd", stat.S_IRWXU) # OK
|
||||
17 | os.chmod(keyfile, 0o777) # Error
|
||||
18 | os.chmod(keyfile, 0o7 | 0o70 | 0o700) # Error
|
||||
| ^^^^^^^^^^^^^^^^^^ S103
|
||||
19 | os.chmod(keyfile, stat.S_IRWXO | stat.S_IRWXG | stat.S_IRWXU) # Error
|
||||
20 | os.chmod("~/hidden_exec", stat.S_IXGRP) # Error
|
||||
|
|
||||
|
||||
S103.py:19:19: S103 `os.chmod` setting a permissive mask `0o777` on file or directory
|
||||
|
|
||||
17 | os.chmod(keyfile, 0o777) # Error
|
||||
18 | os.chmod(keyfile, 0o7 | 0o70 | 0o700) # Error
|
||||
19 | os.chmod(keyfile, stat.S_IRWXO | stat.S_IRWXG | stat.S_IRWXU) # Error
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S103
|
||||
20 | os.chmod("~/hidden_exec", stat.S_IXGRP) # Error
|
||||
21 | os.chmod("~/hidden_exec", stat.S_IXOTH) # OK
|
||||
|
|
||||
|
||||
S103.py:20:27: S103 `os.chmod` setting a permissive mask `0o10` on file or directory
|
||||
|
|
||||
18 | os.chmod(keyfile, 0o7 | 0o70 | 0o700) # Error
|
||||
19 | os.chmod(keyfile, stat.S_IRWXO | stat.S_IRWXG | stat.S_IRWXU) # Error
|
||||
20 | os.chmod("~/hidden_exec", stat.S_IXGRP) # Error
|
||||
| ^^^^^^^^^^^^ S103
|
||||
21 | os.chmod("~/hidden_exec", stat.S_IXOTH) # OK
|
||||
22 | os.chmod("/etc/passwd", stat.S_IWOTH) # Error
|
||||
|
|
||||
|
||||
S103.py:22:25: S103 `os.chmod` setting a permissive mask `0o2` on file or directory
|
||||
|
|
||||
20 | os.chmod("~/hidden_exec", stat.S_IXGRP) # Error
|
||||
21 | os.chmod("~/hidden_exec", stat.S_IXOTH) # OK
|
||||
22 | os.chmod("/etc/passwd", stat.S_IWOTH) # Error
|
||||
| ^^^^^^^^^^^^ S103
|
||||
|
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S104.py:9:1: S104 Possible binding to all interfaces
|
||||
|
|
||||
8 | # Error
|
||||
9 | "0.0.0.0"
|
||||
| ^^^^^^^^^ S104
|
||||
10 | '0.0.0.0'
|
||||
|
|
||||
|
||||
S104.py:10:1: S104 Possible binding to all interfaces
|
||||
|
|
||||
8 | # Error
|
||||
9 | "0.0.0.0"
|
||||
10 | '0.0.0.0'
|
||||
| ^^^^^^^^^ S104
|
||||
|
|
||||
|
||||
S104.py:14:6: S104 Possible binding to all interfaces
|
||||
|
|
||||
13 | # Error
|
||||
14 | func("0.0.0.0")
|
||||
| ^^^^^^^^^ S104
|
||||
|
|
||||
|
||||
S104.py:18:9: S104 Possible binding to all interfaces
|
||||
|
|
||||
17 | def my_func():
|
||||
18 | x = "0.0.0.0"
|
||||
| ^^^^^^^^^ S104
|
||||
19 | print(x)
|
||||
|
|
||||
|
||||
|
||||
@@ -1,377 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S105.py:13:12: S105 Possible hardcoded password assigned to: "password"
|
||||
|
|
||||
12 | # Errors
|
||||
13 | password = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
14 | _pass = "s3cr3t"
|
||||
15 | passwd = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:14:9: S105 Possible hardcoded password assigned to: "_pass"
|
||||
|
|
||||
12 | # Errors
|
||||
13 | password = "s3cr3t"
|
||||
14 | _pass = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
15 | passwd = "s3cr3t"
|
||||
16 | pwd = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:15:10: S105 Possible hardcoded password assigned to: "passwd"
|
||||
|
|
||||
13 | password = "s3cr3t"
|
||||
14 | _pass = "s3cr3t"
|
||||
15 | passwd = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
16 | pwd = "s3cr3t"
|
||||
17 | secret = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:16:7: S105 Possible hardcoded password assigned to: "pwd"
|
||||
|
|
||||
14 | _pass = "s3cr3t"
|
||||
15 | passwd = "s3cr3t"
|
||||
16 | pwd = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
17 | secret = "s3cr3t"
|
||||
18 | token = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:17:10: S105 Possible hardcoded password assigned to: "secret"
|
||||
|
|
||||
15 | passwd = "s3cr3t"
|
||||
16 | pwd = "s3cr3t"
|
||||
17 | secret = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
18 | token = "s3cr3t"
|
||||
19 | secrete = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:18:9: S105 Possible hardcoded password assigned to: "token"
|
||||
|
|
||||
16 | pwd = "s3cr3t"
|
||||
17 | secret = "s3cr3t"
|
||||
18 | token = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
19 | secrete = "s3cr3t"
|
||||
20 | safe = password = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:19:11: S105 Possible hardcoded password assigned to: "secrete"
|
||||
|
|
||||
17 | secret = "s3cr3t"
|
||||
18 | token = "s3cr3t"
|
||||
19 | secrete = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
20 | safe = password = "s3cr3t"
|
||||
21 | password = safe = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:20:19: S105 Possible hardcoded password assigned to: "password"
|
||||
|
|
||||
18 | token = "s3cr3t"
|
||||
19 | secrete = "s3cr3t"
|
||||
20 | safe = password = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
21 | password = safe = "s3cr3t"
|
||||
22 | PASSWORD = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:21:19: S105 Possible hardcoded password assigned to: "password"
|
||||
|
|
||||
19 | secrete = "s3cr3t"
|
||||
20 | safe = password = "s3cr3t"
|
||||
21 | password = safe = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
22 | PASSWORD = "s3cr3t"
|
||||
23 | PassWord = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:22:12: S105 Possible hardcoded password assigned to: "PASSWORD"
|
||||
|
|
||||
20 | safe = password = "s3cr3t"
|
||||
21 | password = safe = "s3cr3t"
|
||||
22 | PASSWORD = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
23 | PassWord = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:23:12: S105 Possible hardcoded password assigned to: "PassWord"
|
||||
|
|
||||
21 | password = safe = "s3cr3t"
|
||||
22 | PASSWORD = "s3cr3t"
|
||||
23 | PassWord = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
24 |
|
||||
25 | d["password"] = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:25:17: S105 Possible hardcoded password assigned to: "password"
|
||||
|
|
||||
23 | PassWord = "s3cr3t"
|
||||
24 |
|
||||
25 | d["password"] = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
26 | d["pass"] = "s3cr3t"
|
||||
27 | d["passwd"] = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:26:13: S105 Possible hardcoded password assigned to: "pass"
|
||||
|
|
||||
25 | d["password"] = "s3cr3t"
|
||||
26 | d["pass"] = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
27 | d["passwd"] = "s3cr3t"
|
||||
28 | d["pwd"] = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:27:15: S105 Possible hardcoded password assigned to: "passwd"
|
||||
|
|
||||
25 | d["password"] = "s3cr3t"
|
||||
26 | d["pass"] = "s3cr3t"
|
||||
27 | d["passwd"] = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
28 | d["pwd"] = "s3cr3t"
|
||||
29 | d["secret"] = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:28:12: S105 Possible hardcoded password assigned to: "pwd"
|
||||
|
|
||||
26 | d["pass"] = "s3cr3t"
|
||||
27 | d["passwd"] = "s3cr3t"
|
||||
28 | d["pwd"] = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
29 | d["secret"] = "s3cr3t"
|
||||
30 | d["token"] = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:29:15: S105 Possible hardcoded password assigned to: "secret"
|
||||
|
|
||||
27 | d["passwd"] = "s3cr3t"
|
||||
28 | d["pwd"] = "s3cr3t"
|
||||
29 | d["secret"] = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
30 | d["token"] = "s3cr3t"
|
||||
31 | d["secrete"] = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:30:14: S105 Possible hardcoded password assigned to: "token"
|
||||
|
|
||||
28 | d["pwd"] = "s3cr3t"
|
||||
29 | d["secret"] = "s3cr3t"
|
||||
30 | d["token"] = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
31 | d["secrete"] = "s3cr3t"
|
||||
32 | safe = d["password"] = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:31:16: S105 Possible hardcoded password assigned to: "secrete"
|
||||
|
|
||||
29 | d["secret"] = "s3cr3t"
|
||||
30 | d["token"] = "s3cr3t"
|
||||
31 | d["secrete"] = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
32 | safe = d["password"] = "s3cr3t"
|
||||
33 | d["password"] = safe = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:32:24: S105 Possible hardcoded password assigned to: "password"
|
||||
|
|
||||
30 | d["token"] = "s3cr3t"
|
||||
31 | d["secrete"] = "s3cr3t"
|
||||
32 | safe = d["password"] = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
33 | d["password"] = safe = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:33:24: S105 Possible hardcoded password assigned to: "password"
|
||||
|
|
||||
31 | d["secrete"] = "s3cr3t"
|
||||
32 | safe = d["password"] = "s3cr3t"
|
||||
33 | d["password"] = safe = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
|
|
||||
|
||||
S105.py:37:16: S105 Possible hardcoded password assigned to: "password"
|
||||
|
|
||||
36 | class MyClass:
|
||||
37 | password = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
38 | safe = password
|
||||
|
|
||||
|
||||
S105.py:41:20: S105 Possible hardcoded password assigned to: "password"
|
||||
|
|
||||
41 | MyClass.password = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
42 | MyClass._pass = "s3cr3t"
|
||||
43 | MyClass.passwd = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:42:17: S105 Possible hardcoded password assigned to: "_pass"
|
||||
|
|
||||
41 | MyClass.password = "s3cr3t"
|
||||
42 | MyClass._pass = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
43 | MyClass.passwd = "s3cr3t"
|
||||
44 | MyClass.pwd = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:43:18: S105 Possible hardcoded password assigned to: "passwd"
|
||||
|
|
||||
41 | MyClass.password = "s3cr3t"
|
||||
42 | MyClass._pass = "s3cr3t"
|
||||
43 | MyClass.passwd = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
44 | MyClass.pwd = "s3cr3t"
|
||||
45 | MyClass.secret = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:44:15: S105 Possible hardcoded password assigned to: "pwd"
|
||||
|
|
||||
42 | MyClass._pass = "s3cr3t"
|
||||
43 | MyClass.passwd = "s3cr3t"
|
||||
44 | MyClass.pwd = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
45 | MyClass.secret = "s3cr3t"
|
||||
46 | MyClass.token = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:45:18: S105 Possible hardcoded password assigned to: "secret"
|
||||
|
|
||||
43 | MyClass.passwd = "s3cr3t"
|
||||
44 | MyClass.pwd = "s3cr3t"
|
||||
45 | MyClass.secret = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
46 | MyClass.token = "s3cr3t"
|
||||
47 | MyClass.secrete = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:46:17: S105 Possible hardcoded password assigned to: "token"
|
||||
|
|
||||
44 | MyClass.pwd = "s3cr3t"
|
||||
45 | MyClass.secret = "s3cr3t"
|
||||
46 | MyClass.token = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
47 | MyClass.secrete = "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:47:19: S105 Possible hardcoded password assigned to: "secrete"
|
||||
|
|
||||
45 | MyClass.secret = "s3cr3t"
|
||||
46 | MyClass.token = "s3cr3t"
|
||||
47 | MyClass.secrete = "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
48 |
|
||||
49 | password == "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:49:13: S105 Possible hardcoded password assigned to: "password"
|
||||
|
|
||||
47 | MyClass.secrete = "s3cr3t"
|
||||
48 |
|
||||
49 | password == "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
50 | _pass == "s3cr3t"
|
||||
51 | passwd == "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:50:10: S105 Possible hardcoded password assigned to: "_pass"
|
||||
|
|
||||
49 | password == "s3cr3t"
|
||||
50 | _pass == "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
51 | passwd == "s3cr3t"
|
||||
52 | pwd == "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:51:11: S105 Possible hardcoded password assigned to: "passwd"
|
||||
|
|
||||
49 | password == "s3cr3t"
|
||||
50 | _pass == "s3cr3t"
|
||||
51 | passwd == "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
52 | pwd == "s3cr3t"
|
||||
53 | secret == "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:52:8: S105 Possible hardcoded password assigned to: "pwd"
|
||||
|
|
||||
50 | _pass == "s3cr3t"
|
||||
51 | passwd == "s3cr3t"
|
||||
52 | pwd == "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
53 | secret == "s3cr3t"
|
||||
54 | token == "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:53:11: S105 Possible hardcoded password assigned to: "secret"
|
||||
|
|
||||
51 | passwd == "s3cr3t"
|
||||
52 | pwd == "s3cr3t"
|
||||
53 | secret == "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
54 | token == "s3cr3t"
|
||||
55 | secrete == "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:54:10: S105 Possible hardcoded password assigned to: "token"
|
||||
|
|
||||
52 | pwd == "s3cr3t"
|
||||
53 | secret == "s3cr3t"
|
||||
54 | token == "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
55 | secrete == "s3cr3t"
|
||||
56 | password == safe == "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:55:12: S105 Possible hardcoded password assigned to: "secrete"
|
||||
|
|
||||
53 | secret == "s3cr3t"
|
||||
54 | token == "s3cr3t"
|
||||
55 | secrete == "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
56 | password == safe == "s3cr3t"
|
||||
|
|
||||
|
||||
S105.py:56:21: S105 Possible hardcoded password assigned to: "password"
|
||||
|
|
||||
54 | token == "s3cr3t"
|
||||
55 | secrete == "s3cr3t"
|
||||
56 | password == safe == "s3cr3t"
|
||||
| ^^^^^^^^ S105
|
||||
57 |
|
||||
58 | if token == "1\n2":
|
||||
|
|
||||
|
||||
S105.py:58:13: S105 Possible hardcoded password assigned to: "token"
|
||||
|
|
||||
56 | password == safe == "s3cr3t"
|
||||
57 |
|
||||
58 | if token == "1\n2":
|
||||
| ^^^^^^ S105
|
||||
59 | pass
|
||||
|
|
||||
|
||||
S105.py:61:13: S105 Possible hardcoded password assigned to: "token"
|
||||
|
|
||||
59 | pass
|
||||
60 |
|
||||
61 | if token == "3\t4":
|
||||
| ^^^^^^ S105
|
||||
62 | pass
|
||||
|
|
||||
|
||||
S105.py:64:13: S105 Possible hardcoded password assigned to: "token"
|
||||
|
|
||||
62 | pass
|
||||
63 |
|
||||
64 | if token == "5\r6":
|
||||
| ^^^^^^ S105
|
||||
65 | pass
|
||||
|
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S106.py:14:9: S106 Possible hardcoded password assigned to argument: "password"
|
||||
|
|
||||
13 | # Error
|
||||
14 | func(1, password="s3cr3t")
|
||||
| ^^^^^^^^^^^^^^^^^ S106
|
||||
|
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S107.py:5:29: S107 Possible hardcoded password assigned to function default: "password"
|
||||
|
|
||||
5 | def default(first, password="default"):
|
||||
| ^^^^^^^^^ S107
|
||||
6 | pass
|
||||
|
|
||||
|
||||
S107.py:13:45: S107 Possible hardcoded password assigned to function default: "password"
|
||||
|
|
||||
13 | def default_posonly(first, /, pos, password="posonly"):
|
||||
| ^^^^^^^^^ S107
|
||||
14 | pass
|
||||
|
|
||||
|
||||
S107.py:21:39: S107 Possible hardcoded password assigned to function default: "password"
|
||||
|
|
||||
21 | def default_kwonly(first, *, password="kwonly"):
|
||||
| ^^^^^^^^ S107
|
||||
22 | pass
|
||||
|
|
||||
|
||||
S107.py:29:39: S107 Possible hardcoded password assigned to function default: "secret"
|
||||
|
|
||||
29 | def default_all(first, /, pos, secret="posonly", *, password="kwonly"):
|
||||
| ^^^^^^^^^ S107
|
||||
30 | pass
|
||||
|
|
||||
|
||||
S107.py:29:62: S107 Possible hardcoded password assigned to function default: "password"
|
||||
|
|
||||
29 | def default_all(first, /, pos, secret="posonly", *, password="kwonly"):
|
||||
| ^^^^^^^^ S107
|
||||
30 | pass
|
||||
|
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S108.py:5:11: S108 Probable insecure usage of temporary file or directory: "/tmp/abc"
|
||||
|
|
||||
3 | f.write("def")
|
||||
4 |
|
||||
5 | with open("/tmp/abc", "w") as f:
|
||||
| ^^^^^^^^^^ S108
|
||||
6 | f.write("def")
|
||||
|
|
||||
|
||||
S108.py:8:11: S108 Probable insecure usage of temporary file or directory: "/var/tmp/123"
|
||||
|
|
||||
6 | f.write("def")
|
||||
7 |
|
||||
8 | with open("/var/tmp/123", "w") as f:
|
||||
| ^^^^^^^^^^^^^^ S108
|
||||
9 | f.write("def")
|
||||
|
|
||||
|
||||
S108.py:11:11: S108 Probable insecure usage of temporary file or directory: "/dev/shm/unit/test"
|
||||
|
|
||||
9 | f.write("def")
|
||||
10 |
|
||||
11 | with open("/dev/shm/unit/test", "w") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^^^ S108
|
||||
12 | f.write("def")
|
||||
|
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S108.py:5:11: S108 Probable insecure usage of temporary file or directory: "/tmp/abc"
|
||||
|
|
||||
3 | f.write("def")
|
||||
4 |
|
||||
5 | with open("/tmp/abc", "w") as f:
|
||||
| ^^^^^^^^^^ S108
|
||||
6 | f.write("def")
|
||||
|
|
||||
|
||||
S108.py:8:11: S108 Probable insecure usage of temporary file or directory: "/var/tmp/123"
|
||||
|
|
||||
6 | f.write("def")
|
||||
7 |
|
||||
8 | with open("/var/tmp/123", "w") as f:
|
||||
| ^^^^^^^^^^^^^^ S108
|
||||
9 | f.write("def")
|
||||
|
|
||||
|
||||
S108.py:11:11: S108 Probable insecure usage of temporary file or directory: "/dev/shm/unit/test"
|
||||
|
|
||||
9 | f.write("def")
|
||||
10 |
|
||||
11 | with open("/dev/shm/unit/test", "w") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^^^ S108
|
||||
12 | f.write("def")
|
||||
|
|
||||
|
||||
S108.py:15:11: S108 Probable insecure usage of temporary file or directory: "/foo/bar"
|
||||
|
|
||||
14 | # not ok by config
|
||||
15 | with open("/foo/bar", "w") as f:
|
||||
| ^^^^^^^^^^ S108
|
||||
16 | f.write("def")
|
||||
|
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S110.py:3:1: S110 `try`-`except`-`pass` detected, consider logging the exception
|
||||
|
|
||||
1 | try:
|
||||
2 | pass
|
||||
3 | / except Exception:
|
||||
4 | | pass
|
||||
| |________^ S110
|
||||
5 |
|
||||
6 | try:
|
||||
|
|
||||
|
||||
S110.py:8:1: S110 `try`-`except`-`pass` detected, consider logging the exception
|
||||
|
|
||||
6 | try:
|
||||
7 | pass
|
||||
8 | / except:
|
||||
9 | | pass
|
||||
| |________^ S110
|
||||
10 |
|
||||
11 | try:
|
||||
|
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S110.py:3:1: S110 `try`-`except`-`pass` detected, consider logging the exception
|
||||
|
|
||||
1 | try:
|
||||
2 | pass
|
||||
3 | / except Exception:
|
||||
4 | | pass
|
||||
| |________^ S110
|
||||
5 |
|
||||
6 | try:
|
||||
|
|
||||
|
||||
S110.py:8:1: S110 `try`-`except`-`pass` detected, consider logging the exception
|
||||
|
|
||||
6 | try:
|
||||
7 | pass
|
||||
8 | / except:
|
||||
9 | | pass
|
||||
| |________^ S110
|
||||
10 |
|
||||
11 | try:
|
||||
|
|
||||
|
||||
S110.py:13:1: S110 `try`-`except`-`pass` detected, consider logging the exception
|
||||
|
|
||||
11 | try:
|
||||
12 | pass
|
||||
13 | / except ValueError:
|
||||
14 | | pass
|
||||
| |________^ S110
|
||||
|
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S112.py:3:1: S112 `try`-`except`-`continue` detected, consider logging the exception
|
||||
|
|
||||
1 | try:
|
||||
2 | pass
|
||||
3 | / except Exception:
|
||||
4 | | continue
|
||||
| |____________^ S112
|
||||
5 |
|
||||
6 | try:
|
||||
|
|
||||
|
||||
S112.py:8:1: S112 `try`-`except`-`continue` detected, consider logging the exception
|
||||
|
|
||||
6 | try:
|
||||
7 | pass
|
||||
8 | / except:
|
||||
9 | | continue
|
||||
| |____________^ S112
|
||||
10 |
|
||||
11 | try:
|
||||
|
|
||||
|
||||
S112.py:13:1: S112 `try`-`except`-`continue` detected, consider logging the exception
|
||||
|
|
||||
11 | try:
|
||||
12 | pass
|
||||
13 | / except (Exception,):
|
||||
14 | | continue
|
||||
| |____________^ S112
|
||||
15 |
|
||||
16 | try:
|
||||
|
|
||||
|
||||
S112.py:18:1: S112 `try`-`except`-`continue` detected, consider logging the exception
|
||||
|
|
||||
16 | try:
|
||||
17 | pass
|
||||
18 | / except (Exception, ValueError):
|
||||
19 | | continue
|
||||
| |____________^ S112
|
||||
20 |
|
||||
21 | try:
|
||||
|
|
||||
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S113.py:3:1: S113 Probable use of requests call without timeout
|
||||
|
|
||||
1 | import requests
|
||||
2 |
|
||||
3 | requests.get('https://gmail.com')
|
||||
| ^^^^^^^^^^^^ S113
|
||||
4 | requests.get('https://gmail.com', timeout=None)
|
||||
5 | requests.get('https://gmail.com', timeout=5)
|
||||
|
|
||||
|
||||
S113.py:4:35: S113 Probable use of requests call with timeout set to `None`
|
||||
|
|
||||
3 | requests.get('https://gmail.com')
|
||||
4 | requests.get('https://gmail.com', timeout=None)
|
||||
| ^^^^^^^^^^^^ S113
|
||||
5 | requests.get('https://gmail.com', timeout=5)
|
||||
6 | requests.post('https://gmail.com')
|
||||
|
|
||||
|
||||
S113.py:6:1: S113 Probable use of requests call without timeout
|
||||
|
|
||||
4 | requests.get('https://gmail.com', timeout=None)
|
||||
5 | requests.get('https://gmail.com', timeout=5)
|
||||
6 | requests.post('https://gmail.com')
|
||||
| ^^^^^^^^^^^^^ S113
|
||||
7 | requests.post('https://gmail.com', timeout=None)
|
||||
8 | requests.post('https://gmail.com', timeout=5)
|
||||
|
|
||||
|
||||
S113.py:7:36: S113 Probable use of requests call with timeout set to `None`
|
||||
|
|
||||
5 | requests.get('https://gmail.com', timeout=5)
|
||||
6 | requests.post('https://gmail.com')
|
||||
7 | requests.post('https://gmail.com', timeout=None)
|
||||
| ^^^^^^^^^^^^ S113
|
||||
8 | requests.post('https://gmail.com', timeout=5)
|
||||
9 | requests.put('https://gmail.com')
|
||||
|
|
||||
|
||||
S113.py:9:1: S113 Probable use of requests call without timeout
|
||||
|
|
||||
7 | requests.post('https://gmail.com', timeout=None)
|
||||
8 | requests.post('https://gmail.com', timeout=5)
|
||||
9 | requests.put('https://gmail.com')
|
||||
| ^^^^^^^^^^^^ S113
|
||||
10 | requests.put('https://gmail.com', timeout=None)
|
||||
11 | requests.put('https://gmail.com', timeout=5)
|
||||
|
|
||||
|
||||
S113.py:10:35: S113 Probable use of requests call with timeout set to `None`
|
||||
|
|
||||
8 | requests.post('https://gmail.com', timeout=5)
|
||||
9 | requests.put('https://gmail.com')
|
||||
10 | requests.put('https://gmail.com', timeout=None)
|
||||
| ^^^^^^^^^^^^ S113
|
||||
11 | requests.put('https://gmail.com', timeout=5)
|
||||
12 | requests.delete('https://gmail.com')
|
||||
|
|
||||
|
||||
S113.py:12:1: S113 Probable use of requests call without timeout
|
||||
|
|
||||
10 | requests.put('https://gmail.com', timeout=None)
|
||||
11 | requests.put('https://gmail.com', timeout=5)
|
||||
12 | requests.delete('https://gmail.com')
|
||||
| ^^^^^^^^^^^^^^^ S113
|
||||
13 | requests.delete('https://gmail.com', timeout=None)
|
||||
14 | requests.delete('https://gmail.com', timeout=5)
|
||||
|
|
||||
|
||||
S113.py:13:38: S113 Probable use of requests call with timeout set to `None`
|
||||
|
|
||||
11 | requests.put('https://gmail.com', timeout=5)
|
||||
12 | requests.delete('https://gmail.com')
|
||||
13 | requests.delete('https://gmail.com', timeout=None)
|
||||
| ^^^^^^^^^^^^ S113
|
||||
14 | requests.delete('https://gmail.com', timeout=5)
|
||||
15 | requests.patch('https://gmail.com')
|
||||
|
|
||||
|
||||
S113.py:15:1: S113 Probable use of requests call without timeout
|
||||
|
|
||||
13 | requests.delete('https://gmail.com', timeout=None)
|
||||
14 | requests.delete('https://gmail.com', timeout=5)
|
||||
15 | requests.patch('https://gmail.com')
|
||||
| ^^^^^^^^^^^^^^ S113
|
||||
16 | requests.patch('https://gmail.com', timeout=None)
|
||||
17 | requests.patch('https://gmail.com', timeout=5)
|
||||
|
|
||||
|
||||
S113.py:16:37: S113 Probable use of requests call with timeout set to `None`
|
||||
|
|
||||
14 | requests.delete('https://gmail.com', timeout=5)
|
||||
15 | requests.patch('https://gmail.com')
|
||||
16 | requests.patch('https://gmail.com', timeout=None)
|
||||
| ^^^^^^^^^^^^ S113
|
||||
17 | requests.patch('https://gmail.com', timeout=5)
|
||||
18 | requests.options('https://gmail.com')
|
||||
|
|
||||
|
||||
S113.py:18:1: S113 Probable use of requests call without timeout
|
||||
|
|
||||
16 | requests.patch('https://gmail.com', timeout=None)
|
||||
17 | requests.patch('https://gmail.com', timeout=5)
|
||||
18 | requests.options('https://gmail.com')
|
||||
| ^^^^^^^^^^^^^^^^ S113
|
||||
19 | requests.options('https://gmail.com', timeout=None)
|
||||
20 | requests.options('https://gmail.com', timeout=5)
|
||||
|
|
||||
|
||||
S113.py:19:39: S113 Probable use of requests call with timeout set to `None`
|
||||
|
|
||||
17 | requests.patch('https://gmail.com', timeout=5)
|
||||
18 | requests.options('https://gmail.com')
|
||||
19 | requests.options('https://gmail.com', timeout=None)
|
||||
| ^^^^^^^^^^^^ S113
|
||||
20 | requests.options('https://gmail.com', timeout=5)
|
||||
21 | requests.head('https://gmail.com')
|
||||
|
|
||||
|
||||
S113.py:21:1: S113 Probable use of requests call without timeout
|
||||
|
|
||||
19 | requests.options('https://gmail.com', timeout=None)
|
||||
20 | requests.options('https://gmail.com', timeout=5)
|
||||
21 | requests.head('https://gmail.com')
|
||||
| ^^^^^^^^^^^^^ S113
|
||||
22 | requests.head('https://gmail.com', timeout=None)
|
||||
23 | requests.head('https://gmail.com', timeout=5)
|
||||
|
|
||||
|
||||
S113.py:22:36: S113 Probable use of requests call with timeout set to `None`
|
||||
|
|
||||
20 | requests.options('https://gmail.com', timeout=5)
|
||||
21 | requests.head('https://gmail.com')
|
||||
22 | requests.head('https://gmail.com', timeout=None)
|
||||
| ^^^^^^^^^^^^ S113
|
||||
23 | requests.head('https://gmail.com', timeout=5)
|
||||
|
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S301.py:3:1: S301 `pickle` and modules that wrap it can be unsafe when used to deserialize untrusted data, possible security issue
|
||||
|
|
||||
1 | import pickle
|
||||
2 |
|
||||
3 | pickle.loads()
|
||||
| ^^^^^^^^^^^^^^ S301
|
||||
|
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S307.py:3:7: S307 Use of possibly insecure function; consider using `ast.literal_eval`
|
||||
|
|
||||
1 | import os
|
||||
2 |
|
||||
3 | print(eval("1+1")) # S307
|
||||
| ^^^^^^^^^^^ S307
|
||||
4 | print(eval("os.getcwd()")) # S307
|
||||
|
|
||||
|
||||
S307.py:4:7: S307 Use of possibly insecure function; consider using `ast.literal_eval`
|
||||
|
|
||||
3 | print(eval("1+1")) # S307
|
||||
4 | print(eval("os.getcwd()")) # S307
|
||||
| ^^^^^^^^^^^^^^^^^^^ S307
|
||||
|
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S312.py:3:1: S312 Telnet-related functions are being called. Telnet is considered insecure. Use SSH or some other encrypted protocol.
|
||||
|
|
||||
1 | from telnetlib import Telnet
|
||||
2 |
|
||||
3 | Telnet("localhost", 23)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ S312
|
||||
|
|
||||
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S324.py:7:13: S324 Probable use of insecure hash functions in `hashlib`: `md5`
|
||||
|
|
||||
5 | # Invalid
|
||||
6 |
|
||||
7 | hashlib.new('md5')
|
||||
| ^^^^^ S324
|
||||
8 |
|
||||
9 | hashlib.new('md4', b'test')
|
||||
|
|
||||
|
||||
S324.py:9:13: S324 Probable use of insecure hash functions in `hashlib`: `md4`
|
||||
|
|
||||
7 | hashlib.new('md5')
|
||||
8 |
|
||||
9 | hashlib.new('md4', b'test')
|
||||
| ^^^^^ S324
|
||||
10 |
|
||||
11 | hashlib.new(name='md5', data=b'test')
|
||||
|
|
||||
|
||||
S324.py:11:18: S324 Probable use of insecure hash functions in `hashlib`: `md5`
|
||||
|
|
||||
9 | hashlib.new('md4', b'test')
|
||||
10 |
|
||||
11 | hashlib.new(name='md5', data=b'test')
|
||||
| ^^^^^ S324
|
||||
12 |
|
||||
13 | hashlib.new('MD4', data=b'test')
|
||||
|
|
||||
|
||||
S324.py:13:13: S324 Probable use of insecure hash functions in `hashlib`: `MD4`
|
||||
|
|
||||
11 | hashlib.new(name='md5', data=b'test')
|
||||
12 |
|
||||
13 | hashlib.new('MD4', data=b'test')
|
||||
| ^^^^^ S324
|
||||
14 |
|
||||
15 | hashlib.new('sha1')
|
||||
|
|
||||
|
||||
S324.py:15:13: S324 Probable use of insecure hash functions in `hashlib`: `sha1`
|
||||
|
|
||||
13 | hashlib.new('MD4', data=b'test')
|
||||
14 |
|
||||
15 | hashlib.new('sha1')
|
||||
| ^^^^^^ S324
|
||||
16 |
|
||||
17 | hashlib.new('sha1', data=b'test')
|
||||
|
|
||||
|
||||
S324.py:17:13: S324 Probable use of insecure hash functions in `hashlib`: `sha1`
|
||||
|
|
||||
15 | hashlib.new('sha1')
|
||||
16 |
|
||||
17 | hashlib.new('sha1', data=b'test')
|
||||
| ^^^^^^ S324
|
||||
18 |
|
||||
19 | hashlib.new('sha', data=b'test')
|
||||
|
|
||||
|
||||
S324.py:19:13: S324 Probable use of insecure hash functions in `hashlib`: `sha`
|
||||
|
|
||||
17 | hashlib.new('sha1', data=b'test')
|
||||
18 |
|
||||
19 | hashlib.new('sha', data=b'test')
|
||||
| ^^^^^ S324
|
||||
20 |
|
||||
21 | hashlib.new(name='SHA', data=b'test')
|
||||
|
|
||||
|
||||
S324.py:21:18: S324 Probable use of insecure hash functions in `hashlib`: `SHA`
|
||||
|
|
||||
19 | hashlib.new('sha', data=b'test')
|
||||
20 |
|
||||
21 | hashlib.new(name='SHA', data=b'test')
|
||||
| ^^^^^ S324
|
||||
22 |
|
||||
23 | hashlib.sha(data=b'test')
|
||||
|
|
||||
|
||||
S324.py:23:1: S324 Probable use of insecure hash functions in `hashlib`: `sha`
|
||||
|
|
||||
21 | hashlib.new(name='SHA', data=b'test')
|
||||
22 |
|
||||
23 | hashlib.sha(data=b'test')
|
||||
| ^^^^^^^^^^^ S324
|
||||
24 |
|
||||
25 | hashlib.md5()
|
||||
|
|
||||
|
||||
S324.py:25:1: S324 Probable use of insecure hash functions in `hashlib`: `md5`
|
||||
|
|
||||
23 | hashlib.sha(data=b'test')
|
||||
24 |
|
||||
25 | hashlib.md5()
|
||||
| ^^^^^^^^^^^ S324
|
||||
26 |
|
||||
27 | hashlib_new('sha1')
|
||||
|
|
||||
|
||||
S324.py:27:13: S324 Probable use of insecure hash functions in `hashlib`: `sha1`
|
||||
|
|
||||
25 | hashlib.md5()
|
||||
26 |
|
||||
27 | hashlib_new('sha1')
|
||||
| ^^^^^^ S324
|
||||
28 |
|
||||
29 | hashlib_sha1('sha1')
|
||||
|
|
||||
|
||||
S324.py:29:1: S324 Probable use of insecure hash functions in `hashlib`: `sha1`
|
||||
|
|
||||
27 | hashlib_new('sha1')
|
||||
28 |
|
||||
29 | hashlib_sha1('sha1')
|
||||
| ^^^^^^^^^^^^ S324
|
||||
30 |
|
||||
31 | # usedforsecurity arg only available in Python 3.9+
|
||||
|
|
||||
|
||||
S324.py:32:13: S324 Probable use of insecure hash functions in `hashlib`: `sha1`
|
||||
|
|
||||
31 | # usedforsecurity arg only available in Python 3.9+
|
||||
32 | hashlib.new('sha1', usedforsecurity=True)
|
||||
| ^^^^^^ S324
|
||||
33 |
|
||||
34 | # Valid
|
||||
|
|
||||
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S501.py:5:47: S501 Probable use of `requests` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
4 | requests.get('https://gmail.com', timeout=30, verify=True)
|
||||
5 | requests.get('https://gmail.com', timeout=30, verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
6 | requests.post('https://gmail.com', timeout=30, verify=True)
|
||||
7 | requests.post('https://gmail.com', timeout=30, verify=False)
|
||||
|
|
||||
|
||||
S501.py:7:48: S501 Probable use of `requests` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
5 | requests.get('https://gmail.com', timeout=30, verify=False)
|
||||
6 | requests.post('https://gmail.com', timeout=30, verify=True)
|
||||
7 | requests.post('https://gmail.com', timeout=30, verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
8 | requests.put('https://gmail.com', timeout=30, verify=True)
|
||||
9 | requests.put('https://gmail.com', timeout=30, verify=False)
|
||||
|
|
||||
|
||||
S501.py:9:47: S501 Probable use of `requests` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
7 | requests.post('https://gmail.com', timeout=30, verify=False)
|
||||
8 | requests.put('https://gmail.com', timeout=30, verify=True)
|
||||
9 | requests.put('https://gmail.com', timeout=30, verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
10 | requests.delete('https://gmail.com', timeout=30, verify=True)
|
||||
11 | requests.delete('https://gmail.com', timeout=30, verify=False)
|
||||
|
|
||||
|
||||
S501.py:11:50: S501 Probable use of `requests` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
9 | requests.put('https://gmail.com', timeout=30, verify=False)
|
||||
10 | requests.delete('https://gmail.com', timeout=30, verify=True)
|
||||
11 | requests.delete('https://gmail.com', timeout=30, verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
12 | requests.patch('https://gmail.com', timeout=30, verify=True)
|
||||
13 | requests.patch('https://gmail.com', timeout=30, verify=False)
|
||||
|
|
||||
|
||||
S501.py:13:49: S501 Probable use of `requests` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
11 | requests.delete('https://gmail.com', timeout=30, verify=False)
|
||||
12 | requests.patch('https://gmail.com', timeout=30, verify=True)
|
||||
13 | requests.patch('https://gmail.com', timeout=30, verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
14 | requests.options('https://gmail.com', timeout=30, verify=True)
|
||||
15 | requests.options('https://gmail.com', timeout=30, verify=False)
|
||||
|
|
||||
|
||||
S501.py:15:51: S501 Probable use of `requests` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
13 | requests.patch('https://gmail.com', timeout=30, verify=False)
|
||||
14 | requests.options('https://gmail.com', timeout=30, verify=True)
|
||||
15 | requests.options('https://gmail.com', timeout=30, verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
16 | requests.head('https://gmail.com', timeout=30, verify=True)
|
||||
17 | requests.head('https://gmail.com', timeout=30, verify=False)
|
||||
|
|
||||
|
||||
S501.py:17:48: S501 Probable use of `requests` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
15 | requests.options('https://gmail.com', timeout=30, verify=False)
|
||||
16 | requests.head('https://gmail.com', timeout=30, verify=True)
|
||||
17 | requests.head('https://gmail.com', timeout=30, verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
18 |
|
||||
19 | httpx.request('GET', 'https://gmail.com', verify=True)
|
||||
|
|
||||
|
||||
S501.py:20:43: S501 Probable use of `httpx` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
19 | httpx.request('GET', 'https://gmail.com', verify=True)
|
||||
20 | httpx.request('GET', 'https://gmail.com', verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
21 | httpx.get('https://gmail.com', verify=True)
|
||||
22 | httpx.get('https://gmail.com', verify=False)
|
||||
|
|
||||
|
||||
S501.py:22:32: S501 Probable use of `httpx` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
20 | httpx.request('GET', 'https://gmail.com', verify=False)
|
||||
21 | httpx.get('https://gmail.com', verify=True)
|
||||
22 | httpx.get('https://gmail.com', verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
23 | httpx.options('https://gmail.com', verify=True)
|
||||
24 | httpx.options('https://gmail.com', verify=False)
|
||||
|
|
||||
|
||||
S501.py:24:36: S501 Probable use of `httpx` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
22 | httpx.get('https://gmail.com', verify=False)
|
||||
23 | httpx.options('https://gmail.com', verify=True)
|
||||
24 | httpx.options('https://gmail.com', verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
25 | httpx.head('https://gmail.com', verify=True)
|
||||
26 | httpx.head('https://gmail.com', verify=False)
|
||||
|
|
||||
|
||||
S501.py:26:33: S501 Probable use of `httpx` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
24 | httpx.options('https://gmail.com', verify=False)
|
||||
25 | httpx.head('https://gmail.com', verify=True)
|
||||
26 | httpx.head('https://gmail.com', verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
27 | httpx.post('https://gmail.com', verify=True)
|
||||
28 | httpx.post('https://gmail.com', verify=False)
|
||||
|
|
||||
|
||||
S501.py:28:33: S501 Probable use of `httpx` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
26 | httpx.head('https://gmail.com', verify=False)
|
||||
27 | httpx.post('https://gmail.com', verify=True)
|
||||
28 | httpx.post('https://gmail.com', verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
29 | httpx.put('https://gmail.com', verify=True)
|
||||
30 | httpx.put('https://gmail.com', verify=False)
|
||||
|
|
||||
|
||||
S501.py:30:32: S501 Probable use of `httpx` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
28 | httpx.post('https://gmail.com', verify=False)
|
||||
29 | httpx.put('https://gmail.com', verify=True)
|
||||
30 | httpx.put('https://gmail.com', verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
31 | httpx.patch('https://gmail.com', verify=True)
|
||||
32 | httpx.patch('https://gmail.com', verify=False)
|
||||
|
|
||||
|
||||
S501.py:32:34: S501 Probable use of `httpx` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
30 | httpx.put('https://gmail.com', verify=False)
|
||||
31 | httpx.patch('https://gmail.com', verify=True)
|
||||
32 | httpx.patch('https://gmail.com', verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
33 | httpx.delete('https://gmail.com', verify=True)
|
||||
34 | httpx.delete('https://gmail.com', verify=False)
|
||||
|
|
||||
|
||||
S501.py:34:35: S501 Probable use of `httpx` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
32 | httpx.patch('https://gmail.com', verify=False)
|
||||
33 | httpx.delete('https://gmail.com', verify=True)
|
||||
34 | httpx.delete('https://gmail.com', verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
35 | httpx.stream('https://gmail.com', verify=True)
|
||||
36 | httpx.stream('https://gmail.com', verify=False)
|
||||
|
|
||||
|
||||
S501.py:36:35: S501 Probable use of `httpx` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
34 | httpx.delete('https://gmail.com', verify=False)
|
||||
35 | httpx.stream('https://gmail.com', verify=True)
|
||||
36 | httpx.stream('https://gmail.com', verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
37 | httpx.Client()
|
||||
38 | httpx.Client(verify=False)
|
||||
|
|
||||
|
||||
S501.py:38:14: S501 Probable use of `httpx` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
36 | httpx.stream('https://gmail.com', verify=False)
|
||||
37 | httpx.Client()
|
||||
38 | httpx.Client(verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
39 | httpx.AsyncClient()
|
||||
40 | httpx.AsyncClient(verify=False)
|
||||
|
|
||||
|
||||
S501.py:40:19: S501 Probable use of `httpx` call with `verify=False` disabling SSL certificate checks
|
||||
|
|
||||
38 | httpx.Client(verify=False)
|
||||
39 | httpx.AsyncClient()
|
||||
40 | httpx.AsyncClient(verify=False)
|
||||
| ^^^^^^^^^^^^ S501
|
||||
|
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S506.py:10:9: S506 Probable use of unsafe `yaml.load`. Allows instantiation of arbitrary objects. Consider `yaml.safe_load`.
|
||||
|
|
||||
8 | def test_yaml_load():
|
||||
9 | ystr = yaml.dump({"a": 1, "b": 2, "c": 3})
|
||||
10 | y = yaml.load(ystr)
|
||||
| ^^^^^^^^^ S506
|
||||
11 | yaml.dump(y)
|
||||
12 | try:
|
||||
|
|
||||
|
||||
S506.py:24:24: S506 Probable use of unsafe loader `Loader` with `yaml.load`. Allows instantiation of arbitrary objects. Consider `yaml.safe_load`.
|
||||
|
|
||||
24 | yaml.load("{}", Loader=yaml.Loader)
|
||||
| ^^^^^^^^^^^ S506
|
||||
25 |
|
||||
26 | # no issue should be found
|
||||
|
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S508.py:3:25: S508 The use of SNMPv1 and SNMPv2 is insecure. Use SNMPv3 if able.
|
||||
|
|
||||
1 | from pysnmp.hlapi import CommunityData
|
||||
2 |
|
||||
3 | CommunityData("public", mpModel=0) # S508
|
||||
| ^^^^^^^^^ S508
|
||||
4 | CommunityData("public", mpModel=1) # S508
|
||||
|
|
||||
|
||||
S508.py:4:25: S508 The use of SNMPv1 and SNMPv2 is insecure. Use SNMPv3 if able.
|
||||
|
|
||||
3 | CommunityData("public", mpModel=0) # S508
|
||||
4 | CommunityData("public", mpModel=1) # S508
|
||||
| ^^^^^^^^^ S508
|
||||
5 |
|
||||
6 | CommunityData("public", mpModel=2) # OK
|
||||
|
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S509.py:4:12: S509 You should not use SNMPv3 without encryption. `noAuthNoPriv` & `authNoPriv` is insecure.
|
||||
|
|
||||
4 | insecure = UsmUserData("securityName") # S509
|
||||
| ^^^^^^^^^^^ S509
|
||||
5 | auth_no_priv = UsmUserData("securityName", "authName") # S509
|
||||
|
|
||||
|
||||
S509.py:5:16: S509 You should not use SNMPv3 without encryption. `noAuthNoPriv` & `authNoPriv` is insecure.
|
||||
|
|
||||
4 | insecure = UsmUserData("securityName") # S509
|
||||
5 | auth_no_priv = UsmUserData("securityName", "authName") # S509
|
||||
| ^^^^^^^^^^^ S509
|
||||
6 |
|
||||
7 | less_insecure = UsmUserData("securityName", "authName", "privName") # OK
|
||||
|
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S601.py:3:1: S601 Possible shell injection via Paramiko call; check inputs are properly sanitized
|
||||
|
|
||||
1 | import paramiko
|
||||
2 |
|
||||
3 | paramiko.exec_command('something; really; unsafe')
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ S601
|
||||
|
|
||||
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S602.py:4:15: S602 `subprocess` call with `shell=True` seems safe, but may be changed in the future; consider rewriting without `shell`
|
||||
|
|
||||
3 | # Check different Popen wrappers are checked.
|
||||
4 | Popen("true", shell=True)
|
||||
| ^^^^^^^^^^ S602
|
||||
5 | call("true", shell=True)
|
||||
6 | check_call("true", shell=True)
|
||||
|
|
||||
|
||||
S602.py:5:14: S602 `subprocess` call with `shell=True` seems safe, but may be changed in the future; consider rewriting without `shell`
|
||||
|
|
||||
3 | # Check different Popen wrappers are checked.
|
||||
4 | Popen("true", shell=True)
|
||||
5 | call("true", shell=True)
|
||||
| ^^^^^^^^^^ S602
|
||||
6 | check_call("true", shell=True)
|
||||
7 | check_output("true", shell=True)
|
||||
|
|
||||
|
||||
S602.py:6:20: S602 `subprocess` call with `shell=True` seems safe, but may be changed in the future; consider rewriting without `shell`
|
||||
|
|
||||
4 | Popen("true", shell=True)
|
||||
5 | call("true", shell=True)
|
||||
6 | check_call("true", shell=True)
|
||||
| ^^^^^^^^^^ S602
|
||||
7 | check_output("true", shell=True)
|
||||
8 | run("true", shell=True)
|
||||
|
|
||||
|
||||
S602.py:7:22: S602 `subprocess` call with `shell=True` seems safe, but may be changed in the future; consider rewriting without `shell`
|
||||
|
|
||||
5 | call("true", shell=True)
|
||||
6 | check_call("true", shell=True)
|
||||
7 | check_output("true", shell=True)
|
||||
| ^^^^^^^^^^ S602
|
||||
8 | run("true", shell=True)
|
||||
|
|
||||
|
||||
S602.py:8:13: S602 `subprocess` call with `shell=True` seems safe, but may be changed in the future; consider rewriting without `shell`
|
||||
|
|
||||
6 | check_call("true", shell=True)
|
||||
7 | check_output("true", shell=True)
|
||||
8 | run("true", shell=True)
|
||||
| ^^^^^^^^^^ S602
|
||||
9 |
|
||||
10 | # Check values that truthy values are treated as true.
|
||||
|
|
||||
|
||||
S602.py:11:15: S602 `subprocess` call with `shell=True` seems safe, but may be changed in the future; consider rewriting without `shell`
|
||||
|
|
||||
10 | # Check values that truthy values are treated as true.
|
||||
11 | Popen("true", shell=1)
|
||||
| ^^^^^^^ S602
|
||||
12 | Popen("true", shell=[1])
|
||||
13 | Popen("true", shell={1: 1})
|
||||
|
|
||||
|
||||
S602.py:12:15: S602 `subprocess` call with `shell=True` seems safe, but may be changed in the future; consider rewriting without `shell`
|
||||
|
|
||||
10 | # Check values that truthy values are treated as true.
|
||||
11 | Popen("true", shell=1)
|
||||
12 | Popen("true", shell=[1])
|
||||
| ^^^^^^^^^ S602
|
||||
13 | Popen("true", shell={1: 1})
|
||||
14 | Popen("true", shell=(1,))
|
||||
|
|
||||
|
||||
S602.py:13:15: S602 `subprocess` call with `shell=True` seems safe, but may be changed in the future; consider rewriting without `shell`
|
||||
|
|
||||
11 | Popen("true", shell=1)
|
||||
12 | Popen("true", shell=[1])
|
||||
13 | Popen("true", shell={1: 1})
|
||||
| ^^^^^^^^^^^^ S602
|
||||
14 | Popen("true", shell=(1,))
|
||||
|
|
||||
|
||||
S602.py:14:15: S602 `subprocess` call with `shell=True` seems safe, but may be changed in the future; consider rewriting without `shell`
|
||||
|
|
||||
12 | Popen("true", shell=[1])
|
||||
13 | Popen("true", shell={1: 1})
|
||||
14 | Popen("true", shell=(1,))
|
||||
| ^^^^^^^^^^ S602
|
||||
15 |
|
||||
16 | # Check command argument looks unsafe.
|
||||
|
|
||||
|
||||
S602.py:18:19: S602 `subprocess` call with `shell=True` identified, security issue
|
||||
|
|
||||
16 | # Check command argument looks unsafe.
|
||||
17 | var_string = "true"
|
||||
18 | Popen(var_string, shell=True)
|
||||
| ^^^^^^^^^^ S602
|
||||
19 | Popen([var_string], shell=True)
|
||||
20 | Popen([var_string, ""], shell=True)
|
||||
|
|
||||
|
||||
S602.py:19:21: S602 `subprocess` call with `shell=True` identified, security issue
|
||||
|
|
||||
17 | var_string = "true"
|
||||
18 | Popen(var_string, shell=True)
|
||||
19 | Popen([var_string], shell=True)
|
||||
| ^^^^^^^^^^ S602
|
||||
20 | Popen([var_string, ""], shell=True)
|
||||
|
|
||||
|
||||
S602.py:20:25: S602 `subprocess` call with `shell=True` identified, security issue
|
||||
|
|
||||
18 | Popen(var_string, shell=True)
|
||||
19 | Popen([var_string], shell=True)
|
||||
20 | Popen([var_string, ""], shell=True)
|
||||
| ^^^^^^^^^^ S602
|
||||
|
|
||||
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S603.py:4:15: S603 `subprocess` call: check for execution of untrusted input
|
||||
|
|
||||
3 | # Different Popen wrappers are checked.
|
||||
4 | Popen("true", shell=False)
|
||||
| ^^^^^^^^^^^ S603
|
||||
5 | call("true", shell=False)
|
||||
6 | check_call("true", shell=False)
|
||||
|
|
||||
|
||||
S603.py:5:14: S603 `subprocess` call: check for execution of untrusted input
|
||||
|
|
||||
3 | # Different Popen wrappers are checked.
|
||||
4 | Popen("true", shell=False)
|
||||
5 | call("true", shell=False)
|
||||
| ^^^^^^^^^^^ S603
|
||||
6 | check_call("true", shell=False)
|
||||
7 | check_output("true", shell=False)
|
||||
|
|
||||
|
||||
S603.py:6:20: S603 `subprocess` call: check for execution of untrusted input
|
||||
|
|
||||
4 | Popen("true", shell=False)
|
||||
5 | call("true", shell=False)
|
||||
6 | check_call("true", shell=False)
|
||||
| ^^^^^^^^^^^ S603
|
||||
7 | check_output("true", shell=False)
|
||||
8 | run("true", shell=False)
|
||||
|
|
||||
|
||||
S603.py:7:22: S603 `subprocess` call: check for execution of untrusted input
|
||||
|
|
||||
5 | call("true", shell=False)
|
||||
6 | check_call("true", shell=False)
|
||||
7 | check_output("true", shell=False)
|
||||
| ^^^^^^^^^^^ S603
|
||||
8 | run("true", shell=False)
|
||||
|
|
||||
|
||||
S603.py:8:13: S603 `subprocess` call: check for execution of untrusted input
|
||||
|
|
||||
6 | check_call("true", shell=False)
|
||||
7 | check_output("true", shell=False)
|
||||
8 | run("true", shell=False)
|
||||
| ^^^^^^^^^^^ S603
|
||||
9 |
|
||||
10 | # Values that falsey values are treated as false.
|
||||
|
|
||||
|
||||
S603.py:11:15: S603 `subprocess` call: check for execution of untrusted input
|
||||
|
|
||||
10 | # Values that falsey values are treated as false.
|
||||
11 | Popen("true", shell=0)
|
||||
| ^^^^^^^ S603
|
||||
12 | Popen("true", shell=[])
|
||||
13 | Popen("true", shell={})
|
||||
|
|
||||
|
||||
S603.py:12:15: S603 `subprocess` call: check for execution of untrusted input
|
||||
|
|
||||
10 | # Values that falsey values are treated as false.
|
||||
11 | Popen("true", shell=0)
|
||||
12 | Popen("true", shell=[])
|
||||
| ^^^^^^^^ S603
|
||||
13 | Popen("true", shell={})
|
||||
14 | Popen("true", shell=None)
|
||||
|
|
||||
|
||||
S603.py:13:15: S603 `subprocess` call: check for execution of untrusted input
|
||||
|
|
||||
11 | Popen("true", shell=0)
|
||||
12 | Popen("true", shell=[])
|
||||
13 | Popen("true", shell={})
|
||||
| ^^^^^^^^ S603
|
||||
14 | Popen("true", shell=None)
|
||||
|
|
||||
|
||||
S603.py:14:15: S603 `subprocess` call: check for execution of untrusted input
|
||||
|
|
||||
12 | Popen("true", shell=[])
|
||||
13 | Popen("true", shell={})
|
||||
14 | Popen("true", shell=None)
|
||||
| ^^^^^^^^^^ S603
|
||||
15 |
|
||||
16 | # Unknown values are treated as falsey.
|
||||
|
|
||||
|
||||
S603.py:17:15: S603 `subprocess` call: check for execution of untrusted input
|
||||
|
|
||||
16 | # Unknown values are treated as falsey.
|
||||
17 | Popen("true", shell=True if True else False)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S603
|
||||
18 |
|
||||
19 | # No value is also caught.
|
||||
|
|
||||
|
||||
S603.py:20:7: S603 `subprocess` call: check for execution of untrusted input
|
||||
|
|
||||
19 | # No value is also caught.
|
||||
20 | Popen("true")
|
||||
| ^^^^^^ S603
|
||||
|
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S604.py:5:5: S604 Function call with `shell=True` parameter identified, security issue
|
||||
|
|
||||
5 | foo(shell=True)
|
||||
| ^^^^^^^^^^ S604
|
||||
|
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user