예제 #1
0
def children_of_for_loop_are_checked():
    _assert_child_expression_is_checked(lambda generate:
        nodes.for_(
            nodes.attr(generate.unbound_ref(), "blah"),
            nodes.list_literal([]),
            [],
            []
        )
    )
    _assert_child_expression_is_checked(lambda generate:
        nodes.for_(
            generate.target(),
            generate.unbound_ref(),
            [],
            []
        ),
    )
    _assert_child_statement_is_checked(lambda generate:
        nodes.for_(
            generate.target(),
            nodes.list_literal([]),
            [generate.unbound_ref_statement()],
            []
        ),
    )
    _assert_child_statement_is_checked(lambda generate:
        nodes.for_(
            generate.target(),
            nodes.list_literal([]),
            [],
            [generate.unbound_ref_statement()],
        ),
    )
예제 #2
0
def for_loop_has_child_names_resolved():
    _assert_children_resolved(
        lambda ref: nodes.for_(ref, nodes.list_literal([]), [], []),
    )
    _assert_children_resolved(
        lambda ref: nodes.for_(nodes.ref("target"), ref, [], []),
        other_names=["target"]
    )
    _assert_children_resolved(
        lambda ref: nodes.for_(nodes.ref("target"), nodes.list_literal([]), [nodes.expression_statement(ref)], []),
        other_names=["target"]
    )
    _assert_children_resolved(
        lambda ref: nodes.for_(nodes.ref("target"), nodes.list_literal([]), [], [nodes.expression_statement(ref)]),
        other_names=["target"]
    )
예제 #3
0
def for_statement_target_can_be_supertype_of_iterable_element_type():
    ref_node = nodes.ref("xs")
    node = nodes.for_(nodes.subscript(nodes.ref("ys"), nodes.int_literal(0)), ref_node, [])
    
    update_context(node, type_bindings={
        "xs": types.list_type(types.int_type),
        "ys": types.list_type(types.object_type),
    })
예제 #4
0
def test_parse_for_loop_with_else_body():
    expected = nodes.for_(
        nodes.ref("x"), nodes.ref("xs"),
        [],
        [nodes.ret(nodes.ref("x"))],
    )
    
    _assert_statement_parse(expected, "for x in xs:\n  pass\nelse:\n  return x")
예제 #5
0
def declarations_in_both_body_and_else_body_of_for_loop_are_not_definitely_bound():
    _assert_name_is_not_definitely_bound(lambda generate:
        nodes.for_(
            generate.target(),
            nodes.list_literal([]),
            [generate.assignment()],
            [generate.assignment()]
        ),
    )
예제 #6
0
def for_statement_has_iterable_type_checked():
    ref_node = nodes.ref("xs")
    node = nodes.for_(nodes.ref("x"), ref_node, [])
    
    try:
        update_context(node)
        assert False, "Expected error"
    except errors.TypeCheckError as error:
        assert_equal(ref_node, error.node)
예제 #7
0
def else_body_of_for_loop_is_type_checked():
    assert_statement_is_type_checked(
        lambda bad_statement: nodes.for_(nodes.ref("x"), nodes.ref("xs"), [], [
            bad_statement
        ]),
        type_bindings={
            "xs": types.list_type(types.str_type),
        }
    )
예제 #8
0
def iter_method_must_take_no_arguments():
    cls = types.class_type("Blah")
    cls.attrs.add("__iter__", types.func([types.str_type], types.iterable(types.str_type)))
    ref_node = nodes.ref("xs")
    node = nodes.for_(nodes.ref("x"), ref_node, [])
    
    try:
        update_context(node, type_bindings={"x": None, "xs": cls})
        assert False, "Expected error"
    except errors.TypeCheckError as error:
        assert_equal(ref_node, ephemeral.root_node(error.node))
예제 #9
0
def for_statement_requires_iterable_to_have_iter_method():
    ref_node = nodes.ref("xs")
    node = nodes.for_(nodes.ref("x"), ref_node, [])
    
    try:
        update_context(node, type_bindings={"xs": types.int_type})
        assert False, "Expected error"
    except errors.UnexpectedValueTypeError as error:
        assert_equal(ref_node, error.node)
        assert_equal("iterable type", error.expected)
        assert_equal(types.int_type, error.actual)
예제 #10
0
def iter_method_must_return_iterator():
    cls = types.class_type("Blah")
    cls.attrs.add("__iter__", types.func([], types.iterable(types.str_type)))
    ref_node = nodes.ref("xs")
    node = nodes.for_(nodes.ref("x"), ref_node, [])
    
    try:
        update_context(node, type_bindings={"x": None, "xs": cls})
        assert False, "Expected error"
    except errors.BadSignatureError as error:
        assert_equal(ref_node, error.node)
