예제 #1
0
def attributes_assigned_in_init_can_be_used_outside_of_class():
    init_func = nodes.func(
        name="__init__",
        args=nodes.args([nodes.arg("self_init")]),
        body=[
            nodes.assign(
                [nodes.attr(nodes.ref("self_init"), "message")],
                nodes.str_literal("Hello"),
                type=nodes.ref("str"),
            )
        ],
        type=nodes.signature(
            args=[nodes.signature_arg(nodes.ref("Self"))],
            returns=nodes.ref("none")
        )
    )
    class_node = nodes.class_("User", [init_func])
    
    node = [
        class_node,
        nodes.assign([nodes.ref("x")], nodes.attr(nodes.call(nodes.ref("User"), []), "message")),
    ]
    
    context = _update_context(node, declared_names_in_node=NodeDict([
        (class_node, ["Self", "__init__"]),
        (init_func, ["self_init"]),
    ]))
    
    assert_equal(types.str_type, context.lookup_name("x"))
예제 #2
0
def attributes_assigned_in_init_can_be_used_in_methods_when_init_method_is_defined_after_other_method():
    init_func = nodes.func(
        name="__init__",
        args=nodes.args([nodes.arg("self_init")]),
        body=[
            nodes.assign(
                [nodes.attr(nodes.ref("self_init"), "message")],
                nodes.str_literal("Hello"),
                type=nodes.ref("str"),
            )
        ],
        type=nodes.signature(
            args=[nodes.signature_arg(nodes.ref("Self"))],
            returns=nodes.ref("none")
        ),
    )
    node = nodes.class_("User", [
        nodes.func(
            name="g",
            args=nodes.args([nodes.arg("self_g")]),
            body=[nodes.ret(nodes.attr(nodes.ref("self_g"), "message"))],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("Self"))],
                returns=nodes.ref("str")
            ),
        ),
        init_func,
    ])
    _infer_class_type(node, ["__init__", "g"], [(init_func, ["self_init"])])
예제 #3
0
def method_can_call_method_on_same_instance_defined_later_in_body():
    node = nodes.class_("User", [
        nodes.func(
            name="f",
            args=nodes.args([nodes.arg("self_f")]),
            body=[
                nodes.ret(nodes.call(nodes.attr(nodes.ref("self_f"), "g"), []))
            ],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("Self"))],
                returns=nodes.ref("none")
            ),
        ),
        nodes.func(
            name="g",
            args=nodes.args([nodes.arg("self_g")]),
            body=[
                nodes.ret(nodes.call(nodes.attr(nodes.ref("self_g"), "f"), []))
            ],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("Self"))],
                returns=nodes.ref("none")
            ),
        )
    ])
    _infer_class_type(node, ["f", "g"])
예제 #4
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()],
        ),
    )
예제 #5
0
def init_method_cannot_call_other_methods():
    node = nodes.class_("User", [
        nodes.func(
            name="__init__",
            args=nodes.args([nodes.arg("self_init")]),
            body=[
                nodes.assign([nodes.ref("x")], nodes.call(nodes.attr(nodes.ref("self_init"), "g"), []))
            ],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("Self"))],
                returns=nodes.ref("none")
            ),
        ),
        nodes.func(
            name="g",
            args=nodes.args([nodes.arg("self_g")]),
            body=[],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("Self"))],
                returns=nodes.ref("none")
            ),
        ),
    ])
    try:
        _infer_class_type(node, ["__init__", "g"])
        assert False, "Expected error"
    except errors.InitMethodCannotGetSelfAttributes as error:
        assert_equal("__init__ methods cannot get attributes of self", str(error))
예제 #6
0
def operands_of_sub_operation_must_support_sub():
    type_bindings = {"x": types.none_type, "y": types.none_type}
    subtraction = nodes.sub(nodes.ref("x"), nodes.ref("y"))
    try:
        infer(subtraction, type_bindings=type_bindings)
        assert False, "Expected error"
    except errors.NoSuchAttributeError as error:
        assert_equal(nodes.attr(subtraction.left, "__sub__"), error.node)
예제 #7
0
def type_error_if_attribute_does_not_exist():
    type_bindings = {"x": types.str_type}
    node = nodes.attr(nodes.ref("x"), "swizzlify")
    try:
        infer(node, type_bindings=type_bindings)
        assert False, "Expected error"
    except errors.NoSuchAttributeError as error:
        assert_equal("'str' object has no attribute 'swizzlify'", str(error))
        assert error.node is node
