ruff icon indicating copy to clipboard operation
ruff copied to clipboard

[Rule request] Missing return statement

Open mrcljx opened this issue 9 months ago • 2 comments

I just stumbled over a bug in our codebase:

def f() -> int:
  return 42

def g() -> int | None:
  f()

The last line should have been return f().

While Mypy reports a Missing return statement, Pyright does not. This is a deliberate decision by the Pyright maintainer (point 2) as there is no type issue here. In this case Mypy actually does some static analysis outside of its main responsibility.

I'm wondering whether there could be a Ruff rule for this. Often, Ruff lacks the type information. But in this case type information isn't needed. If a function:

  1. has a return annotation,
  2. and it's different than -> None or -> NoReturn,
  3. and the body
    1. isn't a stub (... or pass)
    2. doesn't have a return anywhere (in that case RET503 takes over)
    3. and control flow can reach the end of the body
  4. report an error
def ok_1() -> int | None:
  return 2

def ok_2() -> int | None:
  return # < maybe a second rule later could reject `return` without a value in this scenario

def ok_3() -> int | None:
  raise NotImplementedError

def ok_4() -> int | None: ...

def ok_5() -> int | None:
  pass

def ok_6() -> int | None:
  if ...:
    return 42 # RET503 will cause an error here

def ok_7():
  f()
def bad_1() -> int | None:
  f()

def bad_2() -> int | None:
  if ...:
    raise ValueError()

mrcljx avatar May 07 '24 09:05 mrcljx

I think it would be a good idea to extend RET503 to take this into account.

autinerd avatar May 08 '24 04:05 autinerd

I think this could be a good first issue.

JonathanPlasse avatar May 15 '24 12:05 JonathanPlasse