Search code examples
pythonfunctionintrospectionhigher-order-functionsinspect

Python function introspection: what members of a class passed as argument are mentioned inside it?


Say that I have a function like the following:

def eggs(a,b,c):
    if c.foo:
        return a + b.bar
    else:
        return c.spam

I'd like to have a higher order function capable of introspecting the function passed and retrieve what members of an argument are mentioned inside the code via the dot syntax, with the following behavior:

>>> member_inspector(eggs, 'c')
('foo','spam')

>>> member_inspector(eggs, 'b')
('bar')

>>> member_inspector(eggs, 'a')
()

Can this be done? How?


Solution

  • Here's a basic version:

    import inspect
    from textwrap import dedent
    import ast
    
    def member_inspector(f, var):
        source = dedent(inspect.getsource(f))
        module = ast.parse(source)
        func = module.body[0]
        result = []
        for stmt in func.body:
            for node in ast.walk(stmt):
                if (isinstance(node, ast.Attribute) and
                        isinstance(node.value, ast.Name) and
                        node.value.id == var):
                    result.append(node.attr)
        return result