예제 #8
0
def operands_of_add_operation_must_support_add():
    type_bindings = {"x": types.none_type, "y": types.none_type}
    addition = nodes.add(nodes.ref("x"), nodes.ref("y"))
    try:
        infer(addition, type_bindings=type_bindings)
        assert False, "Expected error"
    except errors.NoSuchAttributeError as error:
        assert_equal(nodes.attr(addition.left, "__add__"), error.node)
        assert_equal(addition.left, ephemeral.root_node(error.node))
예제 #9
0
def list_comprehension_has_child_names_resolved():
    _assert_children_resolved(
        lambda ref: nodes.list_comprehension(ref, nodes.none(), nodes.none()),
    )
    _assert_children_resolved(
        lambda ref: nodes.list_comprehension(nodes.none(), nodes.attr(ref, "name"), nodes.none()),
    )
    _assert_children_resolved(
        lambda ref: nodes.list_comprehension(nodes.none(), nodes.none(), ref),
    )
예제 #10
0
def context_manager_of_with_statement_must_have_exit_method():
    cls = types.class_type("Manager", [types.attr("__enter__", enter_method())])
    context_manager_node = nodes.ref("x")
    node = nodes.with_(context_manager_node, None, [])

    try:
        update_context(node, type_bindings={"x": cls})
        assert False, "Expected error"
    except errors.NoSuchAttributeError as error:
        assert_equal(nodes.attr(context_manager_node, "__exit__"), error.node)
예제 #11
0
def declarations_in_list_comprehension_are_variable_reference_targets():
    node = nodes.list_comprehension(
        nodes.none(),
        nodes.tuple_literal([nodes.ref("target"), nodes.attr(nodes.ref("other"), "name")]),
        nodes.ref("iterable")
    )
    
    declarations = _declarations_in(node)
    assert isinstance(declarations.declaration("target"), name_declaration.VariableDeclarationNode)
    assert not declarations.is_declared("other")
    assert not declarations.is_declared("iterable")
예제 #12
0
def cannot_reassign_read_only_attribute():
    cls = types.class_type("X", [types.attr("y", types.str_type, read_only=True)])
    
    attr_node = nodes.attr(nodes.ref("x"), "y")
    node = nodes.assign([attr_node], nodes.str_literal("Hello"))
    type_bindings = {"x": cls}
    try:
        update_context(node, type_bindings=type_bindings)
        assert False, "Expected error"
    except errors.ReadOnlyAttributeError as error:
        assert_equal(attr_node, error.node)
        assert_equal("'X' attribute 'y' is read-only", str(error))
예제 #13
0
def assignment_to_attribute_does_not_allow_strict_supertype():
    cls = types.class_type("X", [types.attr("y", types.str_type, read_only=True)])
    
    attr_node = nodes.attr(nodes.ref("x"), "y")
    node = nodes.assign([attr_node], nodes.ref("obj"))
    type_bindings = {"x": cls, "obj": types.object_type}
    try:
        update_context(node, type_bindings=type_bindings)
        assert False, "Expected error"
    except errors.UnexpectedTargetTypeError as error:
        assert_equal(attr_node, error.node)
        assert_equal(types.object_type, error.value_type)
        assert_equal(types.str_type, error.target_type)
예제 #14
0
def can_assign_literal_to_attribute():
    init_func = nodes.func(
        name="__init__",
        args=nodes.args([nodes.arg("self")]),
        body=[
            nodes.assign(
                [nodes.attr(nodes.ref("self"), "value")],
                nodes.none(),
            )
        ],
        type=_no_arg_init_signature,
    )
    node = nodes.class_("Box", [
        init_func
    ])
    class_type = _infer_class_type(
            node,
            ["__init__"],
            [(init_func, ["self"])])
    assert_equal(types.none_type, class_type.attrs.type_of("value"))
예제 #15
0
def error_is_raised_if_attribute_assignment_has_no_explicit_and_not_literal_nor_argument_value():
    init_func = nodes.func(
        name="__init__",
        args=nodes.args([nodes.arg("self")]),
        body=[
            nodes.assign(
                [nodes.attr(nodes.ref("self"), "message")],
                nodes.ref("message"),
            )
        ],
        type=_no_arg_init_signature,
    )
    node = nodes.class_("User", [
        init_func
    ])
    error = assert_raises(errors.ClassAttributeTypeError,
        lambda: _infer_class_type(
            node,
            ["__init__"],
            [(init_func, ["self"])],
            type_bindings={"message": types.str_type}))
    assert_equal("Could not infer type of attribute. Attribute assignments must be explicitly typed, or a literal, or an argument", str(error))
