Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Check if function has return statement

Tags:

python

return

E.g.

def f1():
    return 1

def f2():
    return None

def f3():
    print("Hello")

Functions f1() and f2() returns something but f3() not.

a = f2()
b = f3()

And here a equals b so I can't just compare the result of functions to check if one has return or not.

like image 727
Misha Avatar asked Dec 01 '22 10:12

Misha


1 Answers

I like @st0le's idea of inspecting the source, but you can take it a step further and parse the source into a source tree, which eliminates the possibility of false positives.

import ast
import inspect

def contains_explicit_return(f):
    return any(isinstance(node, ast.Return) for node in ast.walk(ast.parse(inspect.getsource(f))))

def f1():
    return 1

def f2():
    return None

def f3():
    print("return")

for f in (f1, f2, f3):
    print(f, contains_explicit_return(f))

Result:

<function f1 at 0x01D151E0> True
<function f2 at 0x01D15AE0> True
<function f3 at 0x0386E108> False

Of course, this only works for functions that have source code written in Python, and not all functions do. For instance, contains_explicit_return(math.sqrt) will give you a TypeError.

Furthermore, this won't tell you anything about whether any particular execution of a function hit a return statement or not. Consider the functions:

def f():
    if random.choice((True, False)):
        return 1

def g():
    if False:
        return 1

contains_explicit_return will give True on both of these, despite f not encountering a return in half of its executions, and g not encountering a return ever.

Last, it won't distinguish between whether the function has a return statement or a function defined inside it has a return statement:

def f():
    def g():
        return 5

In this case, contains_explicit_return(f) will return True, even though f will never return anything, because the function g inside contains an explicit return.

like image 136
Kevin Avatar answered Dec 04 '22 08:12

Kevin