Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unreachable code rule #5384

Merged
merged 12 commits into from
Jul 4, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ crates/ruff/resources/test/fixtures/isort/line_ending_crlf.py text eol=crlf
crates/ruff/resources/test/fixtures/pycodestyle/W605_1.py text eol=crlf

ruff.schema.json linguist-generated=true text=auto eol=lf
*.md.snap linguist-language=Markdown
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/ruff/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ name = "ruff"
[dependencies]
ruff_cache = { path = "../ruff_cache" }
ruff_diagnostics = { path = "../ruff_diagnostics", features = ["serde"] }
ruff_index = { path = "../ruff_index" }
ruff_macros = { path = "../ruff_macros" }
ruff_python_whitespace = { path = "../ruff_python_whitespace" }
ruff_python_ast = { path = "../ruff_python_ast", features = ["serde"] }
Expand Down
11 changes: 11 additions & 0 deletions crates/ruff/resources/test/fixtures/control-flow-graph/assert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
def func():
assert True

def func():
assert False

def func():
assert True, "oops"

def func():
assert False, "oops"
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
def func():
async for i in range(5):
print(i)

def func():
async for i in range(20):
print(i)
else:
return 0

def func():
async for i in range(10):
if i == 5:
return 1
return 0

def func():
async for i in range(111):
if i == 5:
return 1
else:
return 0
return 2

def func():
async for i in range(12):
continue

def func():
async for i in range(1110):
if True:
continue

def func():
async for i in range(13):
break

def func():
async for i in range(1110):
if True:
break
41 changes: 41 additions & 0 deletions crates/ruff/resources/test/fixtures/control-flow-graph/for.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
def func():
for i in range(5):
print(i)

def func():
for i in range(20):
print(i)
else:
return 0

def func():
for i in range(10):
if i == 5:
return 1
return 0

def func():
for i in range(111):
if i == 5:
return 1
else:
return 0
return 2

def func():
for i in range(12):
continue

def func():
for i in range(1110):
if True:
continue

def func():
for i in range(13):
break

def func():
for i in range(1110):
if True:
break
108 changes: 108 additions & 0 deletions crates/ruff/resources/test/fixtures/control-flow-graph/if.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
def func():
if False:
return 0
return 1

def func():
if True:
return 1
return 0

def func():
if False:
return 0
else:
return 1

def func():
if True:
return 1
else:
return 0

def func():
if False:
return 0
else:
return 1
return "unreachable"

def func():
if True:
return 1
else:
return 0
return "unreachable"

def func():
if True:
if True:
return 1
return 2
else:
return 3
return "unreachable2"

def func():
if False:
return 0

def func():
if True:
return 1

def func():
if True:
return 1
elif False:
return 2
else:
return 0

def func():
if False:
return 1
elif True:
return 2
else:
return 0

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

def func():
if False:
return "unreached"
elif False:
return "also unreached"
return "reached"

# Test case found in the Bokeh repository that trigger a false positive.
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
131 changes: 131 additions & 0 deletions crates/ruff/resources/test/fixtures/control-flow-graph/match.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
def func(status):
match status:
case _:
return 0
return "unreachable"

def func(status):
match status:
case 1:
return 1
return 0

def func(status):
match status:
case 1:
return 1
case _:
return 0

def func(status):
match status:
case 1 | 2 | 3:
return 5
return 6

def func(status):
match status:
case 1 | 2 | 3:
return 5
case _:
return 10
return 0

def func(status):
match status:
case 0:
return 0
case 1:
return 1
case 1:
return "1 again"
case _:
return 3

def func(status):
i = 0
match status, i:
case _, _:
return 0

def func(status):
i = 0
match status, i:
case _, 0:
return 0
case _, 2:
return 0

def func(point):
match point:
case (0, 0):
print("Origin")
case _:
raise ValueError("oops")

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")

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")

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")

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")

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 :(")
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def func():
raise Exception

def func():
raise "a glass!"
23 changes: 23 additions & 0 deletions crates/ruff/resources/test/fixtures/control-flow-graph/simple.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
def func():
pass

def func():
pass

def func():
return

def func():
return 1

def func():
return 1
return "unreachable"

def func():
i = 0

def func():
i = 0
i += 2
return i
Loading