Compare commits
9 Commits
simplify-S
...
v0.1.13
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d16c4a2d25 | ||
|
|
1602df1643 | ||
|
|
395cdf04e5 | ||
|
|
3daf6e1b6d | ||
|
|
a31a314b2b | ||
|
|
f9dd7bb190 | ||
|
|
350dcb807a | ||
|
|
55f8f3b2cc | ||
|
|
eb4ed2471b |
61
CHANGELOG.md
61
CHANGELOG.md
@@ -1,5 +1,66 @@
|
||||
# Changelog
|
||||
|
||||
## 0.1.13
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Include base pyproject when initializing cache settings ([#9480](https://github.com/astral-sh/ruff/pull/9480))
|
||||
- \[`flake8-simplify`\] Account for possibly-empty f-string values in truthiness logic ([#9484](https://github.com/astral-sh/ruff/pull/9484))
|
||||
- \[`pylint`\] Add the missing period in `unnecessary-dunder-call` ([#9485](https://github.com/astral-sh/ruff/pull/9485))
|
||||
- \[`pylint`\] Fix `__aenter__` message in `unnecessary-dunder-call` ([#9492](https://github.com/astral-sh/ruff/pull/9492))
|
||||
|
||||
## 0.1.12
|
||||
|
||||
### Preview features
|
||||
|
||||
- Formatter: Hug multiline-strings in preview style ([#9243](https://github.com/astral-sh/ruff/pull/9243))
|
||||
- \[`flake8-bandit`\] Add `ssl-with-no-version` (`S504`) ([#9384](https://github.com/astral-sh/ruff/pull/9384))
|
||||
- \[`flake8-bandit`\] Implement `ssl-insecure-version` (`S502`) ([#9390](https://github.com/astral-sh/ruff/pull/9390))
|
||||
- \[`flake8-bandit`\] Implement `ssl-with-bad-defaults` (`S503`) ([#9391](https://github.com/astral-sh/ruff/pull/9391))
|
||||
- \[`flake8-bandit`\] Implement suspicious import rules (`S4XX`) ([#8831](https://github.com/astral-sh/ruff/pull/8831))
|
||||
- \[`flake8-simplify`\] Implement `zip-dict-keys-and-values` (`SIM911`) ([#9460](https://github.com/astral-sh/ruff/pull/9460))
|
||||
- \[`pyflakes`\] Add a fix for `redefined-while-unused` (`F811`) ([#9419](https://github.com/astral-sh/ruff/pull/9419))
|
||||
- \[`pylint`\] Implement `unnecessary-dunder-call` (`C2801`) ([#9166](https://github.com/astral-sh/ruff/pull/9166))
|
||||
- \[`ruff`\] Add `parenthesize-chained-operators` (`RUF021`) to enforce parentheses in `a or b and c` ([#9440](https://github.com/astral-sh/ruff/pull/9440))
|
||||
|
||||
### Rule changes
|
||||
|
||||
- \[`flake8-boolean-trap`\] Allow Boolean positional arguments in setters ([#9429](https://github.com/astral-sh/ruff/pull/9429))
|
||||
- \[`flake8-builtins`\] Restrict `builtin-attribute-shadowing` (`A003`) to actual shadowed references ([#9462](https://github.com/astral-sh/ruff/pull/9462))
|
||||
- \[`flake8-pyi`\] Add fix for `generator-return-from-iter-method` (`PYI058`) ([#9355](https://github.com/astral-sh/ruff/pull/9355))
|
||||
- \[`pyflakes`\] Don't flag `redefined-while-unused` (`F811`) in `if` branches ([#9418](https://github.com/astral-sh/ruff/pull/9418))
|
||||
- \[`pyupgrade`\] Add some additional Python 3.12 typing members to `deprecated-import` ([#9445](https://github.com/astral-sh/ruff/pull/9445))
|
||||
- \[`ruff`\] Add fix for `parenthesize-chained-operators` (`RUF021`) ([#9449](https://github.com/astral-sh/ruff/pull/9449))
|
||||
- \[`ruff`\] Include subscripts and attributes in static key rule (`RUF011`) ([#9416](https://github.com/astral-sh/ruff/pull/9416))
|
||||
- \[`ruff`\] Support variable keys in static dictionary key rule (`RUF011`) ([#9411](https://github.com/astral-sh/ruff/pull/9411))
|
||||
|
||||
### Formatter
|
||||
|
||||
- Generate deterministic IDs when formatting notebooks ([#9359](https://github.com/astral-sh/ruff/pull/9359))
|
||||
- Allow `# fmt: skip` with interspersed same-line comments ([#9395](https://github.com/astral-sh/ruff/pull/9395))
|
||||
- Parenthesize breaking named expressions in match guards ([#9396](https://github.com/astral-sh/ruff/pull/9396))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Add cell indexes to all diagnostics ([#9387](https://github.com/astral-sh/ruff/pull/9387))
|
||||
- Avoid infinite loop in constant vs. `None` comparisons ([#9376](https://github.com/astral-sh/ruff/pull/9376))
|
||||
- Handle raises with implicit alternate branches ([#9377](https://github.com/astral-sh/ruff/pull/9377))
|
||||
- Ignore trailing quotes for unclosed l-brace errors ([#9388](https://github.com/astral-sh/ruff/pull/9388))
|
||||
- Respect multi-segment submodule imports when resolving qualified names ([#9382](https://github.com/astral-sh/ruff/pull/9382))
|
||||
- Use `DisplayParseError` for stdin parser errors ([#9409](https://github.com/astral-sh/ruff/pull/9409))
|
||||
- Use `comment_ranges` for isort directive extraction ([#9414](https://github.com/astral-sh/ruff/pull/9414))
|
||||
- Use transformed source code for diagnostic locations ([#9408](https://github.com/astral-sh/ruff/pull/9408))
|
||||
- \[`flake8-pyi`\] Exclude `warnings.deprecated` and `typing_extensions.deprecated` arguments ([#9423](https://github.com/astral-sh/ruff/pull/9423))
|
||||
- \[`flake8-pyi`\] Fix false negative for `unused-private-protocol` (`PYI046`) with unused generic protocols ([#9405](https://github.com/astral-sh/ruff/pull/9405))
|
||||
- \[`pydocstyle`\] Disambiguate argument descriptors from section headers ([#9427](https://github.com/astral-sh/ruff/pull/9427))
|
||||
- \[`pylint`\] Homogenize `PLR0914` message to match other `PLR09XX` rules ([#9399](https://github.com/astral-sh/ruff/pull/9399))
|
||||
- \[`ruff`\] Allow `Hashable = None` in type annotations (`RUF013`) ([#9442](https://github.com/astral-sh/ruff/pull/9442))
|
||||
|
||||
### Documentation
|
||||
|
||||
- Fix admonition hyperlink colouring ([#9385](https://github.com/astral-sh/ruff/pull/9385))
|
||||
- Add missing preview link ([#9386](https://github.com/astral-sh/ruff/pull/9386))
|
||||
|
||||
## 0.1.11
|
||||
|
||||
### Preview features
|
||||
|
||||
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -2038,7 +2038,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_cli"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argfile",
|
||||
@@ -2165,7 +2165,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_linter"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"annotate-snippets 0.9.2",
|
||||
@@ -2417,7 +2417,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_shrinking"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
|
||||
@@ -150,7 +150,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com/) hook via [`ruff
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.1.11
|
||||
rev: v0.1.13
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_cli"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
publish = false
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_linter"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
publish = false
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
@@ -85,8 +85,6 @@ tempfile = { workspace = true }
|
||||
[features]
|
||||
default = []
|
||||
schemars = ["dep:schemars"]
|
||||
# Enables the UnreachableCode rule
|
||||
unreachable-code = []
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -160,3 +160,10 @@ def secondToTime(s0: int) -> (int, int, int) or str:
|
||||
|
||||
def secondToTime(s0: int) -> ((int, int, int) or str):
|
||||
m, s = divmod(s0, 60)
|
||||
|
||||
|
||||
# Regression test for: https://github.com/astral-sh/ruff/issues/9479
|
||||
print(f"{a}{b}" or "bar")
|
||||
print(f"{a}{''}" or "bar")
|
||||
print(f"{''}{''}" or "bar")
|
||||
print(f"{1}{''}" or "bar")
|
||||
|
||||
@@ -147,3 +147,9 @@ if (a and [] and False and []) == (a and []): # SIM223
|
||||
|
||||
if f(a and [] and False and []): # SIM223
|
||||
pass
|
||||
|
||||
# Regression test for: https://github.com/astral-sh/ruff/issues/9479
|
||||
print(f"{a}{b}" and "bar")
|
||||
print(f"{a}{''}" and "bar")
|
||||
print(f"{''}{''}" and "bar")
|
||||
print(f"{1}{''}" and "bar")
|
||||
|
||||
23
crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM911.py
vendored
Normal file
23
crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM911.py
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
def foo(d: dict[str, str]) -> None:
|
||||
for k, v in zip(d.keys(), d.values()): # SIM911
|
||||
...
|
||||
|
||||
for k, v in zip(d.keys(), d.values(), strict=True): # SIM911
|
||||
...
|
||||
|
||||
for k, v in zip(d.keys(), d.values(), struct=True): # OK
|
||||
...
|
||||
|
||||
|
||||
d1 = d2 = {}
|
||||
|
||||
for k, v in zip(d1.keys(), d2.values()): # OK
|
||||
...
|
||||
|
||||
for k, v in zip(d1.items(), d2.values()): # OK
|
||||
...
|
||||
|
||||
for k, v in zip(d2.keys(), d2.values()): # SIM911
|
||||
...
|
||||
|
||||
items = zip(x.keys(), x.values()) # OK
|
||||
@@ -1,185 +0,0 @@
|
||||
def after_return():
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
|
||||
async def also_works_on_async_functions():
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
|
||||
def if_always_true():
|
||||
if True:
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
|
||||
def if_always_false():
|
||||
if False:
|
||||
return "unreachable"
|
||||
return "reachable"
|
||||
|
||||
def if_elif_always_false():
|
||||
if False:
|
||||
return "unreachable"
|
||||
elif False:
|
||||
return "also unreachable"
|
||||
return "reachable"
|
||||
|
||||
def if_elif_always_true():
|
||||
if False:
|
||||
return "unreachable"
|
||||
elif True:
|
||||
return "reachable"
|
||||
return "also unreachable"
|
||||
|
||||
def ends_with_if():
|
||||
if False:
|
||||
return "unreachable"
|
||||
else:
|
||||
return "reachable"
|
||||
|
||||
def infinite_loop():
|
||||
while True:
|
||||
continue
|
||||
return "unreachable"
|
||||
|
||||
''' TODO: we could determine these, but we don't yet.
|
||||
def for_range_return():
|
||||
for i in range(10):
|
||||
if i == 5:
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
|
||||
def for_range_else():
|
||||
for i in range(111):
|
||||
if i == 5:
|
||||
return "reachable"
|
||||
else:
|
||||
return "unreachable"
|
||||
return "also unreachable"
|
||||
|
||||
def for_range_break():
|
||||
for i in range(13):
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
|
||||
def for_range_if_break():
|
||||
for i in range(1110):
|
||||
if True:
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
'''
|
||||
|
||||
def match_wildcard(status):
|
||||
match status:
|
||||
case _:
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
|
||||
def match_case_and_wildcard(status):
|
||||
match status:
|
||||
case 1:
|
||||
return "reachable"
|
||||
case _:
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
|
||||
def raise_exception():
|
||||
raise Exception
|
||||
return "unreachable"
|
||||
|
||||
def while_false():
|
||||
while False:
|
||||
return "unreachable"
|
||||
return "reachable"
|
||||
|
||||
def while_false_else():
|
||||
while False:
|
||||
return "unreachable"
|
||||
else:
|
||||
return "reachable"
|
||||
|
||||
def while_false_else_return():
|
||||
while False:
|
||||
return "unreachable"
|
||||
else:
|
||||
return "reachable"
|
||||
return "also unreachable"
|
||||
|
||||
def while_true():
|
||||
while True:
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
|
||||
def while_true_else():
|
||||
while True:
|
||||
return "reachable"
|
||||
else:
|
||||
return "unreachable"
|
||||
|
||||
def while_true_else_return():
|
||||
while True:
|
||||
return "reachable"
|
||||
else:
|
||||
return "unreachable"
|
||||
return "also unreachable"
|
||||
|
||||
def while_false_var_i():
|
||||
i = 0
|
||||
while False:
|
||||
i += 1
|
||||
return i
|
||||
|
||||
def while_true_var_i():
|
||||
i = 0
|
||||
while True:
|
||||
i += 1
|
||||
return i
|
||||
|
||||
def while_infinite():
|
||||
while True:
|
||||
pass
|
||||
return "unreachable"
|
||||
|
||||
def while_if_true():
|
||||
while True:
|
||||
if True:
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
|
||||
# Test case found in the Bokeh repository that trigger a false positive.
|
||||
def bokeh1(self, obj: BytesRep) -> bytes:
|
||||
data = obj["data"]
|
||||
|
||||
if isinstance(data, str):
|
||||
return base64.b64decode(data)
|
||||
elif isinstance(data, Buffer):
|
||||
buffer = data
|
||||
else:
|
||||
id = data["id"]
|
||||
|
||||
if id in self._buffers:
|
||||
buffer = self._buffers[id]
|
||||
else:
|
||||
self.error(f"can't resolve buffer '{id}'")
|
||||
|
||||
return buffer.data
|
||||
|
||||
'''
|
||||
TODO: because `try` statements aren't handled this triggers a false positive as
|
||||
the last statement is reached, but the rules thinks it isn't (it doesn't
|
||||
see/process the break statement).
|
||||
|
||||
# Test case found in the Bokeh repository that trigger a false positive.
|
||||
def bokeh2(self, host: str = DEFAULT_HOST, port: int = DEFAULT_PORT) -> None:
|
||||
self.stop_serving = False
|
||||
while True:
|
||||
try:
|
||||
self.server = HTTPServer((host, port), HtmlOnlyHandler)
|
||||
self.host = host
|
||||
self.port = port
|
||||
break
|
||||
except OSError:
|
||||
log.debug(f"port {port} is in use, trying to next one")
|
||||
port += 1
|
||||
|
||||
self.thread = threading.Thread(target=self._run_web_server)
|
||||
'''
|
||||
@@ -863,6 +863,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
|
||||
if checker.enabled(Rule::DictGetWithNoneDefault) {
|
||||
flake8_simplify::rules::dict_get_with_none_default(checker, expr);
|
||||
}
|
||||
if checker.enabled(Rule::ZipDictKeysAndValues) {
|
||||
flake8_simplify::rules::zip_dict_keys_and_values(checker, call);
|
||||
}
|
||||
if checker.any_enabled(&[
|
||||
Rule::OsPathAbspath,
|
||||
Rule::OsChmod,
|
||||
|
||||
@@ -355,12 +355,6 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
||||
if checker.enabled(Rule::TrioAsyncFunctionWithTimeout) {
|
||||
flake8_trio::rules::async_function_with_timeout(checker, function_def);
|
||||
}
|
||||
#[cfg(feature = "unreachable-code")]
|
||||
if checker.enabled(Rule::UnreachableCode) {
|
||||
checker
|
||||
.diagnostics
|
||||
.extend(ruff::rules::unreachable::in_function(name, body));
|
||||
}
|
||||
if checker.enabled(Rule::ReimplementedOperator) {
|
||||
refurb::rules::reimplemented_operator(checker, &function_def.into());
|
||||
}
|
||||
|
||||
@@ -472,6 +472,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8Simplify, "300") => (RuleGroup::Stable, rules::flake8_simplify::rules::YodaConditions),
|
||||
(Flake8Simplify, "401") => (RuleGroup::Stable, rules::flake8_simplify::rules::IfElseBlockInsteadOfDictGet),
|
||||
(Flake8Simplify, "910") => (RuleGroup::Stable, rules::flake8_simplify::rules::DictGetWithNoneDefault),
|
||||
(Flake8Simplify, "911") => (RuleGroup::Preview, rules::flake8_simplify::rules::ZipDictKeysAndValues),
|
||||
|
||||
// flake8-copyright
|
||||
#[allow(deprecated)]
|
||||
@@ -913,9 +914,6 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Ruff, "011") => (RuleGroup::Stable, rules::ruff::rules::StaticKeyDictComprehension),
|
||||
(Ruff, "012") => (RuleGroup::Stable, rules::ruff::rules::MutableClassDefault),
|
||||
(Ruff, "013") => (RuleGroup::Stable, rules::ruff::rules::ImplicitOptional),
|
||||
#[cfg(feature = "unreachable-code")] // When removing this feature gate, also update rules_selector.rs
|
||||
#[allow(deprecated)]
|
||||
(Ruff, "014") => (RuleGroup::Nursery, rules::ruff::rules::UnreachableCode),
|
||||
(Ruff, "015") => (RuleGroup::Stable, rules::ruff::rules::UnnecessaryIterableAllocationForFirstElement),
|
||||
(Ruff, "016") => (RuleGroup::Stable, rules::ruff::rules::InvalidIndexType),
|
||||
#[allow(deprecated)]
|
||||
|
||||
@@ -289,9 +289,6 @@ mod schema {
|
||||
(!prefix.is_empty()).then(|| prefix.to_string())
|
||||
})),
|
||||
)
|
||||
// Filter out rule gated behind `#[cfg(feature = "unreachable-code")]`, which is
|
||||
// off-by-default
|
||||
.filter(|prefix| prefix != "RUF014")
|
||||
.sorted()
|
||||
.map(Value::String)
|
||||
.collect(),
|
||||
@@ -407,40 +404,28 @@ pub mod clap_completion {
|
||||
let prefix = l.common_prefix();
|
||||
(!prefix.is_empty()).then(|| PossibleValue::new(prefix).help(l.name()))
|
||||
})
|
||||
.chain(
|
||||
RuleCodePrefix::iter()
|
||||
// Filter out rule gated behind `#[cfg(feature = "unreachable-code")]`, which is
|
||||
// off-by-default
|
||||
.filter(|prefix| {
|
||||
format!(
|
||||
"{}{}",
|
||||
prefix.linter().common_prefix(),
|
||||
prefix.short_code()
|
||||
) != "RUF014"
|
||||
})
|
||||
.filter_map(|prefix| {
|
||||
// Ex) `UP`
|
||||
if prefix.short_code().is_empty() {
|
||||
let code = prefix.linter().common_prefix();
|
||||
let name = prefix.linter().name();
|
||||
return Some(PossibleValue::new(code).help(name));
|
||||
}
|
||||
.chain(RuleCodePrefix::iter().filter_map(|prefix| {
|
||||
// Ex) `UP`
|
||||
if prefix.short_code().is_empty() {
|
||||
let code = prefix.linter().common_prefix();
|
||||
let name = prefix.linter().name();
|
||||
return Some(PossibleValue::new(code).help(name));
|
||||
}
|
||||
|
||||
// Ex) `UP004`
|
||||
if is_single_rule_selector(&prefix) {
|
||||
let rule = prefix.rules().next()?;
|
||||
let code = format!(
|
||||
"{}{}",
|
||||
prefix.linter().common_prefix(),
|
||||
prefix.short_code()
|
||||
);
|
||||
let name: &'static str = rule.into();
|
||||
return Some(PossibleValue::new(code).help(name));
|
||||
}
|
||||
// Ex) `UP004`
|
||||
if is_single_rule_selector(&prefix) {
|
||||
let rule = prefix.rules().next()?;
|
||||
let code = format!(
|
||||
"{}{}",
|
||||
prefix.linter().common_prefix(),
|
||||
prefix.short_code()
|
||||
);
|
||||
let name: &'static str = rule.into();
|
||||
return Some(PossibleValue::new(code).help(name));
|
||||
}
|
||||
|
||||
None
|
||||
}),
|
||||
),
|
||||
None
|
||||
})),
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ pub(crate) use reimplemented_builtin::*;
|
||||
pub(crate) use return_in_try_except_finally::*;
|
||||
pub(crate) use suppressible_exception::*;
|
||||
pub(crate) use yoda_conditions::*;
|
||||
pub(crate) use zip_dict_keys_and_values::*;
|
||||
|
||||
mod ast_bool_op;
|
||||
mod ast_expr;
|
||||
@@ -34,3 +35,4 @@ mod reimplemented_builtin;
|
||||
mod return_in_try_except_finally;
|
||||
mod suppressible_exception;
|
||||
mod yoda_conditions;
|
||||
mod zip_dict_keys_and_values;
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
use ast::{ExprAttribute, ExprName, Identifier};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::{self as ast, Arguments, Expr, ExprCall};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::{checkers::ast::Checker, fix::snippet::SourceCodeSnippet};
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_python_semantic::analyze::typing::is_dict;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for use of `zip()` to iterate over keys and values of a dictionary at once.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// The `dict` type provides an `.items()` method which is faster and more readable.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// flag_stars = {"USA": 50, "Slovenia": 3, "Panama": 2, "Australia": 6}
|
||||
///
|
||||
/// for country, stars in zip(flag_stars.keys(), flag_stars.values()):
|
||||
/// print(f"{country}'s flag has {stars} stars.")
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// flag_stars = {"USA": 50, "Slovenia": 3, "Panama": 2, "Australia": 6}
|
||||
///
|
||||
/// for country, stars in flag_stars.items():
|
||||
/// print(f"{country}'s flag has {stars} stars.")
|
||||
/// ```
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `dict.items`](https://docs.python.org/3/library/stdtypes.html#dict.items)
|
||||
#[violation]
|
||||
pub struct ZipDictKeysAndValues {
|
||||
expected: SourceCodeSnippet,
|
||||
actual: SourceCodeSnippet,
|
||||
}
|
||||
|
||||
impl AlwaysFixableViolation for ZipDictKeysAndValues {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ZipDictKeysAndValues { expected, actual } = self;
|
||||
if let (Some(expected), Some(actual)) = (expected.full_display(), actual.full_display()) {
|
||||
format!("Use `{expected}` instead of `{actual}`")
|
||||
} else {
|
||||
format!("Use `dict.items()` instead of `zip(dict.keys(), dict.values())`")
|
||||
}
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> String {
|
||||
let ZipDictKeysAndValues { expected, actual } = self;
|
||||
if let (Some(expected), Some(actual)) = (expected.full_display(), actual.full_display()) {
|
||||
format!("Replace `{actual}` with `{expected}`")
|
||||
} else {
|
||||
"Replace `zip(dict.keys(), dict.values())` with `dict.items()`".to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// SIM911
|
||||
pub(crate) fn zip_dict_keys_and_values(checker: &mut Checker, expr: &ExprCall) {
|
||||
let ExprCall {
|
||||
func,
|
||||
arguments: Arguments { args, keywords, .. },
|
||||
..
|
||||
} = expr;
|
||||
match &keywords[..] {
|
||||
[] => {}
|
||||
[ast::Keyword {
|
||||
arg: Some(name), ..
|
||||
}] if name.as_str() == "strict" => {}
|
||||
_ => return,
|
||||
};
|
||||
if matches!(func.as_ref(), Expr::Name(ExprName { id, .. }) if id != "zip") {
|
||||
return;
|
||||
}
|
||||
let [arg1, arg2] = &args[..] else {
|
||||
return;
|
||||
};
|
||||
let Some((var1, attr1)) = get_var_attr(arg1) else {
|
||||
return;
|
||||
};
|
||||
let Some((var2, attr2)) = get_var_attr(arg2) else {
|
||||
return;
|
||||
};
|
||||
if var1.id != var2.id || attr1 != "keys" || attr2 != "values" {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(binding) = checker
|
||||
.semantic()
|
||||
.only_binding(var1)
|
||||
.map(|id| checker.semantic().binding(id))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
if !is_dict(binding, checker.semantic()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let expected = format!("{}.items()", checker.locator().slice(var1));
|
||||
let actual = checker.locator().slice(expr);
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
ZipDictKeysAndValues {
|
||||
expected: SourceCodeSnippet::new(expected.clone()),
|
||||
actual: SourceCodeSnippet::from_str(actual),
|
||||
},
|
||||
expr.range(),
|
||||
);
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
expected,
|
||||
expr.range(),
|
||||
)));
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
||||
fn get_var_attr(expr: &Expr) -> Option<(&ExprName, &Identifier)> {
|
||||
let Expr::Call(ast::ExprCall { func, .. }) = expr else {
|
||||
return None;
|
||||
};
|
||||
let Expr::Attribute(ExprAttribute { value, attr, .. }) = func.as_ref() else {
|
||||
return None;
|
||||
};
|
||||
let Expr::Name(var_name) = value.as_ref() else {
|
||||
return None;
|
||||
};
|
||||
Some((var_name, attr))
|
||||
}
|
||||
@@ -1040,5 +1040,25 @@ SIM222.py:161:31: SIM222 [*] Use `(int, int, int)` instead of `(int, int, int) o
|
||||
161 |-def secondToTime(s0: int) -> ((int, int, int) or str):
|
||||
161 |+def secondToTime(s0: int) -> ((int, int, int)):
|
||||
162 162 | m, s = divmod(s0, 60)
|
||||
163 163 |
|
||||
164 164 |
|
||||
|
||||
SIM222.py:168:7: SIM222 [*] Use `"bar"` instead of `... or "bar"`
|
||||
|
|
||||
166 | print(f"{a}{b}" or "bar")
|
||||
167 | print(f"{a}{''}" or "bar")
|
||||
168 | print(f"{''}{''}" or "bar")
|
||||
| ^^^^^^^^^^^^^^^^^^^^ SIM222
|
||||
169 | print(f"{1}{''}" or "bar")
|
||||
|
|
||||
= help: Replace with `"bar"`
|
||||
|
||||
ℹ Unsafe fix
|
||||
165 165 | # Regression test for: https://github.com/astral-sh/ruff/issues/9479
|
||||
166 166 | print(f"{a}{b}" or "bar")
|
||||
167 167 | print(f"{a}{''}" or "bar")
|
||||
168 |-print(f"{''}{''}" or "bar")
|
||||
168 |+print("bar")
|
||||
169 169 | print(f"{1}{''}" or "bar")
|
||||
|
||||
|
||||
|
||||
@@ -1003,5 +1003,25 @@ SIM223.py:148:12: SIM223 [*] Use `[]` instead of `[] and ...`
|
||||
148 |-if f(a and [] and False and []): # SIM223
|
||||
148 |+if f(a and []): # SIM223
|
||||
149 149 | pass
|
||||
150 150 |
|
||||
151 151 | # Regression test for: https://github.com/astral-sh/ruff/issues/9479
|
||||
|
||||
SIM223.py:154:7: SIM223 [*] Use `f"{''}{''}"` instead of `f"{''}{''}" and ...`
|
||||
|
|
||||
152 | print(f"{a}{b}" and "bar")
|
||||
153 | print(f"{a}{''}" and "bar")
|
||||
154 | print(f"{''}{''}" and "bar")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ SIM223
|
||||
155 | print(f"{1}{''}" and "bar")
|
||||
|
|
||||
= help: Replace with `f"{''}{''}"`
|
||||
|
||||
ℹ Unsafe fix
|
||||
151 151 | # Regression test for: https://github.com/astral-sh/ruff/issues/9479
|
||||
152 152 | print(f"{a}{b}" and "bar")
|
||||
153 153 | print(f"{a}{''}" and "bar")
|
||||
154 |-print(f"{''}{''}" and "bar")
|
||||
154 |+print(f"{''}{''}")
|
||||
155 155 | print(f"{1}{''}" and "bar")
|
||||
|
||||
|
||||
|
||||
@@ -273,7 +273,7 @@ impl DunderReplacement {
|
||||
"__str__" => Some(Self::Builtin("str", "Use `str()` builtin")),
|
||||
"__subclasscheck__" => Some(Self::Builtin("issubclass", "Use `issubclass()` builtin")),
|
||||
|
||||
"__aenter__" => Some(Self::MessageOnly("Use `aenter()` builtin")),
|
||||
"__aenter__" => Some(Self::MessageOnly("Invoke context manager directly")),
|
||||
"__ceil__" => Some(Self::MessageOnly("Use `math.ceil()` function")),
|
||||
"__copy__" => Some(Self::MessageOnly("Use `copy.copy()` function")),
|
||||
"__deepcopy__" => Some(Self::MessageOnly("Use `copy.deepcopy()` function")),
|
||||
@@ -283,15 +283,15 @@ impl DunderReplacement {
|
||||
"__delitem__" => Some(Self::MessageOnly("Use `del` statement")),
|
||||
"__divmod__" => Some(Self::MessageOnly("Use `divmod()` builtin")),
|
||||
"__format__" => Some(Self::MessageOnly(
|
||||
"Use `format` builtin, format string method, or f-string.",
|
||||
"Use `format` builtin, format string method, or f-string",
|
||||
)),
|
||||
"__fspath__" => Some(Self::MessageOnly("Use `os.fspath` function")),
|
||||
"__get__" => Some(Self::MessageOnly("Use `get` method")),
|
||||
"__getattr__" => Some(Self::MessageOnly(
|
||||
"Access attribute directly or use getattr built-in function.",
|
||||
"Access attribute directly or use getattr built-in function",
|
||||
)),
|
||||
"__getattribute__" => Some(Self::MessageOnly(
|
||||
"Access attribute directly or use getattr built-in function.",
|
||||
"Access attribute directly or use getattr built-in function",
|
||||
)),
|
||||
"__getitem__" => Some(Self::MessageOnly("Access item via subscript")),
|
||||
"__init__" => Some(Self::MessageOnly("Instantiate class directly")),
|
||||
@@ -304,7 +304,7 @@ impl DunderReplacement {
|
||||
"__rpow__" => Some(Self::MessageOnly("Use ** operator or `pow()` builtin")),
|
||||
"__set__" => Some(Self::MessageOnly("Use subscript assignment")),
|
||||
"__setattr__" => Some(Self::MessageOnly(
|
||||
"Mutate attribute directly or use setattr built-in function.",
|
||||
"Mutate attribute directly or use setattr built-in function",
|
||||
)),
|
||||
"__setitem__" => Some(Self::MessageOnly("Use subscript assignment")),
|
||||
"__truncate__" => Some(Self::MessageOnly("Use `math.trunc()` function")),
|
||||
|
||||
@@ -37,10 +37,6 @@ mod tests {
|
||||
Path::new("RUF015.py")
|
||||
)]
|
||||
#[test_case(Rule::InvalidIndexType, Path::new("RUF016.py"))]
|
||||
#[cfg_attr(
|
||||
feature = "unreachable-code",
|
||||
test_case(Rule::UnreachableCode, Path::new("RUF014.py"))
|
||||
)]
|
||||
#[test_case(Rule::QuadraticListSummation, Path::new("RUF017_1.py"))]
|
||||
#[test_case(Rule::QuadraticListSummation, Path::new("RUF017_0.py"))]
|
||||
#[test_case(Rule::AssignmentInAssert, Path::new("RUF018.py"))]
|
||||
|
||||
@@ -16,8 +16,6 @@ pub(crate) use quadratic_list_summation::*;
|
||||
pub(crate) use static_key_dict_comprehension::*;
|
||||
pub(crate) use unnecessary_iterable_allocation_for_first_element::*;
|
||||
pub(crate) use unnecessary_key_check::*;
|
||||
#[cfg(feature = "unreachable-code")]
|
||||
pub(crate) use unreachable::*;
|
||||
pub(crate) use unused_noqa::*;
|
||||
|
||||
mod ambiguous_unicode_character;
|
||||
@@ -39,8 +37,6 @@ mod parenthesize_logical_operators;
|
||||
mod static_key_dict_comprehension;
|
||||
mod unnecessary_iterable_allocation_for_first_element;
|
||||
mod unnecessary_key_check;
|
||||
#[cfg(feature = "unreachable-code")]
|
||||
pub(crate) mod unreachable;
|
||||
mod unused_noqa;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
||||
@@ -32,7 +32,7 @@ use crate::checkers::ast::Checker;
|
||||
///
|
||||
/// d, e, f = 0, 1, 2
|
||||
/// y = (d and e) or f
|
||||
/// ````
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct ParenthesizeChainedOperators;
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/rules/unreachable.rs
|
||||
description: "This is a Mermaid graph. You can use https://mermaid.live to visualize it as a diagram."
|
||||
---
|
||||
## Function 0
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
assert True
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Exception raised"]]
|
||||
block2["assert True\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "True" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 1
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
assert False
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Exception raised"]]
|
||||
block2["assert False\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "False" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 2
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
assert True, "oops"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Exception raised"]]
|
||||
block2["assert True, #quot;oops#quot;\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "True" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 3
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
assert False, "oops"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Exception raised"]]
|
||||
block2["assert False, #quot;oops#quot;\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "False" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/rules/unreachable.rs
|
||||
description: "This is a Mermaid graph. You can use https://mermaid.live to visualize it as a diagram."
|
||||
---
|
||||
## Function 0
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
async for i in range(5):
|
||||
print(i)
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(i)\n"]
|
||||
block2["async for i in range(5):
|
||||
print(i)\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "range(5)" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block2
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 1
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
async for i in range(20):
|
||||
print(i)
|
||||
else:
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["print(i)\n"]
|
||||
block1["return 0\n"]
|
||||
block2["async for i in range(20):
|
||||
print(i)
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "range(20)" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 2
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
async for i in range(10):
|
||||
if i == 5:
|
||||
return 1
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 0\n"]
|
||||
block1["return 1\n"]
|
||||
block2["if i == 5:
|
||||
return 1\n"]
|
||||
block3["async for i in range(10):
|
||||
if i == 5:
|
||||
return 1\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(10)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 -- "i == 5" --> block1
|
||||
block2 -- "else" --> block3
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 3
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
async for i in range(111):
|
||||
if i == 5:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
return 2
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 2\n"]
|
||||
block1["return 1\n"]
|
||||
block2["if i == 5:
|
||||
return 1\n"]
|
||||
block3["return 0\n"]
|
||||
block4["async for i in range(111):
|
||||
if i == 5:
|
||||
return 1
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(111)" --> block2
|
||||
block4 -- "else" --> block3
|
||||
block3 --> return
|
||||
block2 -- "i == 5" --> block1
|
||||
block2 -- "else" --> block4
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 4
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
async for i in range(12):
|
||||
continue
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["continue\n"]
|
||||
block2["async for i in range(12):
|
||||
continue\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "range(12)" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block2
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 5
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
async for i in range(1110):
|
||||
if True:
|
||||
continue
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["continue\n"]
|
||||
block2["if True:
|
||||
continue\n"]
|
||||
block3["async for i in range(1110):
|
||||
if True:
|
||||
continue\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(1110)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block3
|
||||
block1 --> block3
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 6
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
async for i in range(13):
|
||||
break
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["break\n"]
|
||||
block2["async for i in range(13):
|
||||
break\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "range(13)" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 7
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
async for i in range(1110):
|
||||
if True:
|
||||
break
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["break\n"]
|
||||
block2["if True:
|
||||
break\n"]
|
||||
block3["async for i in range(1110):
|
||||
if True:
|
||||
break\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(1110)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block3
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
|
||||
@@ -1,302 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/rules/unreachable.rs
|
||||
description: "This is a Mermaid graph. You can use https://mermaid.live to visualize it as a diagram."
|
||||
---
|
||||
## Function 0
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(5):
|
||||
print(i)
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(i)\n"]
|
||||
block2["for i in range(5):
|
||||
print(i)\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "range(5)" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block2
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 1
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(20):
|
||||
print(i)
|
||||
else:
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["print(i)\n"]
|
||||
block1["return 0\n"]
|
||||
block2["for i in range(20):
|
||||
print(i)
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "range(20)" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 2
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(10):
|
||||
if i == 5:
|
||||
return 1
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 0\n"]
|
||||
block1["return 1\n"]
|
||||
block2["if i == 5:
|
||||
return 1\n"]
|
||||
block3["for i in range(10):
|
||||
if i == 5:
|
||||
return 1\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(10)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 -- "i == 5" --> block1
|
||||
block2 -- "else" --> block3
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 3
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(111):
|
||||
if i == 5:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
return 2
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 2\n"]
|
||||
block1["return 1\n"]
|
||||
block2["if i == 5:
|
||||
return 1\n"]
|
||||
block3["return 0\n"]
|
||||
block4["for i in range(111):
|
||||
if i == 5:
|
||||
return 1
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(111)" --> block2
|
||||
block4 -- "else" --> block3
|
||||
block3 --> return
|
||||
block2 -- "i == 5" --> block1
|
||||
block2 -- "else" --> block4
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 4
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(12):
|
||||
continue
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["continue\n"]
|
||||
block2["for i in range(12):
|
||||
continue\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "range(12)" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block2
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 5
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(1110):
|
||||
if True:
|
||||
continue
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["continue\n"]
|
||||
block2["if True:
|
||||
continue\n"]
|
||||
block3["for i in range(1110):
|
||||
if True:
|
||||
continue\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(1110)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block3
|
||||
block1 --> block3
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 6
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(13):
|
||||
break
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["break\n"]
|
||||
block2["for i in range(13):
|
||||
break\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "range(13)" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 7
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(1110):
|
||||
if True:
|
||||
break
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["break\n"]
|
||||
block2["if True:
|
||||
break\n"]
|
||||
block3["for i in range(1110):
|
||||
if True:
|
||||
break\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(1110)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block3
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 8
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(5):
|
||||
pass
|
||||
else:
|
||||
return 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["pass\n"]
|
||||
block1["return 1\n"]
|
||||
block2["for i in range(5):
|
||||
pass
|
||||
else:
|
||||
return 1\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "range(5)" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 9
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(5):
|
||||
pass
|
||||
else:
|
||||
return 1
|
||||
x = 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["x = 1\n"]
|
||||
block1["pass\n"]
|
||||
block2["return 1\n"]
|
||||
block3["for i in range(5):
|
||||
pass
|
||||
else:
|
||||
return 1\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(5)" --> block1
|
||||
block3 -- "else" --> block2
|
||||
block2 --> return
|
||||
block1 --> block3
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
|
||||
@@ -1,553 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/rules/unreachable.rs
|
||||
description: "This is a Mermaid graph. You can use https://mermaid.live to visualize it as a diagram."
|
||||
---
|
||||
## Function 0
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if False:
|
||||
return 0
|
||||
return 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 1\n"]
|
||||
block1["return 0\n"]
|
||||
block2["if False:
|
||||
return 0\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "False" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 1
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if True:
|
||||
return 1
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 0\n"]
|
||||
block1["return 1\n"]
|
||||
block2["if True:
|
||||
return 1\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 2
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if False:
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 0\n"]
|
||||
block1["return 1\n"]
|
||||
block2["if False:
|
||||
return 0
|
||||
else:
|
||||
return 1\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "False" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 3
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if True:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 1\n"]
|
||||
block1["return 0\n"]
|
||||
block2["if True:
|
||||
return 1
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "True" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 4
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if False:
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
return "unreachable"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return #quot;unreachable#quot;\n"]
|
||||
block1["return 0\n"]
|
||||
block2["return 1\n"]
|
||||
block3["if False:
|
||||
return 0
|
||||
else:
|
||||
return 1\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "False" --> block1
|
||||
block3 -- "else" --> block2
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 5
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if True:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
return "unreachable"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return #quot;unreachable#quot;\n"]
|
||||
block1["return 1\n"]
|
||||
block2["return 0\n"]
|
||||
block3["if True:
|
||||
return 1
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "True" --> block1
|
||||
block3 -- "else" --> block2
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 6
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if True:
|
||||
if True:
|
||||
return 1
|
||||
return 2
|
||||
else:
|
||||
return 3
|
||||
return "unreachable2"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return #quot;unreachable2#quot;\n"]
|
||||
block1["return 2\n"]
|
||||
block2["return 1\n"]
|
||||
block3["if True:
|
||||
return 1\n"]
|
||||
block4["return 3\n"]
|
||||
block5["if True:
|
||||
if True:
|
||||
return 1
|
||||
return 2
|
||||
else:
|
||||
return 3\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "True" --> block3
|
||||
block5 -- "else" --> block4
|
||||
block4 --> return
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 7
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if False:
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["return 0\n"]
|
||||
block2["if False:
|
||||
return 0\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "False" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 8
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if True:
|
||||
return 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["return 1\n"]
|
||||
block2["if True:
|
||||
return 1\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 9
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if True:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
else:
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 1\n"]
|
||||
block1["return 0\n"]
|
||||
block2["return 2\n"]
|
||||
block3["if True:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
else:
|
||||
return 0\n"]
|
||||
block4["if True:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "True" --> block0
|
||||
block4 -- "else" --> block3
|
||||
block3 -- "False" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 10
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if False:
|
||||
return 1
|
||||
elif True:
|
||||
return 2
|
||||
else:
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 1\n"]
|
||||
block1["return 0\n"]
|
||||
block2["return 2\n"]
|
||||
block3["if False:
|
||||
return 1
|
||||
elif True:
|
||||
return 2
|
||||
else:
|
||||
return 0\n"]
|
||||
block4["if False:
|
||||
return 1
|
||||
elif True:
|
||||
return 2
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "False" --> block0
|
||||
block4 -- "else" --> block3
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 11
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if True:
|
||||
if False:
|
||||
return 0
|
||||
elif True:
|
||||
return 1
|
||||
else:
|
||||
return 2
|
||||
return 3
|
||||
elif True:
|
||||
return 4
|
||||
else:
|
||||
return 5
|
||||
return 6
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 6\n"]
|
||||
block1["return 3\n"]
|
||||
block2["return 0\n"]
|
||||
block3["return 2\n"]
|
||||
block4["return 1\n"]
|
||||
block5["if False:
|
||||
return 0
|
||||
elif True:
|
||||
return 1
|
||||
else:
|
||||
return 2\n"]
|
||||
block6["if False:
|
||||
return 0
|
||||
elif True:
|
||||
return 1
|
||||
else:
|
||||
return 2\n"]
|
||||
block7["return 5\n"]
|
||||
block8["return 4\n"]
|
||||
block9["if True:
|
||||
if False:
|
||||
return 0
|
||||
elif True:
|
||||
return 1
|
||||
else:
|
||||
return 2
|
||||
return 3
|
||||
elif True:
|
||||
return 4
|
||||
else:
|
||||
return 5\n"]
|
||||
block10["if True:
|
||||
if False:
|
||||
return 0
|
||||
elif True:
|
||||
return 1
|
||||
else:
|
||||
return 2
|
||||
return 3
|
||||
elif True:
|
||||
return 4
|
||||
else:
|
||||
return 5\n"]
|
||||
|
||||
start --> block10
|
||||
block10 -- "True" --> block6
|
||||
block10 -- "else" --> block9
|
||||
block9 -- "True" --> block8
|
||||
block9 -- "else" --> block7
|
||||
block8 --> return
|
||||
block7 --> return
|
||||
block6 -- "False" --> block2
|
||||
block6 -- "else" --> block5
|
||||
block5 -- "True" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> return
|
||||
block3 --> return
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 12
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if False:
|
||||
return "unreached"
|
||||
elif False:
|
||||
return "also unreached"
|
||||
return "reached"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return #quot;reached#quot;\n"]
|
||||
block1["return #quot;unreached#quot;\n"]
|
||||
block2["return #quot;also unreached#quot;\n"]
|
||||
block3["if False:
|
||||
return #quot;unreached#quot;
|
||||
elif False:
|
||||
return #quot;also unreached#quot;\n"]
|
||||
block4["if False:
|
||||
return #quot;unreached#quot;
|
||||
elif False:
|
||||
return #quot;also unreached#quot;\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "False" --> block1
|
||||
block4 -- "else" --> block3
|
||||
block3 -- "False" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 13
|
||||
### Source
|
||||
```python
|
||||
def func(self, obj: BytesRep) -> bytes:
|
||||
data = obj["data"]
|
||||
|
||||
if isinstance(data, str):
|
||||
return base64.b64decode(data)
|
||||
elif isinstance(data, Buffer):
|
||||
buffer = data
|
||||
else:
|
||||
id = data["id"]
|
||||
|
||||
if id in self._buffers:
|
||||
buffer = self._buffers[id]
|
||||
else:
|
||||
self.error(f"can't resolve buffer '{id}'")
|
||||
|
||||
return buffer.data
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return buffer.data\n"]
|
||||
block1["return base64.b64decode(data)\n"]
|
||||
block2["buffer = self._buffers[id]\n"]
|
||||
block3["self.error(f#quot;can't resolve buffer '{id}'#quot;)\n"]
|
||||
block4["id = data[#quot;id#quot;]\nif id in self._buffers:
|
||||
buffer = self._buffers[id]
|
||||
else:
|
||||
self.error(f#quot;can't resolve buffer '{id}'#quot;)\n"]
|
||||
block5["buffer = data\n"]
|
||||
block6["if isinstance(data, str):
|
||||
return base64.b64decode(data)
|
||||
elif isinstance(data, Buffer):
|
||||
buffer = data
|
||||
else:
|
||||
id = data[#quot;id#quot;]
|
||||
|
||||
if id in self._buffers:
|
||||
buffer = self._buffers[id]
|
||||
else:
|
||||
self.error(f#quot;can't resolve buffer '{id}'#quot;)\n"]
|
||||
block7["data = obj[#quot;data#quot;]\nif isinstance(data, str):
|
||||
return base64.b64decode(data)
|
||||
elif isinstance(data, Buffer):
|
||||
buffer = data
|
||||
else:
|
||||
id = data[#quot;id#quot;]
|
||||
|
||||
if id in self._buffers:
|
||||
buffer = self._buffers[id]
|
||||
else:
|
||||
self.error(f#quot;can't resolve buffer '{id}'#quot;)\n"]
|
||||
|
||||
start --> block7
|
||||
block7 -- "isinstance(data, str)" --> block1
|
||||
block7 -- "else" --> block6
|
||||
block6 -- "isinstance(data, Buffer)" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block0
|
||||
block4 -- "id in self._buffers" --> block2
|
||||
block4 -- "else" --> block3
|
||||
block3 --> block0
|
||||
block2 --> block0
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
|
||||
@@ -1,815 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/rules/unreachable.rs
|
||||
description: "This is a Mermaid graph. You can use https://mermaid.live to visualize it as a diagram."
|
||||
---
|
||||
## Function 0
|
||||
### Source
|
||||
```python
|
||||
def func(status):
|
||||
match status:
|
||||
case _:
|
||||
return 0
|
||||
return "unreachable"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return #quot;unreachable#quot;\n"]
|
||||
block1["return 0\n"]
|
||||
block2["match status:
|
||||
case _:
|
||||
return 0\n"]
|
||||
|
||||
start --> block2
|
||||
block2 --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 1
|
||||
### Source
|
||||
```python
|
||||
def func(status):
|
||||
match status:
|
||||
case 1:
|
||||
return 1
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 0\n"]
|
||||
block1["return 1\n"]
|
||||
block2["match status:
|
||||
case 1:
|
||||
return 1\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "case 1" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 2
|
||||
### Source
|
||||
```python
|
||||
def func(status):
|
||||
match status:
|
||||
case 1:
|
||||
return 1
|
||||
case _:
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 0\n"]
|
||||
block1["match status:
|
||||
case 1:
|
||||
return 1
|
||||
case _:
|
||||
return 0\n"]
|
||||
block2["return 1\n"]
|
||||
block3["match status:
|
||||
case 1:
|
||||
return 1
|
||||
case _:
|
||||
return 0\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "case 1" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> return
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 3
|
||||
### Source
|
||||
```python
|
||||
def func(status):
|
||||
match status:
|
||||
case 1 | 2 | 3:
|
||||
return 5
|
||||
return 6
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 6\n"]
|
||||
block1["return 5\n"]
|
||||
block2["match status:
|
||||
case 1 | 2 | 3:
|
||||
return 5\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "case 1 | 2 | 3" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 4
|
||||
### Source
|
||||
```python
|
||||
def func(status):
|
||||
match status:
|
||||
case 1 | 2 | 3:
|
||||
return 5
|
||||
case _:
|
||||
return 10
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 0\n"]
|
||||
block1["return 10\n"]
|
||||
block2["match status:
|
||||
case 1 | 2 | 3:
|
||||
return 5
|
||||
case _:
|
||||
return 10\n"]
|
||||
block3["return 5\n"]
|
||||
block4["match status:
|
||||
case 1 | 2 | 3:
|
||||
return 5
|
||||
case _:
|
||||
return 10\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "case 1 | 2 | 3" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> return
|
||||
block2 --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 5
|
||||
### Source
|
||||
```python
|
||||
def func(status):
|
||||
match status:
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return 1
|
||||
case 1:
|
||||
return "1 again"
|
||||
case _:
|
||||
return 3
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 3\n"]
|
||||
block1["match status:
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return 1
|
||||
case 1:
|
||||
return #quot;1 again#quot;
|
||||
case _:
|
||||
return 3\n"]
|
||||
block2["return #quot;1 again#quot;\n"]
|
||||
block3["match status:
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return 1
|
||||
case 1:
|
||||
return #quot;1 again#quot;
|
||||
case _:
|
||||
return 3\n"]
|
||||
block4["return 1\n"]
|
||||
block5["match status:
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return 1
|
||||
case 1:
|
||||
return #quot;1 again#quot;
|
||||
case _:
|
||||
return 3\n"]
|
||||
block6["return 0\n"]
|
||||
block7["match status:
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return 1
|
||||
case 1:
|
||||
return #quot;1 again#quot;
|
||||
case _:
|
||||
return 3\n"]
|
||||
|
||||
start --> block7
|
||||
block7 -- "case 0" --> block6
|
||||
block7 -- "else" --> block5
|
||||
block6 --> return
|
||||
block5 -- "case 1" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> return
|
||||
block3 -- "case 1" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> return
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 6
|
||||
### Source
|
||||
```python
|
||||
def func(status):
|
||||
i = 0
|
||||
match status, i:
|
||||
case _, _:
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["return 0\n"]
|
||||
block2["match status, i:
|
||||
case _, _:
|
||||
return 0\n"]
|
||||
block3["i = 0\n"]
|
||||
|
||||
start --> block3
|
||||
block3 --> block2
|
||||
block2 -- "case _, _" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 7
|
||||
### Source
|
||||
```python
|
||||
def func(status):
|
||||
i = 0
|
||||
match status, i:
|
||||
case _, 0:
|
||||
return 0
|
||||
case _, 2:
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["return 0\n"]
|
||||
block2["match status, i:
|
||||
case _, 0:
|
||||
return 0
|
||||
case _, 2:
|
||||
return 0\n"]
|
||||
block3["return 0\n"]
|
||||
block4["match status, i:
|
||||
case _, 0:
|
||||
return 0
|
||||
case _, 2:
|
||||
return 0\n"]
|
||||
block5["i = 0\n"]
|
||||
|
||||
start --> block5
|
||||
block5 --> block4
|
||||
block4 -- "case _, 0" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> return
|
||||
block2 -- "case _, 2" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 8
|
||||
### Source
|
||||
```python
|
||||
def func(point):
|
||||
match point:
|
||||
case (0, 0):
|
||||
print("Origin")
|
||||
case _:
|
||||
raise ValueError("oops")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["raise ValueError(#quot;oops#quot;)\n"]
|
||||
block2["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case _:
|
||||
raise ValueError(#quot;oops#quot;)\n"]
|
||||
block3["print(#quot;Origin#quot;)\n"]
|
||||
block4["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case _:
|
||||
raise ValueError(#quot;oops#quot;)\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "case (0, 0)" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block0
|
||||
block2 --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 9
|
||||
### Source
|
||||
```python
|
||||
def func(point):
|
||||
match point:
|
||||
case (0, 0):
|
||||
print("Origin")
|
||||
case (0, y):
|
||||
print(f"Y={y}")
|
||||
case (x, 0):
|
||||
print(f"X={x}")
|
||||
case (x, y):
|
||||
print(f"X={x}, Y={y}")
|
||||
case _:
|
||||
raise ValueError("Not a point")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["raise ValueError(#quot;Not a point#quot;)\n"]
|
||||
block2["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case (0, y):
|
||||
print(f#quot;Y={y}#quot;)
|
||||
case (x, 0):
|
||||
print(f#quot;X={x}#quot;)
|
||||
case (x, y):
|
||||
print(f#quot;X={x}, Y={y}#quot;)
|
||||
case _:
|
||||
raise ValueError(#quot;Not a point#quot;)\n"]
|
||||
block3["print(f#quot;X={x}, Y={y}#quot;)\n"]
|
||||
block4["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case (0, y):
|
||||
print(f#quot;Y={y}#quot;)
|
||||
case (x, 0):
|
||||
print(f#quot;X={x}#quot;)
|
||||
case (x, y):
|
||||
print(f#quot;X={x}, Y={y}#quot;)
|
||||
case _:
|
||||
raise ValueError(#quot;Not a point#quot;)\n"]
|
||||
block5["print(f#quot;X={x}#quot;)\n"]
|
||||
block6["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case (0, y):
|
||||
print(f#quot;Y={y}#quot;)
|
||||
case (x, 0):
|
||||
print(f#quot;X={x}#quot;)
|
||||
case (x, y):
|
||||
print(f#quot;X={x}, Y={y}#quot;)
|
||||
case _:
|
||||
raise ValueError(#quot;Not a point#quot;)\n"]
|
||||
block7["print(f#quot;Y={y}#quot;)\n"]
|
||||
block8["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case (0, y):
|
||||
print(f#quot;Y={y}#quot;)
|
||||
case (x, 0):
|
||||
print(f#quot;X={x}#quot;)
|
||||
case (x, y):
|
||||
print(f#quot;X={x}, Y={y}#quot;)
|
||||
case _:
|
||||
raise ValueError(#quot;Not a point#quot;)\n"]
|
||||
block9["print(#quot;Origin#quot;)\n"]
|
||||
block10["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case (0, y):
|
||||
print(f#quot;Y={y}#quot;)
|
||||
case (x, 0):
|
||||
print(f#quot;X={x}#quot;)
|
||||
case (x, y):
|
||||
print(f#quot;X={x}, Y={y}#quot;)
|
||||
case _:
|
||||
raise ValueError(#quot;Not a point#quot;)\n"]
|
||||
|
||||
start --> block10
|
||||
block10 -- "case (0, 0)" --> block9
|
||||
block10 -- "else" --> block8
|
||||
block9 --> block0
|
||||
block8 -- "case (0, y)" --> block7
|
||||
block8 -- "else" --> block6
|
||||
block7 --> block0
|
||||
block6 -- "case (x, 0)" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block0
|
||||
block4 -- "case (x, y)" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block0
|
||||
block2 --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 10
|
||||
### Source
|
||||
```python
|
||||
def where_is(point):
|
||||
class Point:
|
||||
x: int
|
||||
y: int
|
||||
|
||||
match point:
|
||||
case Point(x=0, y=0):
|
||||
print("Origin")
|
||||
case Point(x=0, y=y):
|
||||
print(f"Y={y}")
|
||||
case Point(x=x, y=0):
|
||||
print(f"X={x}")
|
||||
case Point():
|
||||
print("Somewhere else")
|
||||
case _:
|
||||
print("Not a point")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(#quot;Not a point#quot;)\n"]
|
||||
block2["match point:
|
||||
case Point(x=0, y=0):
|
||||
print(#quot;Origin#quot;)
|
||||
case Point(x=0, y=y):
|
||||
print(f#quot;Y={y}#quot;)
|
||||
case Point(x=x, y=0):
|
||||
print(f#quot;X={x}#quot;)
|
||||
case Point():
|
||||
print(#quot;Somewhere else#quot;)
|
||||
case _:
|
||||
print(#quot;Not a point#quot;)\n"]
|
||||
block3["print(#quot;Somewhere else#quot;)\n"]
|
||||
block4["match point:
|
||||
case Point(x=0, y=0):
|
||||
print(#quot;Origin#quot;)
|
||||
case Point(x=0, y=y):
|
||||
print(f#quot;Y={y}#quot;)
|
||||
case Point(x=x, y=0):
|
||||
print(f#quot;X={x}#quot;)
|
||||
case Point():
|
||||
print(#quot;Somewhere else#quot;)
|
||||
case _:
|
||||
print(#quot;Not a point#quot;)\n"]
|
||||
block5["print(f#quot;X={x}#quot;)\n"]
|
||||
block6["match point:
|
||||
case Point(x=0, y=0):
|
||||
print(#quot;Origin#quot;)
|
||||
case Point(x=0, y=y):
|
||||
print(f#quot;Y={y}#quot;)
|
||||
case Point(x=x, y=0):
|
||||
print(f#quot;X={x}#quot;)
|
||||
case Point():
|
||||
print(#quot;Somewhere else#quot;)
|
||||
case _:
|
||||
print(#quot;Not a point#quot;)\n"]
|
||||
block7["print(f#quot;Y={y}#quot;)\n"]
|
||||
block8["match point:
|
||||
case Point(x=0, y=0):
|
||||
print(#quot;Origin#quot;)
|
||||
case Point(x=0, y=y):
|
||||
print(f#quot;Y={y}#quot;)
|
||||
case Point(x=x, y=0):
|
||||
print(f#quot;X={x}#quot;)
|
||||
case Point():
|
||||
print(#quot;Somewhere else#quot;)
|
||||
case _:
|
||||
print(#quot;Not a point#quot;)\n"]
|
||||
block9["print(#quot;Origin#quot;)\n"]
|
||||
block10["match point:
|
||||
case Point(x=0, y=0):
|
||||
print(#quot;Origin#quot;)
|
||||
case Point(x=0, y=y):
|
||||
print(f#quot;Y={y}#quot;)
|
||||
case Point(x=x, y=0):
|
||||
print(f#quot;X={x}#quot;)
|
||||
case Point():
|
||||
print(#quot;Somewhere else#quot;)
|
||||
case _:
|
||||
print(#quot;Not a point#quot;)\n"]
|
||||
block11["class Point:
|
||||
x: int
|
||||
y: int\n"]
|
||||
|
||||
start --> block11
|
||||
block11 --> block10
|
||||
block10 -- "case Point(x=0, y=0)" --> block9
|
||||
block10 -- "else" --> block8
|
||||
block9 --> block0
|
||||
block8 -- "case Point(x=0, y=y)" --> block7
|
||||
block8 -- "else" --> block6
|
||||
block7 --> block0
|
||||
block6 -- "case Point(x=x, y=0)" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block0
|
||||
block4 -- "case Point()" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block0
|
||||
block2 --> block1
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 11
|
||||
### Source
|
||||
```python
|
||||
def func(points):
|
||||
match points:
|
||||
case []:
|
||||
print("No points")
|
||||
case [Point(0, 0)]:
|
||||
print("The origin")
|
||||
case [Point(x, y)]:
|
||||
print(f"Single point {x}, {y}")
|
||||
case [Point(0, y1), Point(0, y2)]:
|
||||
print(f"Two on the Y axis at {y1}, {y2}")
|
||||
case _:
|
||||
print("Something else")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(#quot;Something else#quot;)\n"]
|
||||
block2["match points:
|
||||
case []:
|
||||
print(#quot;No points#quot;)
|
||||
case [Point(0, 0)]:
|
||||
print(#quot;The origin#quot;)
|
||||
case [Point(x, y)]:
|
||||
print(f#quot;Single point {x}, {y}#quot;)
|
||||
case [Point(0, y1), Point(0, y2)]:
|
||||
print(f#quot;Two on the Y axis at {y1}, {y2}#quot;)
|
||||
case _:
|
||||
print(#quot;Something else#quot;)\n"]
|
||||
block3["print(f#quot;Two on the Y axis at {y1}, {y2}#quot;)\n"]
|
||||
block4["match points:
|
||||
case []:
|
||||
print(#quot;No points#quot;)
|
||||
case [Point(0, 0)]:
|
||||
print(#quot;The origin#quot;)
|
||||
case [Point(x, y)]:
|
||||
print(f#quot;Single point {x}, {y}#quot;)
|
||||
case [Point(0, y1), Point(0, y2)]:
|
||||
print(f#quot;Two on the Y axis at {y1}, {y2}#quot;)
|
||||
case _:
|
||||
print(#quot;Something else#quot;)\n"]
|
||||
block5["print(f#quot;Single point {x}, {y}#quot;)\n"]
|
||||
block6["match points:
|
||||
case []:
|
||||
print(#quot;No points#quot;)
|
||||
case [Point(0, 0)]:
|
||||
print(#quot;The origin#quot;)
|
||||
case [Point(x, y)]:
|
||||
print(f#quot;Single point {x}, {y}#quot;)
|
||||
case [Point(0, y1), Point(0, y2)]:
|
||||
print(f#quot;Two on the Y axis at {y1}, {y2}#quot;)
|
||||
case _:
|
||||
print(#quot;Something else#quot;)\n"]
|
||||
block7["print(#quot;The origin#quot;)\n"]
|
||||
block8["match points:
|
||||
case []:
|
||||
print(#quot;No points#quot;)
|
||||
case [Point(0, 0)]:
|
||||
print(#quot;The origin#quot;)
|
||||
case [Point(x, y)]:
|
||||
print(f#quot;Single point {x}, {y}#quot;)
|
||||
case [Point(0, y1), Point(0, y2)]:
|
||||
print(f#quot;Two on the Y axis at {y1}, {y2}#quot;)
|
||||
case _:
|
||||
print(#quot;Something else#quot;)\n"]
|
||||
block9["print(#quot;No points#quot;)\n"]
|
||||
block10["match points:
|
||||
case []:
|
||||
print(#quot;No points#quot;)
|
||||
case [Point(0, 0)]:
|
||||
print(#quot;The origin#quot;)
|
||||
case [Point(x, y)]:
|
||||
print(f#quot;Single point {x}, {y}#quot;)
|
||||
case [Point(0, y1), Point(0, y2)]:
|
||||
print(f#quot;Two on the Y axis at {y1}, {y2}#quot;)
|
||||
case _:
|
||||
print(#quot;Something else#quot;)\n"]
|
||||
|
||||
start --> block10
|
||||
block10 -- "case []" --> block9
|
||||
block10 -- "else" --> block8
|
||||
block9 --> block0
|
||||
block8 -- "case [Point(0, 0)]" --> block7
|
||||
block8 -- "else" --> block6
|
||||
block7 --> block0
|
||||
block6 -- "case [Point(x, y)]" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block0
|
||||
block4 -- "case [Point(0, y1), Point(0, y2)]" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block0
|
||||
block2 --> block1
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 12
|
||||
### Source
|
||||
```python
|
||||
def func(point):
|
||||
match point:
|
||||
case Point(x, y) if x == y:
|
||||
print(f"Y=X at {x}")
|
||||
case Point(x, y):
|
||||
print(f"Not on the diagonal")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(f#quot;Not on the diagonal#quot;)\n"]
|
||||
block2["match point:
|
||||
case Point(x, y) if x == y:
|
||||
print(f#quot;Y=X at {x}#quot;)
|
||||
case Point(x, y):
|
||||
print(f#quot;Not on the diagonal#quot;)\n"]
|
||||
block3["print(f#quot;Y=X at {x}#quot;)\n"]
|
||||
block4["match point:
|
||||
case Point(x, y) if x == y:
|
||||
print(f#quot;Y=X at {x}#quot;)
|
||||
case Point(x, y):
|
||||
print(f#quot;Not on the diagonal#quot;)\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "case Point(x, y) if x == y" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block0
|
||||
block2 -- "case Point(x, y)" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 13
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
from enum import Enum
|
||||
class Color(Enum):
|
||||
RED = 'red'
|
||||
GREEN = 'green'
|
||||
BLUE = 'blue'
|
||||
|
||||
color = Color(input("Enter your choice of 'red', 'blue' or 'green': "))
|
||||
|
||||
match color:
|
||||
case Color.RED:
|
||||
print("I see red!")
|
||||
case Color.GREEN:
|
||||
print("Grass is green")
|
||||
case Color.BLUE:
|
||||
print("I'm feeling the blues :(")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(#quot;I'm feeling the blues :(#quot;)\n"]
|
||||
block2["match color:
|
||||
case Color.RED:
|
||||
print(#quot;I see red!#quot;)
|
||||
case Color.GREEN:
|
||||
print(#quot;Grass is green#quot;)
|
||||
case Color.BLUE:
|
||||
print(#quot;I'm feeling the blues :(#quot;)\n"]
|
||||
block3["print(#quot;Grass is green#quot;)\n"]
|
||||
block4["match color:
|
||||
case Color.RED:
|
||||
print(#quot;I see red!#quot;)
|
||||
case Color.GREEN:
|
||||
print(#quot;Grass is green#quot;)
|
||||
case Color.BLUE:
|
||||
print(#quot;I'm feeling the blues :(#quot;)\n"]
|
||||
block5["print(#quot;I see red!#quot;)\n"]
|
||||
block6["match color:
|
||||
case Color.RED:
|
||||
print(#quot;I see red!#quot;)
|
||||
case Color.GREEN:
|
||||
print(#quot;Grass is green#quot;)
|
||||
case Color.BLUE:
|
||||
print(#quot;I'm feeling the blues :(#quot;)\n"]
|
||||
block7["from enum import Enum\nclass Color(Enum):
|
||||
RED = 'red'
|
||||
GREEN = 'green'
|
||||
BLUE = 'blue'\ncolor = Color(input(#quot;Enter your choice of 'red', 'blue' or 'green': #quot;))\n"]
|
||||
|
||||
start --> block7
|
||||
block7 --> block6
|
||||
block6 -- "case Color.RED" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block0
|
||||
block4 -- "case Color.GREEN" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block0
|
||||
block2 -- "case Color.BLUE" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 14
|
||||
### Source
|
||||
```python
|
||||
def func(point):
|
||||
match point:
|
||||
case (0, 0):
|
||||
print("Origin")
|
||||
case foo:
|
||||
raise ValueError("oops")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["raise ValueError(#quot;oops#quot;)\n"]
|
||||
block2["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case foo:
|
||||
raise ValueError(#quot;oops#quot;)\n"]
|
||||
block3["print(#quot;Origin#quot;)\n"]
|
||||
block4["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case foo:
|
||||
raise ValueError(#quot;oops#quot;)\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "case (0, 0)" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block0
|
||||
block2 --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/rules/unreachable.rs
|
||||
description: "This is a Mermaid graph. You can use https://mermaid.live to visualize it as a diagram."
|
||||
---
|
||||
## Function 0
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
raise Exception
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["raise Exception\n"]
|
||||
|
||||
start --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 1
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
raise "a glass!"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["raise #quot;a glass!#quot;\n"]
|
||||
|
||||
start --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/rules/unreachable.rs
|
||||
description: "This is a Mermaid graph. You can use https://mermaid.live to visualize it as a diagram."
|
||||
---
|
||||
## Function 0
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
pass
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["pass\n"]
|
||||
|
||||
start --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 1
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
pass
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["pass\n"]
|
||||
|
||||
start --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 2
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
return
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return\n"]
|
||||
|
||||
start --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 3
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
return 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 1\n"]
|
||||
|
||||
start --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 4
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
return 1
|
||||
return "unreachable"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return #quot;unreachable#quot;\n"]
|
||||
block1["return 1\n"]
|
||||
|
||||
start --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 5
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
i = 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["i = 0\n"]
|
||||
|
||||
start --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 6
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
i = 0
|
||||
i += 2
|
||||
return i
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["i = 0\ni += 2\nreturn i\n"]
|
||||
|
||||
start --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
|
||||
@@ -1,527 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/rules/unreachable.rs
|
||||
description: "This is a Mermaid graph. You can use https://mermaid.live to visualize it as a diagram."
|
||||
---
|
||||
## Function 0
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while False:
|
||||
return "unreachable"
|
||||
return 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 1\n"]
|
||||
block1["return #quot;unreachable#quot;\n"]
|
||||
block2["while False:
|
||||
return #quot;unreachable#quot;\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "False" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 1
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while False:
|
||||
return "unreachable"
|
||||
else:
|
||||
return 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return #quot;unreachable#quot;\n"]
|
||||
block1["return 1\n"]
|
||||
block2["while False:
|
||||
return #quot;unreachable#quot;
|
||||
else:
|
||||
return 1\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "False" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 2
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while False:
|
||||
return "unreachable"
|
||||
else:
|
||||
return 1
|
||||
return "also unreachable"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return #quot;also unreachable#quot;\n"]
|
||||
block1["return #quot;unreachable#quot;\n"]
|
||||
block2["return 1\n"]
|
||||
block3["while False:
|
||||
return #quot;unreachable#quot;
|
||||
else:
|
||||
return 1\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "False" --> block1
|
||||
block3 -- "else" --> block2
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 3
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
return 1
|
||||
return "unreachable"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return #quot;unreachable#quot;\n"]
|
||||
block1["return 1\n"]
|
||||
block2["while True:
|
||||
return 1\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 4
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
return 1
|
||||
else:
|
||||
return "unreachable"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 1\n"]
|
||||
block1["return #quot;unreachable#quot;\n"]
|
||||
block2["while True:
|
||||
return 1
|
||||
else:
|
||||
return #quot;unreachable#quot;\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "True" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 5
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
return 1
|
||||
else:
|
||||
return "unreachable"
|
||||
return "also unreachable"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return #quot;also unreachable#quot;\n"]
|
||||
block1["return 1\n"]
|
||||
block2["return #quot;unreachable#quot;\n"]
|
||||
block3["while True:
|
||||
return 1
|
||||
else:
|
||||
return #quot;unreachable#quot;\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "True" --> block1
|
||||
block3 -- "else" --> block2
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 6
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
i = 0
|
||||
while False:
|
||||
i += 1
|
||||
return i
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return i\n"]
|
||||
block1["i += 1\n"]
|
||||
block2["i = 0\nwhile False:
|
||||
i += 1\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "False" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block2
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 7
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
i = 0
|
||||
while True:
|
||||
i += 1
|
||||
return i
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return i\n"]
|
||||
block1["i += 1\n"]
|
||||
block2["i = 0\nwhile True:
|
||||
i += 1\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block2
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 8
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
pass
|
||||
return 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 1\n"]
|
||||
block1["pass\n"]
|
||||
block2["while True:
|
||||
pass\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block2
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 9
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
i = 0
|
||||
while True:
|
||||
if True:
|
||||
print("ok")
|
||||
i += 1
|
||||
return i
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return i\n"]
|
||||
block1["i += 1\n"]
|
||||
block2["print(#quot;ok#quot;)\n"]
|
||||
block3["if True:
|
||||
print(#quot;ok#quot;)\n"]
|
||||
block4["i = 0\nwhile True:
|
||||
if True:
|
||||
print(#quot;ok#quot;)
|
||||
i += 1\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> block1
|
||||
block1 --> block4
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 10
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
i = 0
|
||||
while True:
|
||||
if False:
|
||||
print("ok")
|
||||
i += 1
|
||||
return i
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return i\n"]
|
||||
block1["i += 1\n"]
|
||||
block2["print(#quot;ok#quot;)\n"]
|
||||
block3["if False:
|
||||
print(#quot;ok#quot;)\n"]
|
||||
block4["i = 0\nwhile True:
|
||||
if False:
|
||||
print(#quot;ok#quot;)
|
||||
i += 1\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "False" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> block1
|
||||
block1 --> block4
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 11
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
if True:
|
||||
return 1
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 0\n"]
|
||||
block1["return 1\n"]
|
||||
block2["if True:
|
||||
return 1\n"]
|
||||
block3["while True:
|
||||
if True:
|
||||
return 1\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block3
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 12
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
continue
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["continue\n"]
|
||||
block2["while True:
|
||||
continue\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block2
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 13
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while False:
|
||||
continue
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["continue\n"]
|
||||
block2["while False:
|
||||
continue\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "False" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block2
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 14
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
break
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["break\n"]
|
||||
block2["while True:
|
||||
break\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 15
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while False:
|
||||
break
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["break\n"]
|
||||
block2["while False:
|
||||
break\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "False" --> block1
|
||||
block2 -- "else" --> block0
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 16
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
if True:
|
||||
continue
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["continue\n"]
|
||||
block2["if True:
|
||||
continue\n"]
|
||||
block3["while True:
|
||||
if True:
|
||||
continue\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block3
|
||||
block1 --> block3
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 17
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
if True:
|
||||
break
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["break\n"]
|
||||
block2["if True:
|
||||
break\n"]
|
||||
block3["while True:
|
||||
if True:
|
||||
break\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 -- "True" --> block1
|
||||
block2 -- "else" --> block3
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,249 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
||||
---
|
||||
RUF014.py:3:5: RUF014 Unreachable code in after_return
|
||||
|
|
||||
1 | def after_return():
|
||||
2 | return "reachable"
|
||||
3 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
4 |
|
||||
5 | async def also_works_on_async_functions():
|
||||
|
|
||||
|
||||
RUF014.py:7:5: RUF014 Unreachable code in also_works_on_async_functions
|
||||
|
|
||||
5 | async def also_works_on_async_functions():
|
||||
6 | return "reachable"
|
||||
7 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
8 |
|
||||
9 | def if_always_true():
|
||||
|
|
||||
|
||||
RUF014.py:12:5: RUF014 Unreachable code in if_always_true
|
||||
|
|
||||
10 | if True:
|
||||
11 | return "reachable"
|
||||
12 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
13 |
|
||||
14 | def if_always_false():
|
||||
|
|
||||
|
||||
RUF014.py:16:9: RUF014 Unreachable code in if_always_false
|
||||
|
|
||||
14 | def if_always_false():
|
||||
15 | if False:
|
||||
16 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
17 | return "reachable"
|
||||
|
|
||||
|
||||
RUF014.py:21:9: RUF014 Unreachable code in if_elif_always_false
|
||||
|
|
||||
19 | def if_elif_always_false():
|
||||
20 | if False:
|
||||
21 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
22 | elif False:
|
||||
23 | return "also unreachable"
|
||||
|
|
||||
|
||||
RUF014.py:23:9: RUF014 Unreachable code in if_elif_always_false
|
||||
|
|
||||
21 | return "unreachable"
|
||||
22 | elif False:
|
||||
23 | return "also unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
24 | return "reachable"
|
||||
|
|
||||
|
||||
RUF014.py:28:9: RUF014 Unreachable code in if_elif_always_true
|
||||
|
|
||||
26 | def if_elif_always_true():
|
||||
27 | if False:
|
||||
28 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
29 | elif True:
|
||||
30 | return "reachable"
|
||||
|
|
||||
|
||||
RUF014.py:31:5: RUF014 Unreachable code in if_elif_always_true
|
||||
|
|
||||
29 | elif True:
|
||||
30 | return "reachable"
|
||||
31 | return "also unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
32 |
|
||||
33 | def ends_with_if():
|
||||
|
|
||||
|
||||
RUF014.py:35:9: RUF014 Unreachable code in ends_with_if
|
||||
|
|
||||
33 | def ends_with_if():
|
||||
34 | if False:
|
||||
35 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
36 | else:
|
||||
37 | return "reachable"
|
||||
|
|
||||
|
||||
RUF014.py:42:5: RUF014 Unreachable code in infinite_loop
|
||||
|
|
||||
40 | while True:
|
||||
41 | continue
|
||||
42 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
43 |
|
||||
44 | ''' TODO: we could determine these, but we don't yet.
|
||||
|
|
||||
|
||||
RUF014.py:75:5: RUF014 Unreachable code in match_wildcard
|
||||
|
|
||||
73 | case _:
|
||||
74 | return "reachable"
|
||||
75 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
76 |
|
||||
77 | def match_case_and_wildcard(status):
|
||||
|
|
||||
|
||||
RUF014.py:83:5: RUF014 Unreachable code in match_case_and_wildcard
|
||||
|
|
||||
81 | case _:
|
||||
82 | return "reachable"
|
||||
83 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
84 |
|
||||
85 | def raise_exception():
|
||||
|
|
||||
|
||||
RUF014.py:87:5: RUF014 Unreachable code in raise_exception
|
||||
|
|
||||
85 | def raise_exception():
|
||||
86 | raise Exception
|
||||
87 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
88 |
|
||||
89 | def while_false():
|
||||
|
|
||||
|
||||
RUF014.py:91:9: RUF014 Unreachable code in while_false
|
||||
|
|
||||
89 | def while_false():
|
||||
90 | while False:
|
||||
91 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
92 | return "reachable"
|
||||
|
|
||||
|
||||
RUF014.py:96:9: RUF014 Unreachable code in while_false_else
|
||||
|
|
||||
94 | def while_false_else():
|
||||
95 | while False:
|
||||
96 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
97 | else:
|
||||
98 | return "reachable"
|
||||
|
|
||||
|
||||
RUF014.py:102:9: RUF014 Unreachable code in while_false_else_return
|
||||
|
|
||||
100 | def while_false_else_return():
|
||||
101 | while False:
|
||||
102 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
103 | else:
|
||||
104 | return "reachable"
|
||||
|
|
||||
|
||||
RUF014.py:105:5: RUF014 Unreachable code in while_false_else_return
|
||||
|
|
||||
103 | else:
|
||||
104 | return "reachable"
|
||||
105 | return "also unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
106 |
|
||||
107 | def while_true():
|
||||
|
|
||||
|
||||
RUF014.py:110:5: RUF014 Unreachable code in while_true
|
||||
|
|
||||
108 | while True:
|
||||
109 | return "reachable"
|
||||
110 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
111 |
|
||||
112 | def while_true_else():
|
||||
|
|
||||
|
||||
RUF014.py:116:9: RUF014 Unreachable code in while_true_else
|
||||
|
|
||||
114 | return "reachable"
|
||||
115 | else:
|
||||
116 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
117 |
|
||||
118 | def while_true_else_return():
|
||||
|
|
||||
|
||||
RUF014.py:122:9: RUF014 Unreachable code in while_true_else_return
|
||||
|
|
||||
120 | return "reachable"
|
||||
121 | else:
|
||||
122 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
123 | return "also unreachable"
|
||||
|
|
||||
|
||||
RUF014.py:123:5: RUF014 Unreachable code in while_true_else_return
|
||||
|
|
||||
121 | else:
|
||||
122 | return "unreachable"
|
||||
123 | return "also unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
124 |
|
||||
125 | def while_false_var_i():
|
||||
|
|
||||
|
||||
RUF014.py:128:9: RUF014 Unreachable code in while_false_var_i
|
||||
|
|
||||
126 | i = 0
|
||||
127 | while False:
|
||||
128 | i += 1
|
||||
| ^^^^^^ RUF014
|
||||
129 | return i
|
||||
|
|
||||
|
||||
RUF014.py:135:5: RUF014 Unreachable code in while_true_var_i
|
||||
|
|
||||
133 | while True:
|
||||
134 | i += 1
|
||||
135 | return i
|
||||
| ^^^^^^^^ RUF014
|
||||
136 |
|
||||
137 | def while_infinite():
|
||||
|
|
||||
|
||||
RUF014.py:140:5: RUF014 Unreachable code in while_infinite
|
||||
|
|
||||
138 | while True:
|
||||
139 | pass
|
||||
140 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
141 |
|
||||
142 | def while_if_true():
|
||||
|
|
||||
|
||||
RUF014.py:146:5: RUF014 Unreachable code in while_if_true
|
||||
|
|
||||
144 | if True:
|
||||
145 | return "reachable"
|
||||
146 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ RUF014
|
||||
147 |
|
||||
148 | # Test case found in the Bokeh repository that trigger a false positive.
|
||||
|
|
||||
|
||||
|
||||
@@ -308,10 +308,13 @@ pub fn any_over_pattern(pattern: &Pattern, func: &dyn Fn(&Expr) -> bool) -> bool
|
||||
}
|
||||
}
|
||||
|
||||
pub fn any_over_f_string_element(element: &FStringElement, func: &dyn Fn(&Expr) -> bool) -> bool {
|
||||
pub fn any_over_f_string_element(
|
||||
element: &ast::FStringElement,
|
||||
func: &dyn Fn(&Expr) -> bool,
|
||||
) -> bool {
|
||||
match element {
|
||||
FStringElement::Literal(_) => false,
|
||||
FStringElement::Expression(ast::FStringExpressionElement {
|
||||
ast::FStringElement::Literal(_) => false,
|
||||
ast::FStringElement::Expression(ast::FStringExpressionElement {
|
||||
expression,
|
||||
format_spec,
|
||||
..
|
||||
@@ -1171,21 +1174,10 @@ impl Truthiness {
|
||||
}
|
||||
Expr::NoneLiteral(_) => Self::Falsey,
|
||||
Expr::EllipsisLiteral(_) => Self::Truthy,
|
||||
Expr::FString(ast::ExprFString { value, .. }) => {
|
||||
if value.iter().all(|part| match part {
|
||||
ast::FStringPart::Literal(string_literal) => string_literal.is_empty(),
|
||||
ast::FStringPart::FString(f_string) => f_string.elements.is_empty(),
|
||||
}) {
|
||||
Expr::FString(f_string) => {
|
||||
if is_empty_f_string(f_string) {
|
||||
Self::Falsey
|
||||
} else if value
|
||||
.elements()
|
||||
.any(|f_string_element| match f_string_element {
|
||||
ast::FStringElement::Literal(ast::FStringLiteralElement {
|
||||
value, ..
|
||||
}) => !value.is_empty(),
|
||||
ast::FStringElement::Expression(_) => true,
|
||||
})
|
||||
{
|
||||
} else if is_non_empty_f_string(f_string) {
|
||||
Self::Truthy
|
||||
} else {
|
||||
Self::Unknown
|
||||
@@ -1243,6 +1235,99 @@ impl Truthiness {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the expression definitely resolves to a non-empty string, when used as an
|
||||
/// f-string expression, or `false` if the expression may resolve to an empty string.
|
||||
fn is_non_empty_f_string(expr: &ast::ExprFString) -> bool {
|
||||
fn inner(expr: &Expr) -> bool {
|
||||
match expr {
|
||||
// When stringified, these expressions are always non-empty.
|
||||
Expr::Lambda(_) => true,
|
||||
Expr::Dict(_) => true,
|
||||
Expr::Set(_) => true,
|
||||
Expr::ListComp(_) => true,
|
||||
Expr::SetComp(_) => true,
|
||||
Expr::DictComp(_) => true,
|
||||
Expr::Compare(_) => true,
|
||||
Expr::NumberLiteral(_) => true,
|
||||
Expr::BooleanLiteral(_) => true,
|
||||
Expr::NoneLiteral(_) => true,
|
||||
Expr::EllipsisLiteral(_) => true,
|
||||
Expr::List(_) => true,
|
||||
Expr::Tuple(_) => true,
|
||||
|
||||
// These expressions must resolve to the inner expression.
|
||||
Expr::IfExp(ast::ExprIfExp { body, orelse, .. }) => inner(body) && inner(orelse),
|
||||
Expr::NamedExpr(ast::ExprNamedExpr { value, .. }) => inner(value),
|
||||
|
||||
// These expressions are complex. We can't determine whether they're empty or not.
|
||||
Expr::BoolOp(ast::ExprBoolOp { .. }) => false,
|
||||
Expr::BinOp(ast::ExprBinOp { .. }) => false,
|
||||
Expr::UnaryOp(ast::ExprUnaryOp { .. }) => false,
|
||||
Expr::GeneratorExp(_) => false,
|
||||
Expr::Await(_) => false,
|
||||
Expr::Yield(_) => false,
|
||||
Expr::YieldFrom(_) => false,
|
||||
Expr::Call(_) => false,
|
||||
Expr::Attribute(_) => false,
|
||||
Expr::Subscript(_) => false,
|
||||
Expr::Starred(_) => false,
|
||||
Expr::Name(_) => false,
|
||||
Expr::Slice(_) => false,
|
||||
Expr::IpyEscapeCommand(_) => false,
|
||||
|
||||
// These literals may or may not be empty.
|
||||
Expr::FString(f_string) => is_non_empty_f_string(f_string),
|
||||
Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => !value.is_empty(),
|
||||
Expr::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => !value.is_empty(),
|
||||
}
|
||||
}
|
||||
|
||||
expr.value.iter().any(|part| match part {
|
||||
ast::FStringPart::Literal(string_literal) => !string_literal.is_empty(),
|
||||
ast::FStringPart::FString(f_string) => {
|
||||
f_string.elements.iter().all(|element| match element {
|
||||
FStringElement::Literal(string_literal) => !string_literal.is_empty(),
|
||||
FStringElement::Expression(f_string) => inner(&f_string.expression),
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns `true` if the expression definitely resolves to the empty string, when used as an f-string
|
||||
/// expression.
|
||||
fn is_empty_f_string(expr: &ast::ExprFString) -> bool {
|
||||
fn inner(expr: &Expr) -> bool {
|
||||
match expr {
|
||||
Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => value.is_empty(),
|
||||
Expr::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => value.is_empty(),
|
||||
Expr::FString(ast::ExprFString { value, .. }) => {
|
||||
value
|
||||
.elements()
|
||||
.all(|f_string_element| match f_string_element {
|
||||
FStringElement::Literal(ast::FStringLiteralElement { value, .. }) => {
|
||||
value.is_empty()
|
||||
}
|
||||
FStringElement::Expression(ast::FStringExpressionElement {
|
||||
expression,
|
||||
..
|
||||
}) => inner(expression),
|
||||
})
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
expr.value.iter().all(|part| match part {
|
||||
ast::FStringPart::Literal(string_literal) => string_literal.is_empty(),
|
||||
ast::FStringPart::FString(f_string) => {
|
||||
f_string.elements.iter().all(|element| match element {
|
||||
FStringElement::Literal(string_literal) => string_literal.is_empty(),
|
||||
FStringElement::Expression(f_string) => inner(&f_string.expression),
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn generate_comparison(
|
||||
left: &Expr,
|
||||
ops: &[CmpOp],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_shrinking"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -1213,8 +1213,6 @@ mod tests {
|
||||
}
|
||||
.as_rule_table(preview.map(|preview| preview.mode).unwrap_or_default())
|
||||
.iter_enabled()
|
||||
// Filter out rule gated behind `#[cfg(feature = "unreachable-code")]`, which is off-by-default
|
||||
.filter(|rule| rule.noqa_code() != "RUF014")
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use anyhow::Result;
|
||||
use anyhow::{anyhow, bail};
|
||||
use globset::{Candidate, GlobSet};
|
||||
use ignore::{WalkBuilder, WalkState};
|
||||
use itertools::{Either, Itertools};
|
||||
use itertools::Itertools;
|
||||
use log::debug;
|
||||
use path_absolutize::path_dedot;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
@@ -204,12 +204,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
/// Return an iterator over the resolved [`Settings`] in this [`Resolver`].
|
||||
pub fn settings(&self) -> impl Iterator<Item = &Settings> {
|
||||
match self.pyproject_config.strategy {
|
||||
PyprojectDiscoveryStrategy::Fixed => {
|
||||
Either::Left(std::iter::once(&self.pyproject_config.settings))
|
||||
}
|
||||
PyprojectDiscoveryStrategy::Hierarchical => Either::Right(self.settings.values()),
|
||||
}
|
||||
std::iter::once(&self.pyproject_config.settings).chain(self.settings.values())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Ruff can be used as a [pre-commit](https://pre-commit.com) hook via [`ruff-pre-c
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.1.11
|
||||
rev: v0.1.13
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
@@ -27,7 +27,7 @@ To enable lint fixes, add the `--fix` argument to the lint hook:
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.1.11
|
||||
rev: v0.1.13
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
@@ -41,7 +41,7 @@ To run the hooks over Jupyter Notebooks too, add `jupyter` to the list of allowe
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.1.11
|
||||
rev: v0.1.13
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
||||
|
||||
[project]
|
||||
name = "ruff"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
authors = [{ name = "Astral Software Inc.", email = "hey@astral.sh" }]
|
||||
readme = "README.md"
|
||||
|
||||
1
ruff.schema.json
generated
1
ruff.schema.json
generated
@@ -3580,6 +3580,7 @@
|
||||
"SIM9",
|
||||
"SIM91",
|
||||
"SIM910",
|
||||
"SIM911",
|
||||
"SLF",
|
||||
"SLF0",
|
||||
"SLF00",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "scripts"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
description = ""
|
||||
authors = ["Charles Marsh <charlie.r.marsh@gmail.com>"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user