예제 #16
0
def can_assign_any_value_to_attribute_if_assignment_is_explicitly_typed():
    init_func = nodes.func(
        name="__init__",
        args=nodes.args([nodes.arg("self")]),
        body=[
            nodes.assign(
                [nodes.attr(nodes.ref("self"), "message")],
                nodes.ref("message"),
                type=nodes.ref("str"),
            )
        ],
        type=_no_arg_init_signature,
    )
    node = nodes.class_("User", [
        init_func
    ])
    class_type = _infer_class_type(
            node,
            ["__init__"],
            [(init_func, ["self"])],
            type_bindings={"message": types.str_type})
    assert_equal(types.str_type, class_type.attrs.type_of("message"))
예제 #17
0
def children_of_list_comprehension_are_checked():
    _assert_child_expression_is_checked(lambda generate:
        nodes.list_comprehension(
            generate.unbound_ref(),
            generate.bound_ref("x", types.int_type),
            nodes.list_literal([]),
        )
    )
    _assert_child_expression_is_checked(lambda generate:
        nodes.list_comprehension(
            nodes.none(),
            nodes.attr(generate.unbound_ref(), "x"),
            nodes.list_literal([]),
        )
    )
    _assert_child_expression_is_checked(lambda generate:
        nodes.list_comprehension(
            nodes.none(),
            generate.bound_ref("x", types.int_type),
            generate.unbound_ref(),
        )
    )
예제 #18
0
def children_of_try_statement_are_checked():
    _assert_child_statement_is_checked(lambda generate:
        nodes.try_([generate.unbound_ref_statement()]),
    )
    _assert_child_statement_is_checked(lambda generate:
        nodes.try_([], handlers=[
            nodes.except_(None, None, [generate.unbound_ref_statement()])
        ]),
    )
    _assert_child_expression_is_checked(lambda generate:
        nodes.try_([], handlers=[
            nodes.except_(generate.unbound_ref(), None, [])
        ]),
    )
    _assert_child_expression_is_checked(lambda generate:
        nodes.try_([], handlers=[
            nodes.except_(nodes.none(), nodes.attr(generate.unbound_ref(), "blah"), [])
        ]),
    )
    _assert_child_statement_is_checked(lambda generate:
        nodes.try_([], finally_body=[
            generate.unbound_ref_statement()
        ]),
    )
예제 #19
0
def children_of_with_statement_are_checked():
    context_manager_type = context_manager_class(exit_type=types.none_type)
    
    _assert_child_expression_is_checked(lambda generate:
        nodes.with_(
            generate.unbound_ref(),
            None,
            []
        ),
    )
    _assert_child_expression_is_checked(lambda generate:
        nodes.with_(
            generate.bound_ref("manager", context_manager_type),
            nodes.attr(generate.unbound_ref(), "blah"),
            []
        ),
    )
    _assert_child_statement_is_checked(lambda generate:
        nodes.with_(
            generate.bound_ref("manager", context_manager_type),
            None,
            [generate.unbound_ref_statement()]
        ),
    )
예제 #20
0
def can_infer_type_of_attribute():
    type_bindings = {"x": types.str_type}
    assert_equal(
        types.func([types.str_type], types.int_type),
        infer(nodes.attr(nodes.ref("x"), "find"), type_bindings=type_bindings),
    )
예제 #21
0
def attribute_access_has_child_names_resolved():
    _assert_children_resolved(
        lambda ref: nodes.attr(ref, "blah"),
    )
예제 #22
0
def test_attribute_access():
    expected = nodes.attr(nodes.ref("x"), "y")
    _assert_expression_parse(expected, "x.y")
예제 #23
0
def targets_are_evaluated_left_to_right():
    target_node = nodes.ref("x")
    ref_node = nodes.ref("x")
    node = nodes.assign([nodes.attr(ref_node, "blah"), target_node], nodes.none())
    
    _assert_is_unbound_error(ref_node, lambda: _updated_bindings(node))
예제 #24
0
def assignment_to_attribute_allows_subtype():
    cls = types.class_type("X", [types.attr("y", types.object_type, read_only=False)])
    
    node = nodes.assign([nodes.attr(nodes.ref("x"), "y")], nodes.str_literal("Hello"))
    type_bindings = {"x": cls}
    update_context(node, type_bindings=type_bindings)