Exemplo n.º 1
0
def forward_transfer(gen_sym, in_env, statement):

    if isinstance(statement, ast.Assign):
        target = statement.targets[0].id
        result, gen_sym = peval_expression(statement.value, gen_sym, in_env.known_values())

        new_values=dict(in_env.values)

        for name in result.mutated_bindings:
            new_values[name] = Value(undefined=True)

        if result.fully_evaluated:
            new_value = Value(value=result.value)
        else:
            new_value = Value(undefined=True)
        new_values[target] = new_value

        out_env = Environment(values=new_values)
        new_exprs = [CachedExpression(path=['value'], node=result.node)]

        return gen_sym, out_env, new_exprs, result.temp_bindings

    elif isinstance(statement, (ast.Expr, ast.Return)):
        result, gen_sym = peval_expression(statement.value, gen_sym, in_env.known_values())

        new_values=dict(in_env.values)

        for name in result.mutated_bindings:
            new_values[name] = Value(undefined=True)

        new_exprs = [CachedExpression(path=['value'], node=result.node)]
        out_env = Environment(values=new_values)

        return gen_sym, out_env, new_exprs, result.temp_bindings

    elif isinstance(statement, ast.If):
        result, gen_sym = peval_expression(statement.test, gen_sym, in_env.known_values())

        new_values=dict(in_env.values)

        for name in result.mutated_bindings:
            new_values[name] = Value(undefined=True)

        out_env = Environment(values=new_values)

        new_exprs = [CachedExpression(path=['test'], node=result.node)]

        return gen_sym, out_env, new_exprs, result.temp_bindings

    else:
        return gen_sym, in_env, [], {}
Exemplo n.º 2
0
def check_peval_expression(source, bindings, expected_source,
        fully_evaluated=False, expected_value=None, expected_temp_bindings=None):

    source_tree = expression_ast(source)

    # In some cases we need to enforce the expected node,
    # because it cannot be obtained by parsing
    # (e.g. "-5" is parsed as "UnaryOp(op=USub(), Num(n=5))", not as "Num(n=-5)").
    # But we expect the latter from a fully evaluated expression.
    if isinstance(expected_source, str):
        expected_tree = expression_ast(expected_source)
    else:
        expected_tree = expected_source

    gen_sym = GenSym()
    result, gen_sym = peval_expression(source_tree, gen_sym, bindings)

    assert_ast_equal(result.node, expected_tree)

    assert result.fully_evaluated == fully_evaluated
    if fully_evaluated:
        assert result.value == expected_value

    if expected_temp_bindings is not None:
        for key, val in expected_temp_bindings.items():
            assert key in result.temp_bindings
            assert result.temp_bindings[key] == expected_temp_bindings[key]
Exemplo n.º 3
0
def test_generator_exp():

    # Need to do this manually, since we can't compare generator expressions
    # without changing their state.

    source_tree = expression_ast("(x + 1 for x in range(a))")
    expected_tree = expression_ast("__peval_temp_2")
    bindings = dict(a=10, range=range)

    gen_sym = GenSym()
    result, gen_sym = peval_expression(source_tree, gen_sym, bindings)

    assert_ast_equal(result.node, expected_tree)
    assert result.fully_evaluated

    expected_genexp = (x + 1 for x in range(10))

    assert type(result.value) == type(expected_genexp)
    assert list(result.value) == list(expected_genexp)

    # Since the binding contained the reference to the same genexp,
    # and we destroyed it, we need to do the evaluation again
    # in order to check the binding as well

    gen_sym = GenSym()
    result, gen_sym = peval_expression(source_tree, gen_sym, bindings)

    expected_genexp = (x + 1 for x in range(10))

    assert '__peval_temp_2' in result.temp_bindings
    binding = result.temp_bindings['__peval_temp_2']
    assert type(binding) == type(expected_genexp)
    assert list(binding) == list(expected_genexp)


    check_peval_expression(
        '(x + 1 for x in range(a))', dict(a=10), '(x + 1 for x in range(10))')