Autofix for RET503 breaks RET505 (in one case)
On the latest version of ruff (0.0.278) this fails on the following code:
ruff --select RET503,RET505 test.py --fix --isolated
# test.py:11:9: RET505 Unnecessary `else` after `return` statement
def main(value: str) -> int | None:
if value == "one":
return 1
if value.startswith("do_stuff"):
print("doing stuff")
if value.endswith("haha"):
print("haha")
else:
print("Instruction unclear.")
else:
print("Doing nothing.")
That is because the autofix for RET503 inserts return None in all three
branches of the if/else tree:
--- test.py
+++ test.py
@@ -7,7 +7,10 @@
if value.endswith("haha"):
print("haha")
+ return None
else:
print("Instruction unclear.")
+ return None
else:
print("Doing nothing.")
+ return None
But that is not compliant with RET505.
The fix in this case is to insert return None at the end of the function instead of in each branch in the if/else tree.
def main(value: str) -> int | None:
if value == "one":
return 1
if value.startswith("do_stuff"):
print("doing stuff")
if value.endswith("haha"):
print("haha")
else:
print("Instruction unclear.")
else:
print("Doing nothing.")
return None
Not sure it is worth the effort to update behavior of the RET503 autofix for this case. But I thought I should report it.
Using Ruff 0.0.285, it also just looks pretty silly to have a chain of return None statements added:
ruff --isolated --fix-only t.py --select=RET503
def f():
if ...:
return True
if ...:
pass
+ return None
+ return None
It's not a big deal for me since I don't mind skipping this cosmetic check, but with such a small repro it seemed worth reporting.
Should RET503 be simplified to only add return None at the end of the function?