'''Gain access to the code objects of inner functions for testing purposes.'''
import types

def free_var(val):
    '''A function that wraps free variables.'''
    def nested():
        return val
    return nested.__closure__[0]

def nested(outer, inner_name, **free_vars):
    '''Find the code object of an inner function and return it as a callable object.
    
    Arguments:
        outer (function or method): A function object with an inner function.
        inner_name (str): The name of the inner function we want access to
        **free_vars (dict(str: any)): A dictionary with values for the free
            variables in the context of the inner function.
    Returns:
        A function object for the inner function, with context variables set.
    '''
    if isinstance(outer, (types.FunctionType, types.MethodType)):
        outer = outer.__code__
    for const in outer.co_consts:
        if isinstance(const, types.CodeType) and const.co_name == inner_name:
            return types.FunctionType(const, globals(), None, None, tuple(
                free_var(free_vars[name]) for name in const.co_freevars))