I have a python function x that returns some module x(): return y

I would like to parse the file x is located in and learn that "x returns this thing called 'y'". I have no idea how.

I'm not trying to get the type of the return type, just what the programmer calls exactly what is being returned.

  • What do you need that for? – Robert Harvey Aug 14 '15 at 0:13
  • I am trying to write a plugin that documents endpoints in an API written in pecan. Certain functions return functions that they route to, it would be nice to see the name of the functions being returned. – Alex Aug 14 '15 at 0:48
  • See this builtin module - docs.python.org/3/library/parser.html – Ginden Aug 14 '15 at 6:19
  • 1
    Wouldn't it be easier to call the functions and check returned_object.__name__? – jonrsharpe Aug 14 '15 at 7:40

Use the ast module

import ast                                                                                                  
def extract_return(file, fname):                                                                            
    for x in ast.walk(ast.parse(open(file).read())):                                                        
        if not(isinstance(x, ast.FunctionDef)):                                                             
        if not(x.name == fname):                                                                            
        for b in x.body:                                                                                    
            if isinstance(b, ast.Return):                                                                   
                if isinstance(b.value, ast.Name):                                                           
                    yield b.value.id                                                                        

This defines a function which takes some python source's filename and a function name fname (your "x") and yields each identifier returned by function fname. Here, I assume that you are only interested in return statements that occur at the first level of function x and consequently, I don't visit subexpressions. Also, I'am using yield because in more general cases this could work like a filter which could be composed with other ones. In more complex cases, it can be preferable to subclass ast.NodeVisitor.

This is equivalent in size with the regex approach but far more reliable.


It seems like you could hack something together with regexes pretty quickly.


import re
from collections import defaultdict
def findReturns(program_string):
    result = defaultdict(list)
    func_name = None
    for line in re.findall('def .+\w|(?<=return ).+', program_string):
       if line.startswith('def '):
           func_name = line[4:]
    return result

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.