예제 #11
0
def for_statement_target_can_be_variable():
    node = nodes.for_(nodes.ref("x"), nodes.ref("xs"), [])
    
    # Unassigned case
    update_context(node, type_bindings={
        "xs": types.list_type(types.str_type),
    })
    # Assigned case
    update_context(node, type_bindings={
        "x": types.str_type,
        "xs": types.list_type(types.str_type),
    })
예제 #12
0
def for_statement_accepts_iterable_with_iter_method():
    cls = types.class_type("Blah")
    cls.attrs.add("__iter__", types.func([], types.iterator(types.str_type)))
    
    node = nodes.for_(nodes.ref("x"), nodes.ref("xs"), [])
    
    type_bindings = {
        "xs": cls,
    }
    
    context = update_context(node, type_bindings=type_bindings)
    
    assert_equal(types.str_type, context.lookup_name("x"))
예제 #13
0
 def test_transform_for_loop(self):
     _assert_transform(
         nodes.for_(
             nodes.ref("x"),
             nodes.ref("xs"),
             [nodes.ret(nodes.ref("x"))],
         ),
         """
             var __nope_u_iterator0 = $builtins.iter(xs)
             var __nope_u_element1
             while True:
                 __nope_u_element1 = $builtins.next(__nope_u_iterator0, $internals.loop_sentinel)
                 if __nope_u_element1 is $internals.loop_sentinel:
                     break
                 x = __nope_u_element1
                 return x
         """
     )
예제 #14
0
def for_statement_target_cannot_be_strict_subtype_of_iterable_element_type():
    target_sequence_node = nodes.ref("ys")
    target_node = nodes.subscript(target_sequence_node, nodes.int_literal(0))
    iterable_node = nodes.ref("xs")
    node = nodes.for_(target_node, iterable_node, [])
    
    try:
        update_context(node, type_bindings={
            "xs": types.list_type(types.object_type),
            "ys": types.list_type(types.int_type),
        })
        assert False, "Expected error"
    except errors.UnexpectedTargetTypeError as error:
        assert_equal(target_sequence_node, ephemeral.root_node(error.node))
        assert_equal(
            ephemeral.FormalArg(ephemeral.attr(target_sequence_node, "__setitem__"), 1),
            ephemeral.underlying_node(error.node)
        )
        assert_equal(types.object_type, error.value_type)
        assert_equal(types.int_type, error.target_type)
예제 #15
0
def for_statement_requires_iterable_getitem_method_to_accept_integers():
    cls = types.class_type("Blah")
    cls.attrs.add("__getitem__", types.func([types.str_type], types.str_type))
    
    ref_node = nodes.ref("xs")
    node = nodes.for_(nodes.ref("x"), ref_node, [])
    
    type_bindings = {
        "xs": cls,
    }
    
    try:
        update_context(node, type_bindings=type_bindings)
        assert False, "Expected error"
    except errors.UnexpectedTargetTypeError as error:
        assert_equal(ref_node, ephemeral.root_node(error.node))
        assert_equal(
            ephemeral.FormalArg(ephemeral.attr(ref_node, "__getitem__"), 0),
            ephemeral.underlying_node(error.node)
        )
        assert_equal(types.int_type, error.value_type)
        assert_equal(types.str_type, error.target_type)
예제 #16
0
 def test_transform_for_loop_with_else_branch(self):
     _assert_transform(
         nodes.for_(
             nodes.ref("x"),
             nodes.ref("xs"),
             [nodes.ret(nodes.ref("x"))],
             [nodes.ret(nodes.ref("y"))],
         ),
         """
             var __nope_u_iterator0 = $builtins.iter(xs)
             var __nope_u_element1
             var __nope_u_normal_exit2 = False
             while True:
                 __nope_u_element1 = $builtins.next(__nope_u_iterator0, $internals.loop_sentinel)
                 if __nope_u_element1 is $internals.loop_sentinel:
                     __nope_u_normal_exit2 = True
                     break
                 x = __nope_u_element1
                 return x
             if __nope_u_normal_exit2:
                 return y
         """
     )
예제 #17
0
def break_is_valid_in_for_loop_body():
    node = nodes.for_(nodes.ref("x"), nodes.ref("xs"), [nodes.break_()])
    check_loop_control(node, False)
예제 #18
0
def test_parse_for_loop():
    expected = nodes.for_(nodes.ref("x"), nodes.ref("xs"), [nodes.ret(nodes.ref("x"))])
    
    _assert_statement_parse(expected, "for x in xs:\n  return x")
예제 #19
0
def for_loop_target_is_defined_but_not_definitely_bound():
    _assert_name_is_not_definitely_bound(lambda generate:
        nodes.for_(generate.target(), nodes.list_literal([]), [], [])
    )
예제 #20
0
def for_loop_target_is_declared():
    node = nodes.for_(nodes.ref("target"), nodes.list_literal([]), [], [])
    declarations = find_declarations(node)
    assert_equal("target", declarations.declaration("target").name)
    assert isinstance(declarations.declaration("target"), name_declaration.VariableDeclarationNode)