def test_parse_functions():
    """Test that the body of the function is retrieved correctly."""
    code = '''
x = 5
def foo():
    print('hello')
    print(x)
    '''

    target = {"foo": "def foo():\n    print('hello')\n    print(x)\n"}
    assert kale_ast.parse_functions(code) == target
예제 #2
0
파일: dependencies.py 프로젝트: sylus/kale
def detect_fns_free_variables(source_code,
                              imports_and_functions="",
                              step_parameters=None):
    """Return the function's free variables.

    Free variable: _If a variable is used in a code block but not defined
    there, it is a free variable._

    An Example:

    ```
    x = 5
    def foo():
        print(x)
    ```

    In the example above, `x` is a free variable for function `foo`, because
    it is defined outside of the context of `foo`.

    Here we run the PyFlakes report over the function body to get all the
    missing names (i.e. free variables), excluding the function arguments.

    Args:
        source_code: Multiline Python source code
        imports_and_functions: Multiline Python source that is prepended
            to every pipeline step. It should contain the code cells that
            where tagged as `import` and `functions`. We prepend this code to
            the function body because it will always be present in any pipeline
            step.
        step_parameters: Step parameters names. The step parameters
            are removed from the pyflakes report, as these names will always
            be available in the step's context.

    Returns (dict): A dictionary with the name of the function as key and
        a list of variables names + consumed pipeline parameters as values.
    """
    fns_free_vars = dict()
    # now check the functions' bodies for free variables. fns is a
    # dict function_name -> function_source
    fns = kale_ast.parse_functions(source_code)
    for fn_name, fn in fns.items():
        code = imports_and_functions + "\n" + fn
        free_vars = pyflakes_report(code=code)
        # the pipeline parameters that are used in the function
        consumed_params = {}
        if step_parameters:
            consumed_params = free_vars.intersection(step_parameters.keys())
            # remove the used parameters form the free variables, as they
            # need to be handled differently.
            free_vars.difference_update(consumed_params)
        fns_free_vars[fn_name] = (free_vars, consumed_params)
    return fns_free_vars