mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 18:28:56 +00:00
Control flow graph: setup (#17064)
This PR contains the scaffolding for a new control flow graph implementation, along with its application to the `unreachable` rule. At the moment, the implementation is a maximal over-approximation: no control flow is modeled and all statements are counted as reachable. With each additional statement type we support, this approximation will improve. So this PR just contains: - A `ControlFlowGraph` struct and builder - Support for printing the flow graph as a Mermaid graph - Snapshot tests for the actual graphs - (a very bad!) reimplementation of `unreachable` using the new structs - Snapshot tests for `unreachable` # Instructions for Viewing Mermaid snapshots Unfortunately I don't know how to convince GitHub to render the Mermaid graphs in the snapshots. However, you can view these locally in VSCode if you install an extension that supports Mermaid graphs in Markdown, and then add this to your `settings.json`: ```json "files.associations": { "*.md.snap": "markdown", } ```
This commit is contained in:
parent
0073fd4945
commit
aa93005d8d
24 changed files with 775 additions and 6244 deletions
|
@ -16,7 +16,6 @@ license = { workspace = true }
|
|||
ruff_annotate_snippets = { workspace = true }
|
||||
ruff_cache = { workspace = true }
|
||||
ruff_diagnostics = { workspace = true, features = ["serde"] }
|
||||
ruff_index = { workspace = true }
|
||||
ruff_notebook = { workspace = true }
|
||||
ruff_macros = { workspace = true }
|
||||
ruff_python_ast = { workspace = true, features = ["serde", "cache"] }
|
||||
|
|
|
@ -1,263 +1,14 @@
|
|||
def after_return():
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
def empty_statement_reachable(): ...
|
||||
|
||||
async def also_works_on_async_functions():
|
||||
return "reachable"
|
||||
return "unreachable"
|
||||
def pass_statement_reachable():
|
||||
pass
|
||||
|
||||
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"
|
||||
|
||||
def while_break():
|
||||
while True:
|
||||
print("reachable")
|
||||
break
|
||||
print("unreachable")
|
||||
return "reachable"
|
||||
|
||||
# Test case found in the Bokeh repository that triggered 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
|
||||
|
||||
# Test case found in the Bokeh repository that triggered 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)
|
||||
|
||||
# Test case found in the pandas repository that triggered a false positive.
|
||||
def _check_basic_constructor(self, empty):
|
||||
# mat: 2d matrix with shape (3, 2) to input. empty - makes sized
|
||||
# objects
|
||||
mat = empty((2, 3), dtype=float)
|
||||
# 2-D input
|
||||
frame = DataFrame(mat, columns=["A", "B", "C"], index=[1, 2])
|
||||
|
||||
assert len(frame.index) == 2
|
||||
assert len(frame.columns) == 3
|
||||
|
||||
# 1-D input
|
||||
frame = DataFrame(empty((3,)), columns=["A"], index=[1, 2, 3])
|
||||
assert len(frame.index) == 3
|
||||
assert len(frame.columns) == 1
|
||||
|
||||
if empty is not np.ones:
|
||||
msg = r"Cannot convert non-finite values \(NA or inf\) to integer"
|
||||
with pytest.raises(IntCastingNaNError, match=msg):
|
||||
DataFrame(mat, columns=["A", "B", "C"], index=[1, 2], dtype=np.int64)
|
||||
def no_control_flow_reachable():
|
||||
x = 1
|
||||
x = 2
|
||||
class C:
|
||||
a = 2
|
||||
c = C()
|
||||
del c
|
||||
def foo():
|
||||
return
|
||||
else:
|
||||
frame = DataFrame(
|
||||
mat, columns=["A", "B", "C"], index=[1, 2], dtype=np.int64
|
||||
)
|
||||
assert frame.values.dtype == np.int64
|
||||
|
||||
# wrong size axis labels
|
||||
msg = r"Shape of passed values is \(2, 3\), indices imply \(1, 3\)"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
DataFrame(mat, columns=["A", "B", "C"], index=[1])
|
||||
msg = r"Shape of passed values is \(2, 3\), indices imply \(2, 2\)"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
DataFrame(mat, columns=["A", "B"], index=[1, 2])
|
||||
|
||||
# higher dim raise exception
|
||||
with pytest.raises(ValueError, match="Must pass 2-d input"):
|
||||
DataFrame(empty((3, 3, 3)), columns=["A", "B", "C"], index=[1])
|
||||
|
||||
# automatic labeling
|
||||
frame = DataFrame(mat)
|
||||
tm.assert_index_equal(frame.index, Index(range(2)), exact=True)
|
||||
tm.assert_index_equal(frame.columns, Index(range(3)), exact=True)
|
||||
|
||||
frame = DataFrame(mat, index=[1, 2])
|
||||
tm.assert_index_equal(frame.columns, Index(range(3)), exact=True)
|
||||
|
||||
frame = DataFrame(mat, columns=["A", "B", "C"])
|
||||
tm.assert_index_equal(frame.index, Index(range(2)), exact=True)
|
||||
|
||||
# 0-length axis
|
||||
frame = DataFrame(empty((0, 3)))
|
||||
assert len(frame.index) == 0
|
||||
|
||||
frame = DataFrame(empty((3, 0)))
|
||||
assert len(frame.columns) == 0
|
||||
|
||||
|
||||
def after_return():
|
||||
return "reachable"
|
||||
print("unreachable")
|
||||
print("unreachable")
|
||||
print("unreachable")
|
||||
print("unreachable")
|
||||
print("unreachable")
|
||||
|
||||
|
||||
def check_if_url_exists(url: str) -> bool: # type: ignore[return]
|
||||
return True # uncomment to check URLs
|
||||
response = requests.head(url, allow_redirects=True)
|
||||
if response.status_code == 200:
|
||||
return True
|
||||
if response.status_code == 404:
|
||||
return False
|
||||
console.print(f"[red]Unexpected error received: {response.status_code}[/]")
|
||||
response.raise_for_status()
|
||||
|
|
|
@ -349,7 +349,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
}
|
||||
#[cfg(any(feature = "test-rules", test))]
|
||||
if checker.enabled(Rule::UnreachableCode) {
|
||||
checker.report_diagnostics(pylint::rules::in_function(name, body));
|
||||
pylint::rules::in_function(checker, name, body);
|
||||
}
|
||||
if checker.enabled(Rule::ReimplementedOperator) {
|
||||
refurb::rules::reimplemented_operator(checker, &function_def.into());
|
||||
|
|
|
@ -1,244 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/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
|
||||
```
|
||||
|
||||
## Function 4
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
y = 2
|
||||
assert y == 2
|
||||
assert y > 1
|
||||
assert y < 3
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Exception raised"]]
|
||||
block2["assert y < 3\n"]
|
||||
block3[["Exception raised"]]
|
||||
block4["assert y > 1\n"]
|
||||
block5[["Exception raised"]]
|
||||
block6["y = 2\nassert y == 2\n"]
|
||||
|
||||
start --> block6
|
||||
block6 -- "y == 2" --> block4
|
||||
block6 -- "else" --> block5
|
||||
block5 --> return
|
||||
block4 -- "y > 1" --> block2
|
||||
block4 -- "else" --> block3
|
||||
block3 --> return
|
||||
block2 -- "y < 3" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 5
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(3):
|
||||
assert i < x
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Loop continue"]]
|
||||
block2[["Exception raised"]]
|
||||
block3["assert i < x\n"]
|
||||
block4["for i in range(3):
|
||||
assert i < x\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(3)" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "i < x" --> block1
|
||||
block3 -- "else" --> block2
|
||||
block2 --> return
|
||||
block1 --> block4
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 6
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for j in range(3):
|
||||
x = 2
|
||||
else:
|
||||
assert False
|
||||
return 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 1\n"]
|
||||
block1[["Exception raised"]]
|
||||
block2["assert False\n"]
|
||||
block3[["Loop continue"]]
|
||||
block4["x = 2\n"]
|
||||
block5["for j in range(3):
|
||||
x = 2
|
||||
else:
|
||||
assert False\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "range(3)" --> block4
|
||||
block5 -- "else" --> block2
|
||||
block4 --> block3
|
||||
block3 --> block5
|
||||
block2 -- "False" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 7
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for j in range(3):
|
||||
if j == 2:
|
||||
print('yay')
|
||||
break
|
||||
else:
|
||||
assert False
|
||||
return 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["return 1\n"]
|
||||
block1[["Exception raised"]]
|
||||
block2["assert False\n"]
|
||||
block3[["Loop continue"]]
|
||||
block4["print('yay')\nbreak\n"]
|
||||
block5["if j == 2:
|
||||
print('yay')
|
||||
break\n"]
|
||||
block6["for j in range(3):
|
||||
if j == 2:
|
||||
print('yay')
|
||||
break
|
||||
else:
|
||||
assert False\n"]
|
||||
|
||||
start --> block6
|
||||
block6 -- "range(3)" --> block5
|
||||
block6 -- "else" --> block2
|
||||
block5 -- "j == 2" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> block0
|
||||
block3 --> block6
|
||||
block2 -- "False" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
|
@ -1,257 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/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[["Loop continue"]]
|
||||
block2["print(i)\n"]
|
||||
block3["async for i in range(5):
|
||||
print(i)\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(5)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> block1
|
||||
block1 --> block3
|
||||
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[["`*(empty)*`"]]
|
||||
block1["return 0\n"]
|
||||
block2[["Loop continue"]]
|
||||
block3["print(i)\n"]
|
||||
block4["async for i in range(20):
|
||||
print(i)
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(20)" --> block3
|
||||
block4 -- "else" --> block1
|
||||
block3 --> block2
|
||||
block2 --> block4
|
||||
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[["Loop continue"]]
|
||||
block2["return 1\n"]
|
||||
block3["if i == 5:
|
||||
return 1\n"]
|
||||
block4["async for i in range(10):
|
||||
if i == 5:
|
||||
return 1\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(10)" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "i == 5" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> return
|
||||
block1 --> block4
|
||||
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 0\n"]
|
||||
block2[["Loop continue"]]
|
||||
block3["return 1\n"]
|
||||
block4["if i == 5:
|
||||
return 1\n"]
|
||||
block5["async for i in range(111):
|
||||
if i == 5:
|
||||
return 1
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "range(111)" --> block4
|
||||
block5 -- "else" --> block1
|
||||
block4 -- "i == 5" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> return
|
||||
block2 --> block5
|
||||
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[["Loop continue"]]
|
||||
block2["continue\n"]
|
||||
block3["async for i in range(12):
|
||||
continue\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(12)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> block3
|
||||
block1 --> block3
|
||||
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[["Loop continue"]]
|
||||
block2["continue\n"]
|
||||
block3["if True:
|
||||
continue\n"]
|
||||
block4["async for i in range(1110):
|
||||
if True:
|
||||
continue\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(1110)" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> block4
|
||||
block1 --> block4
|
||||
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[["Loop continue"]]
|
||||
block2["break\n"]
|
||||
block3["async for i in range(13):
|
||||
break\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(13)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> return
|
||||
block1 --> block3
|
||||
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[["Loop continue"]]
|
||||
block2["break\n"]
|
||||
block3["if True:
|
||||
break\n"]
|
||||
block4["async for i in range(1110):
|
||||
if True:
|
||||
break\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(1110)" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> return
|
||||
block1 --> block4
|
||||
block0 --> return
|
||||
```
|
|
@ -1,590 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/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[["Loop continue"]]
|
||||
block2["print(i)\n"]
|
||||
block3["for i in range(5):
|
||||
print(i)\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(5)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> block1
|
||||
block1 --> block3
|
||||
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[["`*(empty)*`"]]
|
||||
block1["return 0\n"]
|
||||
block2[["Loop continue"]]
|
||||
block3["print(i)\n"]
|
||||
block4["for i in range(20):
|
||||
print(i)
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(20)" --> block3
|
||||
block4 -- "else" --> block1
|
||||
block3 --> block2
|
||||
block2 --> block4
|
||||
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[["Loop continue"]]
|
||||
block2["return 1\n"]
|
||||
block3["if i == 5:
|
||||
return 1\n"]
|
||||
block4["for i in range(10):
|
||||
if i == 5:
|
||||
return 1\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(10)" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "i == 5" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> return
|
||||
block1 --> block4
|
||||
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 0\n"]
|
||||
block2[["Loop continue"]]
|
||||
block3["return 1\n"]
|
||||
block4["if i == 5:
|
||||
return 1\n"]
|
||||
block5["for i in range(111):
|
||||
if i == 5:
|
||||
return 1
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "range(111)" --> block4
|
||||
block5 -- "else" --> block1
|
||||
block4 -- "i == 5" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> return
|
||||
block2 --> block5
|
||||
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[["Loop continue"]]
|
||||
block2["continue\n"]
|
||||
block3["for i in range(12):
|
||||
continue\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(12)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> block3
|
||||
block1 --> block3
|
||||
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[["Loop continue"]]
|
||||
block2["continue\n"]
|
||||
block3["if True:
|
||||
continue\n"]
|
||||
block4["for i in range(1110):
|
||||
if True:
|
||||
continue\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(1110)" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> block4
|
||||
block1 --> block4
|
||||
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[["Loop continue"]]
|
||||
block2["break\n"]
|
||||
block3["for i in range(13):
|
||||
break\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "range(13)" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> return
|
||||
block1 --> block3
|
||||
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[["Loop continue"]]
|
||||
block2["break\n"]
|
||||
block3["if True:
|
||||
break\n"]
|
||||
block4["for i in range(1110):
|
||||
if True:
|
||||
break\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(1110)" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> return
|
||||
block1 --> block4
|
||||
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[["`*(empty)*`"]]
|
||||
block1["return 1\n"]
|
||||
block2[["Loop continue"]]
|
||||
block3["pass\n"]
|
||||
block4["for i in range(5):
|
||||
pass
|
||||
else:
|
||||
return 1\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(5)" --> block3
|
||||
block4 -- "else" --> block1
|
||||
block3 --> block2
|
||||
block2 --> block4
|
||||
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["return 1\n"]
|
||||
block2[["Loop continue"]]
|
||||
block3["pass\n"]
|
||||
block4["for i in range(5):
|
||||
pass
|
||||
else:
|
||||
return 1\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(5)" --> block3
|
||||
block4 -- "else" --> block1
|
||||
block3 --> block2
|
||||
block2 --> block4
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 10
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(5):
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["pass\n"]
|
||||
block2[["Loop continue"]]
|
||||
block3["pass\n"]
|
||||
block4["for i in range(5):
|
||||
pass
|
||||
else:
|
||||
pass\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "range(5)" --> block3
|
||||
block4 -- "else" --> block1
|
||||
block3 --> block2
|
||||
block2 --> block4
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 11
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(3):
|
||||
if i == 2:
|
||||
assert i is not None
|
||||
break
|
||||
else:
|
||||
raise Exception()
|
||||
x = 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["x = 0\n"]
|
||||
block1[["Exception raised"]]
|
||||
block2["raise Exception()\n"]
|
||||
block3[["Loop continue"]]
|
||||
block4["break\n"]
|
||||
block5[["Exception raised"]]
|
||||
block6["assert i is not None\n"]
|
||||
block7["if i == 2:
|
||||
assert i is not None
|
||||
break\n"]
|
||||
block8["for i in range(3):
|
||||
if i == 2:
|
||||
assert i is not None
|
||||
break
|
||||
else:
|
||||
raise Exception()\n"]
|
||||
|
||||
start --> block8
|
||||
block8 -- "range(3)" --> block7
|
||||
block8 -- "else" --> block2
|
||||
block7 -- "i == 2" --> block6
|
||||
block7 -- "else" --> block3
|
||||
block6 -- "i is not None" --> block4
|
||||
block6 -- "else" --> block5
|
||||
block5 --> return
|
||||
block4 --> block0
|
||||
block3 --> block8
|
||||
block2 --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 12
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(13):
|
||||
for i in range(12):
|
||||
x = 2
|
||||
if True:
|
||||
break
|
||||
|
||||
x = 3
|
||||
if True:
|
||||
break
|
||||
|
||||
print('hello')
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["print('hello')\n"]
|
||||
block1[["Loop continue"]]
|
||||
block2["break\n"]
|
||||
block3["x = 3\nif True:
|
||||
break\n"]
|
||||
block4[["Loop continue"]]
|
||||
block5["break\n"]
|
||||
block6["x = 2\nif True:
|
||||
break\n"]
|
||||
block7["for i in range(12):
|
||||
x = 2
|
||||
if True:
|
||||
break\n"]
|
||||
block8["for i in range(13):
|
||||
for i in range(12):
|
||||
x = 2
|
||||
if True:
|
||||
break
|
||||
|
||||
x = 3
|
||||
if True:
|
||||
break\n"]
|
||||
|
||||
start --> block8
|
||||
block8 -- "range(13)" --> block7
|
||||
block8 -- "else" --> block0
|
||||
block7 -- "range(12)" --> block6
|
||||
block7 -- "else" --> block3
|
||||
block6 -- "True" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block3
|
||||
block4 --> block7
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> block0
|
||||
block1 --> block8
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 13
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(13):
|
||||
for i in range(12):
|
||||
x = 2
|
||||
if True:
|
||||
continue
|
||||
|
||||
x = 3
|
||||
if True:
|
||||
break
|
||||
|
||||
print('hello')
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["print('hello')\n"]
|
||||
block1[["Loop continue"]]
|
||||
block2["break\n"]
|
||||
block3["x = 3\nif True:
|
||||
break\n"]
|
||||
block4[["Loop continue"]]
|
||||
block5["continue\n"]
|
||||
block6["x = 2\nif True:
|
||||
continue\n"]
|
||||
block7["for i in range(12):
|
||||
x = 2
|
||||
if True:
|
||||
continue\n"]
|
||||
block8["for i in range(13):
|
||||
for i in range(12):
|
||||
x = 2
|
||||
if True:
|
||||
continue
|
||||
|
||||
x = 3
|
||||
if True:
|
||||
break\n"]
|
||||
|
||||
start --> block8
|
||||
block8 -- "range(13)" --> block7
|
||||
block8 -- "else" --> block0
|
||||
block7 -- "range(12)" --> block6
|
||||
block7 -- "else" --> block3
|
||||
block6 -- "True" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block7
|
||||
block4 --> block7
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> block0
|
||||
block1 --> block8
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 14
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in range(13):
|
||||
for i in range(12):
|
||||
x = 2
|
||||
if True:
|
||||
break
|
||||
|
||||
x = 3
|
||||
if True:
|
||||
continue
|
||||
|
||||
print('hello')
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["print('hello')\n"]
|
||||
block1[["Loop continue"]]
|
||||
block2["continue\n"]
|
||||
block3["x = 3\nif True:
|
||||
continue\n"]
|
||||
block4[["Loop continue"]]
|
||||
block5["break\n"]
|
||||
block6["x = 2\nif True:
|
||||
break\n"]
|
||||
block7["for i in range(12):
|
||||
x = 2
|
||||
if True:
|
||||
break\n"]
|
||||
block8["for i in range(13):
|
||||
for i in range(12):
|
||||
x = 2
|
||||
if True:
|
||||
break
|
||||
|
||||
x = 3
|
||||
if True:
|
||||
continue\n"]
|
||||
|
||||
start --> block8
|
||||
block8 -- "range(13)" --> block7
|
||||
block8 -- "else" --> block0
|
||||
block7 -- "range(12)" --> block6
|
||||
block7 -- "else" --> block3
|
||||
block6 -- "True" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block3
|
||||
block4 --> block7
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> block8
|
||||
block1 --> block8
|
||||
block0 --> return
|
||||
```
|
|
@ -1,720 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/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[["`*(empty)*`"]]
|
||||
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 3
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if True:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
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 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[["`*(empty)*`"]]
|
||||
block1["return 1\n"]
|
||||
block2["return 0\n"]
|
||||
block3["return 2\n"]
|
||||
block4["if True:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
else:
|
||||
return 0\n"]
|
||||
block5["if True:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "True" --> block1
|
||||
block5 -- "else" --> block4
|
||||
block4 -- "False" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> return
|
||||
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[["`*(empty)*`"]]
|
||||
block1["return 1\n"]
|
||||
block2["return 0\n"]
|
||||
block3["return 2\n"]
|
||||
block4["if False:
|
||||
return 1
|
||||
elif True:
|
||||
return 2
|
||||
else:
|
||||
return 0\n"]
|
||||
block5["if False:
|
||||
return 1
|
||||
elif True:
|
||||
return 2
|
||||
else:
|
||||
return 0\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "False" --> block1
|
||||
block5 -- "else" --> block4
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> return
|
||||
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
|
||||
```
|
||||
|
||||
## Function 14
|
||||
### Source
|
||||
```python
|
||||
def func(x):
|
||||
if x == 1:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
elif x == 3:
|
||||
return 3
|
||||
elif True:
|
||||
return 4
|
||||
elif x == 5:
|
||||
return 5
|
||||
elif x == 6:
|
||||
return 6
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["return 1\n"]
|
||||
block2["return 6\n"]
|
||||
block3["if x == 1:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
elif x == 3:
|
||||
return 3
|
||||
elif True:
|
||||
return 4
|
||||
elif x == 5:
|
||||
return 5
|
||||
elif x == 6:
|
||||
return 6\n"]
|
||||
block4["return 5\n"]
|
||||
block5["if x == 1:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
elif x == 3:
|
||||
return 3
|
||||
elif True:
|
||||
return 4
|
||||
elif x == 5:
|
||||
return 5
|
||||
elif x == 6:
|
||||
return 6\n"]
|
||||
block6["return 4\n"]
|
||||
block7["if x == 1:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
elif x == 3:
|
||||
return 3
|
||||
elif True:
|
||||
return 4
|
||||
elif x == 5:
|
||||
return 5
|
||||
elif x == 6:
|
||||
return 6\n"]
|
||||
block8["return 3\n"]
|
||||
block9["if x == 1:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
elif x == 3:
|
||||
return 3
|
||||
elif True:
|
||||
return 4
|
||||
elif x == 5:
|
||||
return 5
|
||||
elif x == 6:
|
||||
return 6\n"]
|
||||
block10["return 2\n"]
|
||||
block11["if x == 1:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
elif x == 3:
|
||||
return 3
|
||||
elif True:
|
||||
return 4
|
||||
elif x == 5:
|
||||
return 5
|
||||
elif x == 6:
|
||||
return 6\n"]
|
||||
block12["if x == 1:
|
||||
return 1
|
||||
elif False:
|
||||
return 2
|
||||
elif x == 3:
|
||||
return 3
|
||||
elif True:
|
||||
return 4
|
||||
elif x == 5:
|
||||
return 5
|
||||
elif x == 6:
|
||||
return 6\n"]
|
||||
|
||||
start --> block12
|
||||
block12 -- "x == 1" --> block1
|
||||
block12 -- "else" --> block11
|
||||
block11 -- "False" --> block10
|
||||
block11 -- "else" --> block9
|
||||
block10 --> return
|
||||
block9 -- "x == 3" --> block8
|
||||
block9 -- "else" --> block7
|
||||
block8 --> return
|
||||
block7 -- "True" --> block6
|
||||
block7 -- "else" --> block5
|
||||
block6 --> return
|
||||
block5 -- "x == 5" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> return
|
||||
block3 -- "x == 6" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 15
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
if x:
|
||||
return
|
||||
else:
|
||||
assert x
|
||||
|
||||
print('pop')
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["print('pop')\n"]
|
||||
block1["return\n"]
|
||||
block2[["Exception raised"]]
|
||||
block3["assert x\n"]
|
||||
block4["if x:
|
||||
return
|
||||
else:
|
||||
assert x\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "x" --> block1
|
||||
block4 -- "else" --> block3
|
||||
block3 -- "x" --> block0
|
||||
block3 -- "else" --> block2
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
|
@ -1,823 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/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[["`*(empty)*`"]]
|
||||
block1["return 0\n"]
|
||||
block2["match status:
|
||||
case 1:
|
||||
return 1
|
||||
case _:
|
||||
return 0\n"]
|
||||
block3["return 1\n"]
|
||||
block4["match status:
|
||||
case 1:
|
||||
return 1
|
||||
case _:
|
||||
return 0\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "case 1" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> return
|
||||
block2 --> block1
|
||||
block1 --> return
|
||||
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[["`*(empty)*`"]]
|
||||
block1["return 3\n"]
|
||||
block2["match status:
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return 1
|
||||
case 1:
|
||||
return #quot;1 again#quot;
|
||||
case _:
|
||||
return 3\n"]
|
||||
block3["return #quot;1 again#quot;\n"]
|
||||
block4["match status:
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return 1
|
||||
case 1:
|
||||
return #quot;1 again#quot;
|
||||
case _:
|
||||
return 3\n"]
|
||||
block5["return 1\n"]
|
||||
block6["match status:
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return 1
|
||||
case 1:
|
||||
return #quot;1 again#quot;
|
||||
case _:
|
||||
return 3\n"]
|
||||
block7["return 0\n"]
|
||||
block8["match status:
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return 1
|
||||
case 1:
|
||||
return #quot;1 again#quot;
|
||||
case _:
|
||||
return 3\n"]
|
||||
|
||||
start --> block8
|
||||
block8 -- "case 0" --> block7
|
||||
block8 -- "else" --> block6
|
||||
block7 --> return
|
||||
block6 -- "case 1" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> return
|
||||
block4 -- "case 1" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> return
|
||||
block2 --> block1
|
||||
block1 --> return
|
||||
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[["Exception raised"]]
|
||||
block2["raise ValueError(#quot;oops#quot;)\n"]
|
||||
block3["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case _:
|
||||
raise ValueError(#quot;oops#quot;)\n"]
|
||||
block4["print(#quot;Origin#quot;)\n"]
|
||||
block5["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case _:
|
||||
raise ValueError(#quot;oops#quot;)\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "case (0, 0)" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> block0
|
||||
block3 --> block2
|
||||
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[["Exception raised"]]
|
||||
block2["raise ValueError(#quot;Not a point#quot;)\n"]
|
||||
block3["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"]
|
||||
block4["print(f#quot;X={x}, Y={y}#quot;)\n"]
|
||||
block5["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"]
|
||||
block6["print(f#quot;X={x}#quot;)\n"]
|
||||
block7["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"]
|
||||
block8["print(f#quot;Y={y}#quot;)\n"]
|
||||
block9["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"]
|
||||
block10["print(#quot;Origin#quot;)\n"]
|
||||
block11["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 --> block11
|
||||
block11 -- "case (0, 0)" --> block10
|
||||
block11 -- "else" --> block9
|
||||
block10 --> block0
|
||||
block9 -- "case (0, y)" --> block8
|
||||
block9 -- "else" --> block7
|
||||
block8 --> block0
|
||||
block7 -- "case (x, 0)" --> block6
|
||||
block7 -- "else" --> block5
|
||||
block6 --> block0
|
||||
block5 -- "case (x, y)" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> block0
|
||||
block3 --> block2
|
||||
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[["Exception raised"]]
|
||||
block2["raise ValueError(#quot;oops#quot;)\n"]
|
||||
block3["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case foo:
|
||||
raise ValueError(#quot;oops#quot;)\n"]
|
||||
block4["print(#quot;Origin#quot;)\n"]
|
||||
block5["match point:
|
||||
case (0, 0):
|
||||
print(#quot;Origin#quot;)
|
||||
case foo:
|
||||
raise ValueError(#quot;oops#quot;)\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "case (0, 0)" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> block0
|
||||
block3 --> block2
|
||||
block2 --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
|
@ -1,43 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/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[["Exception raised"]]
|
||||
block1["raise Exception\n"]
|
||||
|
||||
start --> block1
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 1
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
raise "a glass!"
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["Exception raised"]]
|
||||
block1["raise #quot;a glass!#quot;\n"]
|
||||
|
||||
start --> block1
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
|
@ -1,188 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/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
|
||||
```
|
||||
|
||||
## Function 7
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
with x:
|
||||
i = 0
|
||||
i = 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["i = 1\n"]
|
||||
block1["i = 0\n"]
|
||||
block2["with x:
|
||||
i = 0\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "Exception raised" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 8
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
with x:
|
||||
i = 0
|
||||
return 1
|
||||
i = 1
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["i = 1\n"]
|
||||
block1["i = 0\nreturn 1\n"]
|
||||
block2["with x:
|
||||
i = 0
|
||||
return 1\n"]
|
||||
|
||||
start --> block2
|
||||
block2 -- "Exception raised" --> block0
|
||||
block2 -- "else" --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
|
@ -1,63 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/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 l():
|
||||
while T:
|
||||
try:
|
||||
while ():
|
||||
if 3:
|
||||
break
|
||||
finally:
|
||||
return
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Loop continue"]]
|
||||
block2["return\n"]
|
||||
block3[["Loop continue"]]
|
||||
block4["break\n"]
|
||||
block5["if 3:
|
||||
break\n"]
|
||||
block6["while ():
|
||||
if 3:
|
||||
break\n"]
|
||||
block7[["Exception raised"]]
|
||||
block8["try:
|
||||
while ():
|
||||
if 3:
|
||||
break
|
||||
finally:
|
||||
return\n"]
|
||||
block9["while T:
|
||||
try:
|
||||
while ():
|
||||
if 3:
|
||||
break
|
||||
finally:
|
||||
return\n"]
|
||||
|
||||
start --> block9
|
||||
block9 -- "T" --> block8
|
||||
block9 -- "else" --> block0
|
||||
block8 -- "Exception raised" --> block7
|
||||
block8 -- "else" --> block6
|
||||
block7 --> block2
|
||||
block6 -- "()" --> block5
|
||||
block6 -- "else" --> block2
|
||||
block5 -- "3" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> block2
|
||||
block3 --> block6
|
||||
block2 --> return
|
||||
block1 --> block9
|
||||
block0 --> return
|
||||
```
|
|
@ -1,783 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/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():
|
||||
try:
|
||||
print("try")
|
||||
except Exception:
|
||||
print("Exception")
|
||||
except OtherException as e:
|
||||
print("OtherException")
|
||||
else:
|
||||
print("else")
|
||||
finally:
|
||||
print("finally")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(#quot;finally#quot;)\n"]
|
||||
block2["print(#quot;else#quot;)\n"]
|
||||
block3["print(#quot;try#quot;)\n"]
|
||||
block4[["Exception raised"]]
|
||||
block5["print(#quot;OtherException#quot;)\n"]
|
||||
block6["try:
|
||||
print(#quot;try#quot;)
|
||||
except Exception:
|
||||
print(#quot;Exception#quot;)
|
||||
except OtherException as e:
|
||||
print(#quot;OtherException#quot;)
|
||||
else:
|
||||
print(#quot;else#quot;)
|
||||
finally:
|
||||
print(#quot;finally#quot;)\n"]
|
||||
block7["print(#quot;Exception#quot;)\n"]
|
||||
block8["try:
|
||||
print(#quot;try#quot;)
|
||||
except Exception:
|
||||
print(#quot;Exception#quot;)
|
||||
except OtherException as e:
|
||||
print(#quot;OtherException#quot;)
|
||||
else:
|
||||
print(#quot;else#quot;)
|
||||
finally:
|
||||
print(#quot;finally#quot;)\n"]
|
||||
block9["try:
|
||||
print(#quot;try#quot;)
|
||||
except Exception:
|
||||
print(#quot;Exception#quot;)
|
||||
except OtherException as e:
|
||||
print(#quot;OtherException#quot;)
|
||||
else:
|
||||
print(#quot;else#quot;)
|
||||
finally:
|
||||
print(#quot;finally#quot;)\n"]
|
||||
|
||||
start --> block9
|
||||
block9 -- "Exception raised" --> block8
|
||||
block9 -- "else" --> block3
|
||||
block8 -- "Exception" --> block7
|
||||
block8 -- "else" --> block6
|
||||
block7 --> block1
|
||||
block6 -- "OtherException" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block1
|
||||
block4 --> block1
|
||||
block3 --> block2
|
||||
block2 --> block1
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 1
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
print("try")
|
||||
except:
|
||||
print("Exception")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(#quot;try#quot;)\n"]
|
||||
block2[["Exception raised"]]
|
||||
block3["print(#quot;Exception#quot;)\n"]
|
||||
block4["try:
|
||||
print(#quot;try#quot;)
|
||||
except:
|
||||
print(#quot;Exception#quot;)\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "Exception raised" --> block3
|
||||
block4 -- "else" --> block1
|
||||
block3 --> block0
|
||||
block2 --> return
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 2
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
print("try")
|
||||
except:
|
||||
print("Exception")
|
||||
except OtherException as e:
|
||||
print("OtherException")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(#quot;try#quot;)\n"]
|
||||
block2[["Exception raised"]]
|
||||
block3["print(#quot;OtherException#quot;)\n"]
|
||||
block4["try:
|
||||
print(#quot;try#quot;)
|
||||
except:
|
||||
print(#quot;Exception#quot;)
|
||||
except OtherException as e:
|
||||
print(#quot;OtherException#quot;)\n"]
|
||||
block5["print(#quot;Exception#quot;)\n"]
|
||||
block6["try:
|
||||
print(#quot;try#quot;)
|
||||
except:
|
||||
print(#quot;Exception#quot;)
|
||||
except OtherException as e:
|
||||
print(#quot;OtherException#quot;)\n"]
|
||||
|
||||
start --> block6
|
||||
block6 -- "Exception raised" --> block5
|
||||
block6 -- "else" --> block1
|
||||
block5 --> block0
|
||||
block4 -- "OtherException" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block0
|
||||
block2 --> return
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 3
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
print("try")
|
||||
except Exception:
|
||||
print("Exception")
|
||||
except OtherException as e:
|
||||
print("OtherException")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(#quot;try#quot;)\n"]
|
||||
block2[["Exception raised"]]
|
||||
block3["print(#quot;OtherException#quot;)\n"]
|
||||
block4["try:
|
||||
print(#quot;try#quot;)
|
||||
except Exception:
|
||||
print(#quot;Exception#quot;)
|
||||
except OtherException as e:
|
||||
print(#quot;OtherException#quot;)\n"]
|
||||
block5["print(#quot;Exception#quot;)\n"]
|
||||
block6["try:
|
||||
print(#quot;try#quot;)
|
||||
except Exception:
|
||||
print(#quot;Exception#quot;)
|
||||
except OtherException as e:
|
||||
print(#quot;OtherException#quot;)\n"]
|
||||
block7["try:
|
||||
print(#quot;try#quot;)
|
||||
except Exception:
|
||||
print(#quot;Exception#quot;)
|
||||
except OtherException as e:
|
||||
print(#quot;OtherException#quot;)\n"]
|
||||
|
||||
start --> block7
|
||||
block7 -- "Exception raised" --> block6
|
||||
block7 -- "else" --> block1
|
||||
block6 -- "Exception" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block0
|
||||
block4 -- "OtherException" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block0
|
||||
block2 --> return
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 4
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
print("try")
|
||||
except Exception:
|
||||
print("Exception")
|
||||
except OtherException as e:
|
||||
print("OtherException")
|
||||
else:
|
||||
print("else")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(#quot;else#quot;)\n"]
|
||||
block2["print(#quot;try#quot;)\n"]
|
||||
block3[["Exception raised"]]
|
||||
block4["print(#quot;OtherException#quot;)\n"]
|
||||
block5["try:
|
||||
print(#quot;try#quot;)
|
||||
except Exception:
|
||||
print(#quot;Exception#quot;)
|
||||
except OtherException as e:
|
||||
print(#quot;OtherException#quot;)
|
||||
else:
|
||||
print(#quot;else#quot;)\n"]
|
||||
block6["print(#quot;Exception#quot;)\n"]
|
||||
block7["try:
|
||||
print(#quot;try#quot;)
|
||||
except Exception:
|
||||
print(#quot;Exception#quot;)
|
||||
except OtherException as e:
|
||||
print(#quot;OtherException#quot;)
|
||||
else:
|
||||
print(#quot;else#quot;)\n"]
|
||||
block8["try:
|
||||
print(#quot;try#quot;)
|
||||
except Exception:
|
||||
print(#quot;Exception#quot;)
|
||||
except OtherException as e:
|
||||
print(#quot;OtherException#quot;)
|
||||
else:
|
||||
print(#quot;else#quot;)\n"]
|
||||
|
||||
start --> block8
|
||||
block8 -- "Exception raised" --> block7
|
||||
block8 -- "else" --> block2
|
||||
block7 -- "Exception" --> block6
|
||||
block7 -- "else" --> block5
|
||||
block6 --> block0
|
||||
block5 -- "OtherException" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> block0
|
||||
block3 --> return
|
||||
block2 --> block1
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 5
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
print("try")
|
||||
finally:
|
||||
print("finally")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(#quot;finally#quot;)\n"]
|
||||
block2["print(#quot;try#quot;)\n"]
|
||||
block3[["Exception raised"]]
|
||||
block4["try:
|
||||
print(#quot;try#quot;)
|
||||
finally:
|
||||
print(#quot;finally#quot;)\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "Exception raised" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block1
|
||||
block2 --> block1
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 6
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
return 0
|
||||
except:
|
||||
return 1
|
||||
finally:
|
||||
return 2
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["return 2\n"]
|
||||
block2["return 0\n"]
|
||||
block3[["Exception raised"]]
|
||||
block4["return 1\n"]
|
||||
block5["try:
|
||||
return 0
|
||||
except:
|
||||
return 1
|
||||
finally:
|
||||
return 2\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "Exception raised" --> block4
|
||||
block5 -- "else" --> block2
|
||||
block4 --> block1
|
||||
block3 --> block1
|
||||
block2 --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 7
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
raise Exception()
|
||||
except:
|
||||
print("reached")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Exception raised"]]
|
||||
block2["raise Exception()\n"]
|
||||
block3[["Exception raised"]]
|
||||
block4["print(#quot;reached#quot;)\n"]
|
||||
block5["try:
|
||||
raise Exception()
|
||||
except:
|
||||
print(#quot;reached#quot;)\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "Exception raised" --> block4
|
||||
block5 -- "else" --> block2
|
||||
block4 --> block0
|
||||
block3 --> return
|
||||
block2 --> block4
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 8
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
assert False
|
||||
print("unreachable")
|
||||
except:
|
||||
print("reached")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(#quot;unreachable#quot;)\n"]
|
||||
block2[["Exception raised"]]
|
||||
block3["assert False\n"]
|
||||
block4[["Exception raised"]]
|
||||
block5["print(#quot;reached#quot;)\n"]
|
||||
block6["try:
|
||||
assert False
|
||||
print(#quot;unreachable#quot;)
|
||||
except:
|
||||
print(#quot;reached#quot;)\n"]
|
||||
|
||||
start --> block6
|
||||
block6 -- "Exception raised" --> block5
|
||||
block6 -- "else" --> block3
|
||||
block5 --> block0
|
||||
block4 --> return
|
||||
block3 -- "False" --> block1
|
||||
block3 -- "else" --> block5
|
||||
block2 --> return
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 9
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
raise Exception()
|
||||
finally:
|
||||
print('reached')
|
||||
return 2
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print('reached')\nreturn 2\n"]
|
||||
block2[["Exception raised"]]
|
||||
block3["raise Exception()\n"]
|
||||
block4[["Exception raised"]]
|
||||
block5["try:
|
||||
raise Exception()
|
||||
finally:
|
||||
print('reached')
|
||||
return 2\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "Exception raised" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> block1
|
||||
block3 --> block1
|
||||
block2 --> return
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 10
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
assert False
|
||||
print("unreachable")
|
||||
finally:
|
||||
print("reached")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["print(#quot;reached#quot;)\n"]
|
||||
block2["print(#quot;unreachable#quot;)\n"]
|
||||
block3[["Exception raised"]]
|
||||
block4["assert False\n"]
|
||||
block5[["Exception raised"]]
|
||||
block6["try:
|
||||
assert False
|
||||
print(#quot;unreachable#quot;)
|
||||
finally:
|
||||
print(#quot;reached#quot;)\n"]
|
||||
|
||||
start --> block6
|
||||
block6 -- "Exception raised" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block1
|
||||
block4 -- "False" --> block2
|
||||
block4 -- "else" --> block1
|
||||
block3 --> return
|
||||
block2 --> block1
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 11
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
if catalog is not None:
|
||||
try:
|
||||
x = 0
|
||||
except PySparkParseException:
|
||||
x = 1
|
||||
try:
|
||||
x = 2
|
||||
except PySparkParseException:
|
||||
x = 3
|
||||
x = 8
|
||||
finally:
|
||||
if catalog is not None:
|
||||
try:
|
||||
x = 4
|
||||
except PySparkParseException:
|
||||
x = 5
|
||||
try:
|
||||
x = 6
|
||||
except PySparkParseException:
|
||||
x = 7
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1["x = 6\n"]
|
||||
block2[["Exception raised"]]
|
||||
block3["x = 7\n"]
|
||||
block4["try:
|
||||
x = 6
|
||||
except PySparkParseException:
|
||||
x = 7\n"]
|
||||
block5["try:
|
||||
x = 6
|
||||
except PySparkParseException:
|
||||
x = 7\n"]
|
||||
block6["x = 4\n"]
|
||||
block7[["Exception raised"]]
|
||||
block8["x = 5\n"]
|
||||
block9["try:
|
||||
x = 4
|
||||
except PySparkParseException:
|
||||
x = 5\n"]
|
||||
block10["try:
|
||||
x = 4
|
||||
except PySparkParseException:
|
||||
x = 5\n"]
|
||||
block11["if catalog is not None:
|
||||
try:
|
||||
x = 4
|
||||
except PySparkParseException:
|
||||
x = 5\n"]
|
||||
block12["x = 8\n"]
|
||||
block13["x = 2\n"]
|
||||
block14[["Exception raised"]]
|
||||
block15["x = 3\n"]
|
||||
block16["try:
|
||||
x = 2
|
||||
except PySparkParseException:
|
||||
x = 3\n"]
|
||||
block17["try:
|
||||
x = 2
|
||||
except PySparkParseException:
|
||||
x = 3\n"]
|
||||
block18["x = 0\n"]
|
||||
block19[["Exception raised"]]
|
||||
block20["x = 1\n"]
|
||||
block21["try:
|
||||
x = 0
|
||||
except PySparkParseException:
|
||||
x = 1\n"]
|
||||
block22["try:
|
||||
x = 0
|
||||
except PySparkParseException:
|
||||
x = 1\n"]
|
||||
block23["if catalog is not None:
|
||||
try:
|
||||
x = 0
|
||||
except PySparkParseException:
|
||||
x = 1\n"]
|
||||
block24[["Exception raised"]]
|
||||
block25["try:
|
||||
if catalog is not None:
|
||||
try:
|
||||
x = 0
|
||||
except PySparkParseException:
|
||||
x = 1
|
||||
try:
|
||||
x = 2
|
||||
except PySparkParseException:
|
||||
x = 3
|
||||
x = 8
|
||||
finally:
|
||||
if catalog is not None:
|
||||
try:
|
||||
x = 4
|
||||
except PySparkParseException:
|
||||
x = 5
|
||||
try:
|
||||
x = 6
|
||||
except PySparkParseException:
|
||||
x = 7\n"]
|
||||
|
||||
start --> block25
|
||||
block25 -- "Exception raised" --> block24
|
||||
block25 -- "else" --> block23
|
||||
block24 --> block11
|
||||
block23 -- "catalog is not None" --> block22
|
||||
block23 -- "else" --> block17
|
||||
block22 -- "Exception raised" --> block21
|
||||
block22 -- "else" --> block18
|
||||
block21 -- "PySparkParseException" --> block20
|
||||
block21 -- "else" --> block19
|
||||
block20 --> block17
|
||||
block19 --> block11
|
||||
block18 --> block17
|
||||
block17 -- "Exception raised" --> block16
|
||||
block17 -- "else" --> block13
|
||||
block16 -- "PySparkParseException" --> block15
|
||||
block16 -- "else" --> block14
|
||||
block15 --> block12
|
||||
block14 --> block11
|
||||
block13 --> block12
|
||||
block12 --> block11
|
||||
block11 -- "catalog is not None" --> block10
|
||||
block11 -- "else" --> block5
|
||||
block10 -- "Exception raised" --> block9
|
||||
block10 -- "else" --> block6
|
||||
block9 -- "PySparkParseException" --> block8
|
||||
block9 -- "else" --> block7
|
||||
block8 --> block5
|
||||
block7 --> return
|
||||
block6 --> block5
|
||||
block5 -- "Exception raised" --> block4
|
||||
block5 -- "else" --> block1
|
||||
block4 -- "PySparkParseException" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block0
|
||||
block2 --> return
|
||||
block1 --> block0
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 12
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
try:
|
||||
assert False
|
||||
except ex:
|
||||
raise ex
|
||||
|
||||
finally:
|
||||
raise Exception("other")
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Exception raised"]]
|
||||
block2["raise Exception(#quot;other#quot;)\n"]
|
||||
block3[["Exception raised"]]
|
||||
block4["assert False\n"]
|
||||
block5[["Exception raised"]]
|
||||
block6[["Exception raised"]]
|
||||
block7["raise ex\n"]
|
||||
block8["try:
|
||||
assert False
|
||||
except ex:
|
||||
raise ex
|
||||
|
||||
finally:
|
||||
raise Exception(#quot;other#quot;)\n"]
|
||||
block9["try:
|
||||
assert False
|
||||
except ex:
|
||||
raise ex
|
||||
|
||||
finally:
|
||||
raise Exception(#quot;other#quot;)\n"]
|
||||
|
||||
start --> block9
|
||||
block9 -- "Exception raised" --> block8
|
||||
block9 -- "else" --> block4
|
||||
block8 -- "ex" --> block7
|
||||
block8 -- "else" --> block5
|
||||
block7 --> block2
|
||||
block6 --> return
|
||||
block5 --> block2
|
||||
block4 -- "False" --> block2
|
||||
block4 -- "else" --> block8
|
||||
block3 --> return
|
||||
block2 --> block1
|
||||
block1 --> return
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 13
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
for i in():
|
||||
try:
|
||||
try:
|
||||
while r:
|
||||
if t:break
|
||||
finally:()
|
||||
return
|
||||
except:l
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Loop continue"]]
|
||||
block2["return\n"]
|
||||
block3["()\n"]
|
||||
block4[["Loop continue"]]
|
||||
block5["break\n"]
|
||||
block6["if t:break\n"]
|
||||
block7["while r:
|
||||
if t:break\n"]
|
||||
block8[["Exception raised"]]
|
||||
block9["try:
|
||||
while r:
|
||||
if t:break
|
||||
finally:()\n"]
|
||||
block10[["Exception raised"]]
|
||||
block11["l\n"]
|
||||
block12["try:
|
||||
try:
|
||||
while r:
|
||||
if t:break
|
||||
finally:()
|
||||
return
|
||||
except:l\n"]
|
||||
block13["for i in():
|
||||
try:
|
||||
try:
|
||||
while r:
|
||||
if t:break
|
||||
finally:()
|
||||
return
|
||||
except:l\n"]
|
||||
|
||||
start --> block13
|
||||
block13 -- "()" --> block12
|
||||
block13 -- "else" --> block0
|
||||
block12 -- "Exception raised" --> block11
|
||||
block12 -- "else" --> block9
|
||||
block11 --> block1
|
||||
block10 --> return
|
||||
block9 -- "Exception raised" --> block8
|
||||
block9 -- "else" --> block7
|
||||
block8 --> block3
|
||||
block7 -- "r" --> block6
|
||||
block7 -- "else" --> block3
|
||||
block6 -- "t" --> block5
|
||||
block6 -- "else" --> block4
|
||||
block5 --> block3
|
||||
block4 --> block7
|
||||
block3 --> block2
|
||||
block2 --> return
|
||||
block1 --> block13
|
||||
block0 --> return
|
||||
```
|
|
@ -1,839 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/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[["Loop continue"]]
|
||||
block2["return #quot;unreachable#quot;\n"]
|
||||
block3["while False:
|
||||
return #quot;unreachable#quot;\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "False" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> return
|
||||
block1 --> block3
|
||||
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[["`*(empty)*`"]]
|
||||
block1["return 1\n"]
|
||||
block2[["Loop continue"]]
|
||||
block3["return #quot;unreachable#quot;\n"]
|
||||
block4["while False:
|
||||
return #quot;unreachable#quot;
|
||||
else:
|
||||
return 1\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "False" --> block3
|
||||
block4 -- "else" --> block1
|
||||
block3 --> return
|
||||
block2 --> block4
|
||||
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 1\n"]
|
||||
block2[["Loop continue"]]
|
||||
block3["return #quot;unreachable#quot;\n"]
|
||||
block4["while False:
|
||||
return #quot;unreachable#quot;
|
||||
else:
|
||||
return 1\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "False" --> block3
|
||||
block4 -- "else" --> block1
|
||||
block3 --> return
|
||||
block2 --> block4
|
||||
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[["Loop continue"]]
|
||||
block2["return 1\n"]
|
||||
block3["while True:
|
||||
return 1\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> return
|
||||
block1 --> block3
|
||||
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[["`*(empty)*`"]]
|
||||
block1["return #quot;unreachable#quot;\n"]
|
||||
block2[["Loop continue"]]
|
||||
block3["return 1\n"]
|
||||
block4["while True:
|
||||
return 1
|
||||
else:
|
||||
return #quot;unreachable#quot;\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block1
|
||||
block3 --> return
|
||||
block2 --> block4
|
||||
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 #quot;unreachable#quot;\n"]
|
||||
block2[["Loop continue"]]
|
||||
block3["return 1\n"]
|
||||
block4["while True:
|
||||
return 1
|
||||
else:
|
||||
return #quot;unreachable#quot;\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block1
|
||||
block3 --> return
|
||||
block2 --> block4
|
||||
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[["Loop continue"]]
|
||||
block2["i += 1\n"]
|
||||
block3["i = 0\nwhile False:
|
||||
i += 1\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "False" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> block1
|
||||
block1 --> block3
|
||||
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[["Loop continue"]]
|
||||
block2["i += 1\n"]
|
||||
block3["i = 0\nwhile True:
|
||||
i += 1\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> block1
|
||||
block1 --> block3
|
||||
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[["Loop continue"]]
|
||||
block2["pass\n"]
|
||||
block3["while True:
|
||||
pass\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> block1
|
||||
block1 --> block3
|
||||
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[["Loop continue"]]
|
||||
block2["i += 1\n"]
|
||||
block3["print(#quot;ok#quot;)\n"]
|
||||
block4["if True:
|
||||
print(#quot;ok#quot;)\n"]
|
||||
block5["i = 0\nwhile True:
|
||||
if True:
|
||||
print(#quot;ok#quot;)
|
||||
i += 1\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "True" --> block4
|
||||
block5 -- "else" --> block0
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block2
|
||||
block2 --> block1
|
||||
block1 --> block5
|
||||
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[["Loop continue"]]
|
||||
block2["i += 1\n"]
|
||||
block3["print(#quot;ok#quot;)\n"]
|
||||
block4["if False:
|
||||
print(#quot;ok#quot;)\n"]
|
||||
block5["i = 0\nwhile True:
|
||||
if False:
|
||||
print(#quot;ok#quot;)
|
||||
i += 1\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "True" --> block4
|
||||
block5 -- "else" --> block0
|
||||
block4 -- "False" --> block3
|
||||
block4 -- "else" --> block2
|
||||
block3 --> block2
|
||||
block2 --> block1
|
||||
block1 --> block5
|
||||
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[["Loop continue"]]
|
||||
block2["return 1\n"]
|
||||
block3["if True:
|
||||
return 1\n"]
|
||||
block4["while True:
|
||||
if True:
|
||||
return 1\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> return
|
||||
block1 --> block4
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 12
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
continue
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Loop continue"]]
|
||||
block2["continue\n"]
|
||||
block3["while True:
|
||||
continue\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> block3
|
||||
block1 --> block3
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 13
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while False:
|
||||
continue
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Loop continue"]]
|
||||
block2["continue\n"]
|
||||
block3["while False:
|
||||
continue\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "False" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> block3
|
||||
block1 --> block3
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 14
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
break
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Loop continue"]]
|
||||
block2["break\n"]
|
||||
block3["while True:
|
||||
break\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> return
|
||||
block1 --> block3
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 15
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while False:
|
||||
break
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Loop continue"]]
|
||||
block2["break\n"]
|
||||
block3["while False:
|
||||
break\n"]
|
||||
|
||||
start --> block3
|
||||
block3 -- "False" --> block2
|
||||
block3 -- "else" --> block0
|
||||
block2 --> return
|
||||
block1 --> block3
|
||||
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[["Loop continue"]]
|
||||
block2["continue\n"]
|
||||
block3["if True:
|
||||
continue\n"]
|
||||
block4["while True:
|
||||
if True:
|
||||
continue\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> block4
|
||||
block1 --> block4
|
||||
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[["Loop continue"]]
|
||||
block2["break\n"]
|
||||
block3["if True:
|
||||
break\n"]
|
||||
block4["while True:
|
||||
if True:
|
||||
break\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 -- "True" --> block2
|
||||
block3 -- "else" --> block1
|
||||
block2 --> return
|
||||
block1 --> block4
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 18
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
x = 0
|
||||
x = 1
|
||||
break
|
||||
x = 2
|
||||
x = 3
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["x = 3\n"]
|
||||
block1[["Loop continue"]]
|
||||
block2["x = 2\n"]
|
||||
block3["x = 0\nx = 1\nbreak\n"]
|
||||
block4["while True:
|
||||
x = 0
|
||||
x = 1
|
||||
break
|
||||
x = 2\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 --> block0
|
||||
block2 --> block1
|
||||
block1 --> block4
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 19
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
x = 0
|
||||
x = 1
|
||||
continue
|
||||
x = 2
|
||||
x = 3
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["x = 3\n"]
|
||||
block1[["Loop continue"]]
|
||||
block2["x = 2\n"]
|
||||
block3["x = 0\nx = 1\ncontinue\n"]
|
||||
block4["while True:
|
||||
x = 0
|
||||
x = 1
|
||||
continue
|
||||
x = 2\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 --> block4
|
||||
block2 --> block1
|
||||
block1 --> block4
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 20
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
x = 0
|
||||
x = 1
|
||||
return
|
||||
x = 2
|
||||
x = 3
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["x = 3\n"]
|
||||
block1[["Loop continue"]]
|
||||
block2["x = 2\n"]
|
||||
block3["x = 0\nx = 1\nreturn\n"]
|
||||
block4["while True:
|
||||
x = 0
|
||||
x = 1
|
||||
return
|
||||
x = 2\n"]
|
||||
|
||||
start --> block4
|
||||
block4 -- "True" --> block3
|
||||
block4 -- "else" --> block0
|
||||
block3 --> return
|
||||
block2 --> block1
|
||||
block1 --> block4
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 21
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while True:
|
||||
x = 0
|
||||
x = 1
|
||||
raise Exception
|
||||
x = 2
|
||||
x = 3
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["x = 3\n"]
|
||||
block1[["Loop continue"]]
|
||||
block2["x = 2\n"]
|
||||
block3[["Exception raised"]]
|
||||
block4["x = 0\nx = 1\nraise Exception\n"]
|
||||
block5["while True:
|
||||
x = 0
|
||||
x = 1
|
||||
raise Exception
|
||||
x = 2\n"]
|
||||
|
||||
start --> block5
|
||||
block5 -- "True" --> block4
|
||||
block5 -- "else" --> block0
|
||||
block4 --> block3
|
||||
block3 --> return
|
||||
block2 --> block1
|
||||
block1 --> block5
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 22
|
||||
### Source
|
||||
```python
|
||||
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)
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0["self.thread = threading.Thread(target=self._run_web_server)\n"]
|
||||
block1[["Loop continue"]]
|
||||
block2["self.server = HTTPServer((host, port), HtmlOnlyHandler)\nself.host = host\nself.port = port\nbreak\n"]
|
||||
block3[["Exception raised"]]
|
||||
block4["log.debug(f#quot;port {port} is in use, trying to next one#quot;)\nport += 1\n"]
|
||||
block5["try:
|
||||
self.server = HTTPServer((host, port), HtmlOnlyHandler)
|
||||
self.host = host
|
||||
self.port = port
|
||||
break
|
||||
except OSError:
|
||||
log.debug(f#quot;port {port} is in use, trying to next one#quot;)
|
||||
port += 1\n"]
|
||||
block6["try:
|
||||
self.server = HTTPServer((host, port), HtmlOnlyHandler)
|
||||
self.host = host
|
||||
self.port = port
|
||||
break
|
||||
except OSError:
|
||||
log.debug(f#quot;port {port} is in use, trying to next one#quot;)
|
||||
port += 1\n"]
|
||||
block7["self.stop_serving = False\nwhile True:
|
||||
try:
|
||||
self.server = HTTPServer((host, port), HtmlOnlyHandler)
|
||||
self.host = host
|
||||
self.port = port
|
||||
break
|
||||
except OSError:
|
||||
log.debug(f#quot;port {port} is in use, trying to next one#quot;)
|
||||
port += 1\n"]
|
||||
|
||||
start --> block7
|
||||
block7 -- "True" --> block6
|
||||
block7 -- "else" --> block0
|
||||
block6 -- "Exception raised" --> block5
|
||||
block6 -- "else" --> block2
|
||||
block5 -- "OSError" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> block1
|
||||
block3 --> return
|
||||
block2 --> block0
|
||||
block1 --> block7
|
||||
block0 --> return
|
||||
```
|
||||
|
||||
## Function 23
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
while T:
|
||||
try:
|
||||
while():
|
||||
if 3:
|
||||
break
|
||||
finally:
|
||||
return
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start(("Start"))
|
||||
return(("End"))
|
||||
block0[["`*(empty)*`"]]
|
||||
block1[["Loop continue"]]
|
||||
block2["return\n"]
|
||||
block3[["Loop continue"]]
|
||||
block4["break\n"]
|
||||
block5["if 3:
|
||||
break\n"]
|
||||
block6["while():
|
||||
if 3:
|
||||
break\n"]
|
||||
block7[["Exception raised"]]
|
||||
block8["try:
|
||||
while():
|
||||
if 3:
|
||||
break
|
||||
finally:
|
||||
return\n"]
|
||||
block9["while T:
|
||||
try:
|
||||
while():
|
||||
if 3:
|
||||
break
|
||||
finally:
|
||||
return\n"]
|
||||
|
||||
start --> block9
|
||||
block9 -- "T" --> block8
|
||||
block9 -- "else" --> block0
|
||||
block8 -- "Exception raised" --> block7
|
||||
block8 -- "else" --> block6
|
||||
block7 --> block2
|
||||
block6 -- "()" --> block5
|
||||
block6 -- "else" --> block2
|
||||
block5 -- "3" --> block4
|
||||
block5 -- "else" --> block3
|
||||
block4 --> block2
|
||||
block3 --> block6
|
||||
block2 --> return
|
||||
block1 --> block9
|
||||
block0 --> return
|
||||
```
|
File diff suppressed because it is too large
Load diff
|
@ -1,266 +1,4 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
||||
---
|
||||
unreachable.py:3:5: PLW0101 Unreachable code in `after_return`
|
||||
|
|
||||
1 | def after_return():
|
||||
2 | return "reachable"
|
||||
3 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
4 |
|
||||
5 | async def also_works_on_async_functions():
|
||||
|
|
||||
|
||||
unreachable.py:7:5: PLW0101 Unreachable code in `also_works_on_async_functions`
|
||||
|
|
||||
5 | async def also_works_on_async_functions():
|
||||
6 | return "reachable"
|
||||
7 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
8 |
|
||||
9 | def if_always_true():
|
||||
|
|
||||
|
||||
unreachable.py:12:5: PLW0101 Unreachable code in `if_always_true`
|
||||
|
|
||||
10 | if True:
|
||||
11 | return "reachable"
|
||||
12 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
13 |
|
||||
14 | def if_always_false():
|
||||
|
|
||||
|
||||
unreachable.py:16:9: PLW0101 Unreachable code in `if_always_false`
|
||||
|
|
||||
14 | def if_always_false():
|
||||
15 | if False:
|
||||
16 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
17 | return "reachable"
|
||||
|
|
||||
|
||||
unreachable.py:21:9: PLW0101 Unreachable code in `if_elif_always_false`
|
||||
|
|
||||
19 | def if_elif_always_false():
|
||||
20 | if False:
|
||||
21 | / return "unreachable"
|
||||
22 | | elif False:
|
||||
23 | | return "also unreachable"
|
||||
| |_________________________________^ PLW0101
|
||||
24 | return "reachable"
|
||||
|
|
||||
|
||||
unreachable.py:28:9: PLW0101 Unreachable code in `if_elif_always_true`
|
||||
|
|
||||
26 | def if_elif_always_true():
|
||||
27 | if False:
|
||||
28 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
29 | elif True:
|
||||
30 | return "reachable"
|
||||
|
|
||||
|
||||
unreachable.py:31:5: PLW0101 Unreachable code in `if_elif_always_true`
|
||||
|
|
||||
29 | elif True:
|
||||
30 | return "reachable"
|
||||
31 | return "also unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
32 |
|
||||
33 | def ends_with_if():
|
||||
|
|
||||
|
||||
unreachable.py:35:9: PLW0101 Unreachable code in `ends_with_if`
|
||||
|
|
||||
33 | def ends_with_if():
|
||||
34 | if False:
|
||||
35 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
36 | else:
|
||||
37 | return "reachable"
|
||||
|
|
||||
|
||||
unreachable.py:42:5: PLW0101 Unreachable code in `infinite_loop`
|
||||
|
|
||||
40 | while True:
|
||||
41 | continue
|
||||
42 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
43 |
|
||||
44 | ''' TODO: we could determine these, but we don't yet.
|
||||
|
|
||||
|
||||
unreachable.py:75:5: PLW0101 Unreachable code in `match_wildcard`
|
||||
|
|
||||
73 | case _:
|
||||
74 | return "reachable"
|
||||
75 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
76 |
|
||||
77 | def match_case_and_wildcard(status):
|
||||
|
|
||||
|
||||
unreachable.py:83:5: PLW0101 Unreachable code in `match_case_and_wildcard`
|
||||
|
|
||||
81 | case _:
|
||||
82 | return "reachable"
|
||||
83 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
84 |
|
||||
85 | def raise_exception():
|
||||
|
|
||||
|
||||
unreachable.py:87:5: PLW0101 Unreachable code in `raise_exception`
|
||||
|
|
||||
85 | def raise_exception():
|
||||
86 | raise Exception
|
||||
87 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
88 |
|
||||
89 | def while_false():
|
||||
|
|
||||
|
||||
unreachable.py:91:9: PLW0101 Unreachable code in `while_false`
|
||||
|
|
||||
89 | def while_false():
|
||||
90 | while False:
|
||||
91 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
92 | return "reachable"
|
||||
|
|
||||
|
||||
unreachable.py:96:9: PLW0101 Unreachable code in `while_false_else`
|
||||
|
|
||||
94 | def while_false_else():
|
||||
95 | while False:
|
||||
96 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
97 | else:
|
||||
98 | return "reachable"
|
||||
|
|
||||
|
||||
unreachable.py:102:9: PLW0101 Unreachable code in `while_false_else_return`
|
||||
|
|
||||
100 | def while_false_else_return():
|
||||
101 | while False:
|
||||
102 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
103 | else:
|
||||
104 | return "reachable"
|
||||
|
|
||||
|
||||
unreachable.py:105:5: PLW0101 Unreachable code in `while_false_else_return`
|
||||
|
|
||||
103 | else:
|
||||
104 | return "reachable"
|
||||
105 | return "also unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
106 |
|
||||
107 | def while_true():
|
||||
|
|
||||
|
||||
unreachable.py:110:5: PLW0101 Unreachable code in `while_true`
|
||||
|
|
||||
108 | while True:
|
||||
109 | return "reachable"
|
||||
110 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
111 |
|
||||
112 | def while_true_else():
|
||||
|
|
||||
|
||||
unreachable.py:116:9: PLW0101 Unreachable code in `while_true_else`
|
||||
|
|
||||
114 | return "reachable"
|
||||
115 | else:
|
||||
116 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
117 |
|
||||
118 | def while_true_else_return():
|
||||
|
|
||||
|
||||
unreachable.py:122:9: PLW0101 Unreachable code in `while_true_else_return`
|
||||
|
|
||||
120 | return "reachable"
|
||||
121 | else:
|
||||
122 | / return "unreachable"
|
||||
123 | | return "also unreachable"
|
||||
| |_____________________________^ PLW0101
|
||||
124 |
|
||||
125 | def while_false_var_i():
|
||||
|
|
||||
|
||||
unreachable.py:128:9: PLW0101 Unreachable code in `while_false_var_i`
|
||||
|
|
||||
126 | i = 0
|
||||
127 | while False:
|
||||
128 | i += 1
|
||||
| ^^^^^^ PLW0101
|
||||
129 | return i
|
||||
|
|
||||
|
||||
unreachable.py:135:5: PLW0101 Unreachable code in `while_true_var_i`
|
||||
|
|
||||
133 | while True:
|
||||
134 | i += 1
|
||||
135 | return i
|
||||
| ^^^^^^^^ PLW0101
|
||||
136 |
|
||||
137 | def while_infinite():
|
||||
|
|
||||
|
||||
unreachable.py:140:5: PLW0101 Unreachable code in `while_infinite`
|
||||
|
|
||||
138 | while True:
|
||||
139 | pass
|
||||
140 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
141 |
|
||||
142 | def while_if_true():
|
||||
|
|
||||
|
||||
unreachable.py:146:5: PLW0101 Unreachable code in `while_if_true`
|
||||
|
|
||||
144 | if True:
|
||||
145 | return "reachable"
|
||||
146 | return "unreachable"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
147 |
|
||||
148 | def while_break():
|
||||
|
|
||||
|
||||
unreachable.py:152:9: PLW0101 Unreachable code in `while_break`
|
||||
|
|
||||
150 | print("reachable")
|
||||
151 | break
|
||||
152 | print("unreachable")
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PLW0101
|
||||
153 | return "reachable"
|
||||
|
|
||||
|
||||
unreachable.py:248:5: PLW0101 Unreachable code in `after_return`
|
||||
|
|
||||
246 | def after_return():
|
||||
247 | return "reachable"
|
||||
248 | / print("unreachable")
|
||||
249 | | print("unreachable")
|
||||
250 | | print("unreachable")
|
||||
251 | | print("unreachable")
|
||||
252 | | print("unreachable")
|
||||
| |________________________^ PLW0101
|
||||
|
|
||||
|
||||
unreachable.py:257:5: PLW0101 Unreachable code in `check_if_url_exists`
|
||||
|
|
||||
255 | def check_if_url_exists(url: str) -> bool: # type: ignore[return]
|
||||
256 | return True # uncomment to check URLs
|
||||
257 | / response = requests.head(url, allow_redirects=True)
|
||||
258 | | if response.status_code == 200:
|
||||
259 | | return True
|
||||
260 | | if response.status_code == 404:
|
||||
261 | | return False
|
||||
262 | | console.print(f"[red]Unexpected error received: {response.status_code}[/]")
|
||||
263 | | response.raise_for_status()
|
||||
| |_______________________________^ PLW0101
|
||||
|
|
||||
|
|
|
@ -27,6 +27,8 @@ serde = { workspace = true, optional = true }
|
|||
smallvec = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
insta = { workspace = true, features = ["filters", "json", "redactions"] }
|
||||
test-case = { workspace = true }
|
||||
ruff_python_parser = { workspace = true }
|
||||
|
||||
[lints]
|
||||
|
|
24
crates/ruff_python_semantic/resources/test/fixtures/cfg/no_flow.py
vendored
Normal file
24
crates/ruff_python_semantic/resources/test/fixtures/cfg/no_flow.py
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
def func(): ...
|
||||
|
||||
|
||||
def func():
|
||||
pass
|
||||
|
||||
|
||||
def func():
|
||||
x = 1
|
||||
x = 2
|
||||
|
||||
|
||||
def func():
|
||||
foo()
|
||||
|
||||
|
||||
def func():
|
||||
from foo import bar
|
||||
|
||||
class C:
|
||||
a = 1
|
||||
|
||||
c = C()
|
||||
del c
|
293
crates/ruff_python_semantic/src/cfg/graph.rs
Normal file
293
crates/ruff_python_semantic/src/cfg/graph.rs
Normal file
|
@ -0,0 +1,293 @@
|
|||
use ruff_index::{newtype_index, IndexVec};
|
||||
use ruff_python_ast::Stmt;
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
/// Returns the control flow graph associated to an array of statements
|
||||
pub fn build_cfg(stmts: &[Stmt]) -> ControlFlowGraph<'_> {
|
||||
let mut builder = CFGBuilder::with_capacity(stmts.len());
|
||||
builder.process_stmts(stmts);
|
||||
builder.finish()
|
||||
}
|
||||
|
||||
/// Control flow graph
|
||||
#[derive(Debug)]
|
||||
pub struct ControlFlowGraph<'stmt> {
|
||||
/// Basic blocks - the nodes of the control flow graph
|
||||
blocks: IndexVec<BlockId, BlockData<'stmt>>,
|
||||
/// Entry point to the control flow graph
|
||||
initial: BlockId,
|
||||
/// Terminal block - will always be empty
|
||||
terminal: BlockId,
|
||||
}
|
||||
|
||||
impl<'stmt> ControlFlowGraph<'stmt> {
|
||||
/// Index of entry point to the control flow graph
|
||||
pub fn initial(&self) -> BlockId {
|
||||
self.initial
|
||||
}
|
||||
|
||||
/// Index of terminal block
|
||||
pub fn terminal(&self) -> BlockId {
|
||||
self.terminal
|
||||
}
|
||||
|
||||
/// Number of basic blocks, or nodes, in the graph
|
||||
pub fn num_blocks(&self) -> usize {
|
||||
self.blocks.len()
|
||||
}
|
||||
|
||||
/// Returns the statements comprising the basic block at the given index
|
||||
pub fn stmts(&self, block: BlockId) -> &'stmt [Stmt] {
|
||||
self.blocks[block].stmts
|
||||
}
|
||||
|
||||
/// Returns the range of the statements comprising the basic block at the given index
|
||||
pub fn range(&self, block: BlockId) -> TextRange {
|
||||
self.blocks[block].range()
|
||||
}
|
||||
|
||||
/// Returns the [`Edges`] going out of the basic block at the given index
|
||||
pub fn outgoing(&self, block: BlockId) -> &Edges {
|
||||
&self.blocks[block].out
|
||||
}
|
||||
|
||||
/// Returns an iterator over the indices of the direct predecessors of the block at the given index
|
||||
pub fn predecessors(&self, block: BlockId) -> impl ExactSizeIterator<Item = BlockId> + '_ {
|
||||
self.blocks[block].parents.iter().copied()
|
||||
}
|
||||
|
||||
/// Returns the [`BlockKind`] of the block at the given index
|
||||
pub(crate) fn kind(&self, block: BlockId) -> BlockKind {
|
||||
self.blocks[block].kind
|
||||
}
|
||||
}
|
||||
|
||||
#[newtype_index]
|
||||
pub struct BlockId;
|
||||
|
||||
/// Holds the data of a basic block. A basic block consists of a collection of
|
||||
/// [`Stmt`]s, together with outgoing edges to other basic blocks.
|
||||
#[derive(Debug, Default)]
|
||||
struct BlockData<'stmt> {
|
||||
kind: BlockKind,
|
||||
/// Slice of statements regarded as executing unconditionally in order
|
||||
stmts: &'stmt [Stmt],
|
||||
/// Outgoing edges, indicating possible paths of execution after the
|
||||
/// block has concluded
|
||||
out: Edges,
|
||||
/// Collection of indices for basic blocks having the current
|
||||
/// block as the target of an edge
|
||||
parents: SmallVec<[BlockId; 2]>,
|
||||
}
|
||||
|
||||
impl Ranged for BlockData<'_> {
|
||||
fn range(&self) -> TextRange {
|
||||
let Some(first) = self.stmts.first() else {
|
||||
return TextRange::default();
|
||||
};
|
||||
let Some(last) = self.stmts.last() else {
|
||||
return TextRange::default();
|
||||
};
|
||||
|
||||
TextRange::new(first.start(), last.end())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
pub(crate) enum BlockKind {
|
||||
#[default]
|
||||
Generic,
|
||||
/// Entry point of the control flow graph
|
||||
Start,
|
||||
/// Terminal block for the control flow graph
|
||||
Terminal,
|
||||
}
|
||||
|
||||
/// Holds a collection of edges. Each edge is determined by:
|
||||
/// - a [`Condition`] for traversing the edge, and
|
||||
/// - a target block, specified by its [`BlockId`].
|
||||
///
|
||||
/// The conditions and targets are kept in two separate
|
||||
/// vectors which must always be kept the same length.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Edges {
|
||||
conditions: SmallVec<[Condition; 4]>,
|
||||
targets: SmallVec<[BlockId; 4]>,
|
||||
}
|
||||
|
||||
impl Edges {
|
||||
/// Creates an unconditional edge to the target block
|
||||
fn always(target: BlockId) -> Self {
|
||||
Self {
|
||||
conditions: smallvec![Condition::Always],
|
||||
targets: smallvec![target],
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns iterator over indices of blocks targeted by given edges
|
||||
pub fn targets(&self) -> impl ExactSizeIterator<Item = BlockId> + '_ {
|
||||
self.targets.iter().copied()
|
||||
}
|
||||
|
||||
/// Returns iterator over [`Condition`]s which must be satisfied to traverse corresponding edge
|
||||
pub fn conditions(&self) -> impl ExactSizeIterator<Item = &Condition> {
|
||||
self.conditions.iter()
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
self.targets.is_empty()
|
||||
}
|
||||
|
||||
pub fn filter_targets_by_conditions<'a, T: FnMut(&Condition) -> bool + 'a>(
|
||||
&'a self,
|
||||
mut predicate: T,
|
||||
) -> impl Iterator<Item = BlockId> + 'a {
|
||||
self.conditions()
|
||||
.zip(self.targets())
|
||||
.filter(move |(cond, _)| predicate(cond))
|
||||
.map(|(_, block)| block)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a condition to be tested in a multi-way branch
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Condition {
|
||||
/// Unconditional edge
|
||||
Always,
|
||||
}
|
||||
|
||||
struct CFGBuilder<'stmt> {
|
||||
/// Control flow graph under construction
|
||||
cfg: ControlFlowGraph<'stmt>,
|
||||
/// Current basic block index
|
||||
current: BlockId,
|
||||
/// Exit block index for current control flow
|
||||
exit: BlockId,
|
||||
}
|
||||
|
||||
impl<'stmt> CFGBuilder<'stmt> {
|
||||
/// Returns [`CFGBuilder`] with vector of blocks initialized at given capacity and with both initial and terminal blocks populated.
|
||||
fn with_capacity(capacity: usize) -> Self {
|
||||
let mut blocks = IndexVec::with_capacity(capacity);
|
||||
let initial = blocks.push(BlockData {
|
||||
kind: BlockKind::Start,
|
||||
..BlockData::default()
|
||||
});
|
||||
let terminal = blocks.push(BlockData {
|
||||
kind: BlockKind::Terminal,
|
||||
..BlockData::default()
|
||||
});
|
||||
|
||||
Self {
|
||||
cfg: ControlFlowGraph {
|
||||
blocks,
|
||||
initial,
|
||||
terminal,
|
||||
},
|
||||
current: initial,
|
||||
exit: terminal,
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs the core logic for the builder.
|
||||
fn process_stmts(&mut self, stmts: &'stmt [Stmt]) {
|
||||
let start = 0;
|
||||
for stmt in stmts {
|
||||
let cache_exit = self.exit();
|
||||
match stmt {
|
||||
Stmt::FunctionDef(_)
|
||||
| Stmt::ClassDef(_)
|
||||
| Stmt::Assign(_)
|
||||
| Stmt::AugAssign(_)
|
||||
| Stmt::AnnAssign(_)
|
||||
| Stmt::TypeAlias(_)
|
||||
| Stmt::Import(_)
|
||||
| Stmt::ImportFrom(_)
|
||||
| Stmt::Global(_)
|
||||
| Stmt::Nonlocal(_)
|
||||
| Stmt::Expr(_)
|
||||
| Stmt::Pass(_)
|
||||
| Stmt::Delete(_)
|
||||
| Stmt::IpyEscapeCommand(_) => {}
|
||||
// Loops
|
||||
Stmt::While(_) => {}
|
||||
Stmt::For(_) => {}
|
||||
|
||||
// Switch statements
|
||||
Stmt::If(_) => {}
|
||||
Stmt::Match(_) => {}
|
||||
|
||||
// Exception handling statements
|
||||
Stmt::Try(_) => {}
|
||||
Stmt::With(_) => {}
|
||||
|
||||
// Jumps
|
||||
Stmt::Return(_) => {}
|
||||
Stmt::Break(_) => {}
|
||||
Stmt::Continue(_) => {}
|
||||
Stmt::Raise(_) => {}
|
||||
|
||||
// An `assert` is a mixture of a switch and a jump.
|
||||
Stmt::Assert(_) => {}
|
||||
}
|
||||
// Restore exit
|
||||
self.update_exit(cache_exit);
|
||||
}
|
||||
// It can happen that we have statements left over
|
||||
// and not yet occupying a block. In that case,
|
||||
// `self.current` should be pointing to an empty block
|
||||
// and we push the remaining statements to it here.
|
||||
if start < stmts.len() {
|
||||
self.set_current_block_stmts(&stmts[start..]);
|
||||
}
|
||||
// Add edge to exit if not already present
|
||||
if self.cfg.blocks[self.current].out.is_empty() {
|
||||
let edges = Edges::always(self.exit());
|
||||
self.set_current_block_edges(edges);
|
||||
}
|
||||
self.move_to(self.exit());
|
||||
}
|
||||
|
||||
/// Returns finished control flow graph
|
||||
fn finish(self) -> ControlFlowGraph<'stmt> {
|
||||
self.cfg
|
||||
}
|
||||
|
||||
/// Current exit block, which may change during construction
|
||||
fn exit(&self) -> BlockId {
|
||||
self.exit
|
||||
}
|
||||
|
||||
/// Point the current exit to block at provided index
|
||||
fn update_exit(&mut self, new_exit: BlockId) {
|
||||
self.exit = new_exit;
|
||||
}
|
||||
|
||||
/// Moves current block to provided index
|
||||
fn move_to(&mut self, block: BlockId) {
|
||||
self.current = block;
|
||||
}
|
||||
|
||||
/// Populates the current basic block with the given set of statements.
|
||||
///
|
||||
/// This should only be called once on any given block.
|
||||
fn set_current_block_stmts(&mut self, stmts: &'stmt [Stmt]) {
|
||||
debug_assert!(
|
||||
self.cfg.blocks[self.current].stmts.is_empty(),
|
||||
"Attempting to set statements on an already populated basic block."
|
||||
);
|
||||
self.cfg.blocks[self.current].stmts = stmts;
|
||||
}
|
||||
|
||||
/// Draws provided edges out of the current basic block.
|
||||
///
|
||||
/// This should only be called once on any given block.
|
||||
fn set_current_block_edges(&mut self, edges: Edges) {
|
||||
debug_assert!(
|
||||
self.cfg.blocks[self.current].out.is_empty(),
|
||||
"Attempting to set edges on a basic block that already has an outgoing edge."
|
||||
);
|
||||
self.cfg.blocks[self.current].out = edges;
|
||||
}
|
||||
}
|
61
crates/ruff_python_semantic/src/cfg/mod.rs
Normal file
61
crates/ruff_python_semantic/src/cfg/mod.rs
Normal file
|
@ -0,0 +1,61 @@
|
|||
pub mod graph;
|
||||
pub mod visualize;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fmt::Write;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::cfg::graph::build_cfg;
|
||||
use crate::cfg::visualize::draw_cfg;
|
||||
use insta;
|
||||
|
||||
use ruff_python_parser::parse_module;
|
||||
use ruff_text_size::Ranged;
|
||||
use test_case::test_case;
|
||||
|
||||
#[test_case("no_flow.py")]
|
||||
fn control_flow_graph(filename: &str) {
|
||||
let path = PathBuf::from("resources/test/fixtures/cfg").join(filename);
|
||||
let source = fs::read_to_string(path).expect("failed to read file");
|
||||
let stmts = parse_module(&source)
|
||||
.unwrap_or_else(|err| panic!("failed to parse source: '{source}': {err}"))
|
||||
.into_suite();
|
||||
|
||||
let mut output = String::new();
|
||||
|
||||
for (i, stmt) in stmts.into_iter().enumerate() {
|
||||
let func = stmt.as_function_def_stmt().expect(
|
||||
"Snapshot test for control flow graph should consist only of function definitions",
|
||||
);
|
||||
let cfg = build_cfg(&func.body);
|
||||
|
||||
let mermaid_graph = draw_cfg(cfg, &source);
|
||||
writeln!(
|
||||
output,
|
||||
"## Function {}\n\
|
||||
### Source\n\
|
||||
```python\n\
|
||||
{}\n\
|
||||
```\n\n\
|
||||
### Control Flow Graph\n\
|
||||
```mermaid\n\
|
||||
{}\n\
|
||||
```\n",
|
||||
i,
|
||||
&source[func.range()],
|
||||
mermaid_graph,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
insta::with_settings!({
|
||||
omit_expression => true,
|
||||
input_file => filename,
|
||||
description => "This is a Mermaid graph. You can use https://mermaid.live to visualize it as a diagram."
|
||||
}, {
|
||||
insta::assert_snapshot!(format!("{filename}.md"), output);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
---
|
||||
source: crates/ruff_python_semantic/src/cfg/mod.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(): ...
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
node0["..."]
|
||||
node1((("EXIT")))
|
||||
node0==>node1
|
||||
```
|
||||
|
||||
## Function 1
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
pass
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
node0["pass"]
|
||||
node1((("EXIT")))
|
||||
node0==>node1
|
||||
```
|
||||
|
||||
## Function 2
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
x = 1
|
||||
x = 2
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
node0["x = 1
|
||||
x = 2"]
|
||||
node1((("EXIT")))
|
||||
node0==>node1
|
||||
```
|
||||
|
||||
## Function 3
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
foo()
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
node0["foo()"]
|
||||
node1((("EXIT")))
|
||||
node0==>node1
|
||||
```
|
||||
|
||||
## Function 4
|
||||
### Source
|
||||
```python
|
||||
def func():
|
||||
from foo import bar
|
||||
|
||||
class C:
|
||||
a = 1
|
||||
|
||||
c = C()
|
||||
del c
|
||||
```
|
||||
|
||||
### Control Flow Graph
|
||||
```mermaid
|
||||
flowchart TD
|
||||
node0["from foo import bar
|
||||
class C:
|
||||
a = 1
|
||||
c = C()
|
||||
del c"]
|
||||
node1((("EXIT")))
|
||||
node0==>node1
|
||||
```
|
244
crates/ruff_python_semantic/src/cfg/visualize.rs
Normal file
244
crates/ruff_python_semantic/src/cfg/visualize.rs
Normal file
|
@ -0,0 +1,244 @@
|
|||
//! Heavily inspired by rustc data structures
|
||||
use ruff_index::Idx;
|
||||
use ruff_text_size::Ranged;
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
use crate::cfg::graph::{BlockId, BlockKind, Condition, ControlFlowGraph};
|
||||
|
||||
/// Returns control flow graph in Mermaid syntax.
|
||||
pub fn draw_cfg(graph: ControlFlowGraph, source: &str) -> String {
|
||||
CFGWithSource::new(graph, source).draw_graph()
|
||||
}
|
||||
|
||||
trait MermaidGraph<'a>: DirectedGraph<'a> {
|
||||
fn draw_node(&self, node: Self::Node) -> MermaidNode;
|
||||
fn draw_edges(&self, node: Self::Node) -> impl Iterator<Item = (Self::Node, MermaidEdge)>;
|
||||
|
||||
fn draw_graph(&self) -> String {
|
||||
let mut graph = Vec::new();
|
||||
|
||||
// Begin mermaid graph.
|
||||
graph.push("flowchart TD".to_string());
|
||||
|
||||
// Draw nodes
|
||||
let num_nodes = self.num_nodes();
|
||||
for idx in 0..num_nodes {
|
||||
let node = Self::Node::new(idx);
|
||||
graph.push(format!("\tnode{}{}", idx, &self.draw_node(node)));
|
||||
}
|
||||
|
||||
// Draw edges
|
||||
for idx in 0..num_nodes {
|
||||
graph.extend(
|
||||
self.draw_edges(Self::Node::new(idx))
|
||||
.map(|(end_idx, edge)| format!("\tnode{}{}node{}", idx, edge, end_idx.index())),
|
||||
);
|
||||
}
|
||||
graph.join("\n")
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MermaidNode {
|
||||
shape: MermaidNodeShape,
|
||||
content: String,
|
||||
}
|
||||
|
||||
impl MermaidNode {
|
||||
pub fn with_content(content: String) -> Self {
|
||||
Self {
|
||||
shape: MermaidNodeShape::default(),
|
||||
content,
|
||||
}
|
||||
}
|
||||
|
||||
fn mermaid_write_quoted_str(f: &mut fmt::Formatter<'_>, value: &str) -> fmt::Result {
|
||||
let mut parts = value.split('"');
|
||||
if let Some(v) = parts.next() {
|
||||
write!(f, "{v}")?;
|
||||
}
|
||||
for v in parts {
|
||||
write!(f, "#quot;{v}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for MermaidNode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let (open, close) = self.shape.open_close();
|
||||
write!(f, "{open}\"")?;
|
||||
if self.content.is_empty() {
|
||||
write!(f, "empty")?;
|
||||
} else {
|
||||
MermaidNode::mermaid_write_quoted_str(f, &self.content)?;
|
||||
}
|
||||
write!(f, "\"{close}")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub enum MermaidNodeShape {
|
||||
#[default]
|
||||
Rectangle,
|
||||
DoubleRectangle,
|
||||
RoundedRectangle,
|
||||
Stadium,
|
||||
Circle,
|
||||
DoubleCircle,
|
||||
Asymmetric,
|
||||
Rhombus,
|
||||
Hexagon,
|
||||
Parallelogram,
|
||||
Trapezoid,
|
||||
}
|
||||
|
||||
impl MermaidNodeShape {
|
||||
fn open_close(&self) -> (&'static str, &'static str) {
|
||||
match self {
|
||||
Self::Rectangle => ("[", "]"),
|
||||
Self::DoubleRectangle => ("[[", "]]"),
|
||||
Self::RoundedRectangle => ("(", ")"),
|
||||
Self::Stadium => ("([", "])"),
|
||||
Self::Circle => ("((", "))"),
|
||||
Self::DoubleCircle => ("(((", ")))"),
|
||||
Self::Asymmetric => (">", "]"),
|
||||
Self::Rhombus => ("{", "}"),
|
||||
Self::Hexagon => ("{{", "}}"),
|
||||
Self::Parallelogram => ("[/", "/]"),
|
||||
Self::Trapezoid => ("[/", "\\]"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct MermaidEdge {
|
||||
kind: MermaidEdgeKind,
|
||||
content: String,
|
||||
}
|
||||
|
||||
impl Display for MermaidEdge {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if self.content.is_empty() {
|
||||
write!(f, "{}", self.kind)
|
||||
} else {
|
||||
write!(f, "{}|\"{}\"|", self.kind, self.content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub enum MermaidEdgeKind {
|
||||
#[default]
|
||||
Arrow,
|
||||
DottedArrow,
|
||||
ThickArrow,
|
||||
BidirectionalArrow,
|
||||
}
|
||||
|
||||
impl Display for MermaidEdgeKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
MermaidEdgeKind::Arrow => write!(f, "-->"),
|
||||
MermaidEdgeKind::DottedArrow => write!(f, "-..->"),
|
||||
MermaidEdgeKind::ThickArrow => write!(f, "==>"),
|
||||
MermaidEdgeKind::BidirectionalArrow => write!(f, "<-->"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DirectedGraph<'a> {
|
||||
type Node: Idx;
|
||||
|
||||
fn num_nodes(&self) -> usize;
|
||||
fn start_node(&self) -> Self::Node;
|
||||
fn successors(&self, node: Self::Node) -> impl ExactSizeIterator<Item = Self::Node> + '_;
|
||||
}
|
||||
|
||||
struct CFGWithSource<'stmt> {
|
||||
cfg: ControlFlowGraph<'stmt>,
|
||||
source: &'stmt str,
|
||||
}
|
||||
|
||||
impl<'stmt> CFGWithSource<'stmt> {
|
||||
fn new(cfg: ControlFlowGraph<'stmt>, source: &'stmt str) -> Self {
|
||||
Self { cfg, source }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'stmt> DirectedGraph<'stmt> for CFGWithSource<'stmt> {
|
||||
type Node = BlockId;
|
||||
|
||||
fn num_nodes(&self) -> usize {
|
||||
self.cfg.num_blocks()
|
||||
}
|
||||
|
||||
fn start_node(&self) -> Self::Node {
|
||||
self.cfg.initial()
|
||||
}
|
||||
|
||||
fn successors(&self, node: Self::Node) -> impl ExactSizeIterator<Item = Self::Node> + '_ {
|
||||
self.cfg.outgoing(node).targets()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'stmt> MermaidGraph<'stmt> for CFGWithSource<'stmt> {
|
||||
fn draw_node(&self, node: Self::Node) -> MermaidNode {
|
||||
let statements: Vec<String> = self
|
||||
.cfg
|
||||
.stmts(node)
|
||||
.iter()
|
||||
.map(|stmt| self.source[stmt.range()].to_string())
|
||||
.collect();
|
||||
let content = match self.cfg.kind(node) {
|
||||
BlockKind::Generic => {
|
||||
if statements.is_empty() {
|
||||
"EMPTY".to_string()
|
||||
} else {
|
||||
statements.join("\n")
|
||||
}
|
||||
}
|
||||
BlockKind::Start => {
|
||||
if statements.is_empty() {
|
||||
"START".to_string()
|
||||
} else {
|
||||
statements.join("\n")
|
||||
}
|
||||
}
|
||||
BlockKind::Terminal => {
|
||||
return MermaidNode {
|
||||
content: "EXIT".to_string(),
|
||||
shape: MermaidNodeShape::DoubleCircle,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MermaidNode::with_content(content)
|
||||
}
|
||||
|
||||
fn draw_edges(&self, node: Self::Node) -> impl Iterator<Item = (Self::Node, MermaidEdge)> {
|
||||
let edge_data = self.cfg.outgoing(node);
|
||||
edge_data
|
||||
.targets()
|
||||
.zip(edge_data.conditions())
|
||||
.map(|(target, condition)| {
|
||||
let edge = match condition {
|
||||
Condition::Always => {
|
||||
if target == self.cfg.terminal() {
|
||||
MermaidEdge {
|
||||
kind: MermaidEdgeKind::ThickArrow,
|
||||
content: String::new(),
|
||||
}
|
||||
} else {
|
||||
MermaidEdge {
|
||||
kind: MermaidEdgeKind::Arrow,
|
||||
content: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
(target, edge)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
pub mod analyze;
|
||||
mod binding;
|
||||
mod branches;
|
||||
pub mod cfg;
|
||||
mod context;
|
||||
mod definition;
|
||||
mod globals;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue