Beispiel #1
0
def test_dataflow_primitive_assignment(graph: DataflowGraph) -> None:
    x: AssignableNodeReference = get_dataflow_node(graph, "x")
    statement: Statement = Statement()
    x.assign(ValueNode(42).reference(), statement, graph)
    assert isinstance(x, DirectNodeReference)
    assert len(x.node.value_assignments) == 1
    assignment: Assignment[ValueNodeReference] = x.node.value_assignments[0]
    assert assignment.lhs == x.node
    assert assignment.rhs.node == ValueNode(42)
    assert assignment.responsible == statement
    assert assignment.context == graph
Beispiel #2
0
 def _consume_token_rhs_element(
         self) -> Tuple[Optional[NodeReference], Optional[str]]:
     instance_id: Optional[str] = self._consume_token_instance()
     if instance_id is not None:
         if self._consume_token_attribute() is not None:
             raise Exception(
                 "Syntax error: this simple language only supports attributes directly on instances in the lhs."
             )
         if instance_id not in self._instances:
             return (None, instance_id)
         return (self._instances[instance_id].reference(), None)
     else:
         token: str = self._tokens.pop(0)
         if not token.isalnum():
             raise Exception(
                 "Invalid syntax: expected `variable_name [. attr [...]]` or `<instance> instance_id`, got `%s`"
                 % token)
         try:
             return (ValueNode(int(token)).reference(), None)
         except ValueError:
             node_ref: AssignableNodeReference = get_dataflow_node(
                 self.get_graph(), token)
             assert isinstance(node_ref, VariableNodeReference)
             attribute_name: Optional[str] = self._consume_token_attribute()
             while attribute_name is not None:
                 node_ref = AttributeNodeReference(node_ref, attribute_name)
                 attribute_name = self._consume_token_attribute()
             return (node_ref, None)
Beispiel #3
0
def test_dataflow_tentative_attribute_propagation_on_equivalence(
        graph: DataflowGraph) -> None:
    x: AssignableNodeReference = get_dataflow_node(graph, "x")
    y: AssignableNodeReference = get_dataflow_node(graph, "y")
    z: AssignableNodeReference = get_dataflow_node(graph, "z")

    x.assign(y, Statement(), graph)
    y.assign(z, Statement(), graph)
    z.assign(x, Statement(), graph)

    x_n: AssignableNodeReference = get_dataflow_node(graph, "x.n")
    x_n.assign(ValueNode(42).reference(), Statement(), graph)

    assert isinstance(y, VariableNodeReference)
    assert len(y.node.instance_assignments) == 0

    y.assign(create_instance().reference(), Statement(), graph)

    assert len(y.node.instance_assignments) == 1
    y_n: Optional[AttributeNode] = y.node.instance_assignments[0].rhs.node(
    ).get_attribute("n")
    assert y_n is not None

    assert len(y_n.value_assignments) == 1
    assert y_n.value_assignments[0].rhs.node.value == 42
Beispiel #4
0
def test_dataflow_tentative_attribute_propagation(
        graph: DataflowGraph) -> None:
    x: AssignableNodeReference = get_dataflow_node(graph, "x")
    y: AssignableNodeReference = get_dataflow_node(graph, "y")
    z: AssignableNodeReference = get_dataflow_node(graph, "z")

    x.assign(y, Statement(), graph)
    y.assign(z, Statement(), graph)

    x_a_n: AssignableNodeReference = get_dataflow_node(graph, "x.a.n")
    x_a_n.assign(ValueNode(42).reference(), Statement(), graph)

    def assert_tentative_a_n(var: AssignableNode,
                             values: Optional[Set[int]] = None) -> None:
        if values is None:
            values = {42}
        instance: Optional[InstanceNode] = var.equivalence.tentative_instance
        assert instance is not None
        a: Optional[AttributeNode] = instance.get_attribute("a")
        assert a is not None
        instance2: Optional[InstanceNode] = a.equivalence.tentative_instance
        assert instance2 is not None
        n: Optional[AttributeNode] = instance2.get_attribute("n")
        assert n is not None
        assert len(n.value_assignments) == len(values)
        assert {
            assignment.rhs.node.value
            for assignment in n.value_assignments
        } == values

    assert isinstance(z, VariableNodeReference)
    assert_tentative_a_n(z.node)

    u: AssignableNodeReference = get_dataflow_node(graph, "u")
    v: AssignableNodeReference = get_dataflow_node(graph, "v")

    u.assign(v, Statement(), graph)
    z.assign(u, Statement(), graph)

    assert isinstance(z, VariableNodeReference)
    assert z.node.equivalence.tentative_instance is None
    assert isinstance(v, VariableNodeReference)
    assert_tentative_a_n(v.node)

    x_a_n.assign(ValueNode(0).reference(), Statement(), graph)
    assert_tentative_a_n(v.node, {0, 42})
def test_dataflow_index_nodes(graph: DataflowGraph) -> None:
    entity: Entity = Entity("DummyEntity", Namespace("dummy_namespace"))
    i1: InstanceNode = create_instance(graph, entity)
    i2: InstanceNode = create_instance(graph, entity)

    i1.register_attribute("n").assign(
        ValueNode(0).reference(), Statement(), graph)
    i1.register_attribute("n").assign(
        ValueNode(0).reference(), Statement(), graph)

    x: AssignableNodeReference = get_dataflow_node(graph, "x")
    y: AssignableNodeReference = get_dataflow_node(graph, "y")

    x.assign(i1.reference(), Statement(), graph)
    y.assign(i2.reference(), Statement(), graph)

    graph.add_index_match([i.reference() for i in [i1, i2]])

    x_n: AssignableNodeReference = get_dataflow_node(graph, "x.n")
    y_n: AssignableNodeReference = get_dataflow_node(graph, "y.n")

    assert set(x_n.nodes()) == set(y_n.nodes())
Beispiel #6
0
def test_attribute_assignment(graph: DataflowGraph, instantiate: bool) -> None:
    x: AssignableNodeReference = get_dataflow_node(graph, "x")
    x_n: AssignableNodeReference = get_dataflow_node(graph, "x.n")

    if instantiate:
        x.assign(create_instance().reference(), Statement(), graph)
    x_n.assign(ValueNode(42).reference(), Statement(), graph)

    assert isinstance(x, VariableNodeReference)
    instance: InstanceNode
    if instantiate:
        assert x.node.equivalence.tentative_instance is None
        assert len(x.node.instance_assignments) == 1
        instance = x.node.instance_assignments[0].rhs.node()
    else:
        assert x.node.equivalence.tentative_instance is not None
        instance = x.node.equivalence.tentative_instance

    n: Optional[AttributeNode] = instance.get_attribute("n")
    assert n is not None
    assert len(n.value_assignments) == 1
    assert n.value_assignments[0].rhs == ValueNode(42).reference()
Beispiel #7
0
def test_dataflow_attribute_reference_nodes(graph: DataflowGraph) -> None:
    x: AssignableNodeReference = get_dataflow_node(graph, "x")
    y: AssignableNodeReference = get_dataflow_node(graph, "y")
    x.assign(y, Statement(), graph)
    y.assign(create_instance().reference(), Statement(), graph)

    assert isinstance(y, VariableNodeReference)
    assert len(y.node.instance_assignments) == 1

    y_n: AssignableNodeReference = get_dataflow_node(graph, "y.n")
    y_n.assign(ValueNode(42).reference(), Statement(), graph)

    x_n: AssignableNodeReference = get_dataflow_node(graph, "x.n")
    x_n_nodes: List[AssignableNode] = list(x_n.nodes())
    assert len(x_n_nodes) == 1
    assert x_n_nodes[0] == y.node.instance_assignments[0].rhs.node(
    ).get_attribute("n")
Beispiel #8
0
def test_dataflow_variable_loop_with_value_assignment_leaves(
        graph: DataflowGraph) -> None:
    x: AssignableNodeReference = get_dataflow_node(graph, "x")
    y: AssignableNodeReference = get_dataflow_node(graph, "y")
    z: AssignableNodeReference = get_dataflow_node(graph, "z")

    x.assign(y, Statement(), graph)
    y.assign(z, Statement(), graph)
    z.assign(x, Statement(), graph)

    y.assign(ValueNode(42).reference(), Statement(), graph)

    leaves: Set[AssignableNode] = set(x.leaf_nodes())
    assert isinstance(x, DirectNodeReference)
    assert isinstance(y, DirectNodeReference)
    assert isinstance(z, DirectNodeReference)
    assert leaves == {y.node}
Beispiel #9
0
def test_dataflow_tentative_attribute_propagation_over_uninitialized_attribute(
        graph: DataflowGraph) -> None:
    x_y: AssignableNodeReference = get_dataflow_node(graph, "x.y")
    u_n: AssignableNodeReference = get_dataflow_node(graph, "u.n")
    y: AssignableNodeReference = get_dataflow_node(graph, "y")
    u: AssignableNodeReference = get_dataflow_node(graph, "u")

    u_n.assign(ValueNode(42).reference(), Statement(), graph)
    x_y.assign(y, Statement(), graph)
    u.assign(x_y, Statement(), graph)

    assert isinstance(y, VariableNodeReference)
    instance: Optional[InstanceNode] = y.node.equivalence.tentative_instance
    assert instance is not None
    n: Optional[AttributeNode] = instance.get_attribute("n")
    assert n is not None
    assert len(n.value_assignments) == 1
    assert n.value_assignments[0].rhs.node.value == 42
def test_dataflow_model_primitive_double_assignment_responsible(
        dataflow_test_helper: DataflowTestHelper) -> None:
    dataflow_test_helper.compile(
        """
x = 42
x = 0
        """,
        DoubleSetException,
    )
    graph: DataflowGraph = dataflow_test_helper.get_graph()
    x: AssignableNodeReference = get_dataflow_node(graph, "x")
    assert isinstance(x, VariableNodeReference)
    assignments: List[Assignment] = x.node.value_assignments
    assert len(assignments) == 2
    zero_index: int = [assignment.rhs for assignment in assignments
                       ].index(ValueNode(0).reference())
    for i, assignment in enumerate(assignments):
        value: int = 0 if i == zero_index else 42
        assert assignment.context == graph
        assert isinstance(assignment.responsible, Assign)
        assert assignment.responsible.name == "x"
        assert isinstance(assignment.responsible.value, Literal)
        assert assignment.responsible.value.value == value
Beispiel #11
0
def test_slots_dataflow():
    namespace: Namespace = Namespace("root", None)
    resolver: Resolver = Resolver(namespace)

    graph: DataflowGraph = DataflowGraph(resolver)
    assignable_node: AssignableNode = AssignableNode("node")
    value_node: ValueNode = ValueNode(42)
    instance_node: InstanceNode = InstanceNode([])

    assert_slotted(graph)
    assert_slotted(assignable_node)
    assert_slotted(assignable_node.equivalence)
    assert_slotted(value_node)
    assert_slotted(instance_node)

    assert_slotted(AttributeNodeReference(assignable_node.reference(), "attr"))
    assert_slotted(VariableNodeReference(assignable_node))
    assert_slotted(ValueNodeReference(value_node))
    assert_slotted(InstanceNodeReference(instance_node))
    assert_slotted(
        Assignment(assignable_node.reference(), value_node, Statement(),
                   graph))
    assert_slotted(NodeStub("stub"))
    assert_slotted(AttributeNode(instance_node, "attr"))
Beispiel #12
0

def test_dataflow_variable_chain_leaf(graph: DataflowGraph) -> None:
    x: AssignableNodeReference = get_dataflow_node(graph, "x")
    y: AssignableNodeReference = get_dataflow_node(graph, "y")
    z: AssignableNodeReference = get_dataflow_node(graph, "z")

    x.assign(y, Statement(), graph)
    y.assign(z, Statement(), graph)

    leaves: Set[AssignableNode] = set(x.leaf_nodes())
    assert isinstance(z, DirectNodeReference)
    assert leaves == {z.node}


@pytest.mark.parametrize("value_node", [ValueNode(42), create_instance()])
def test_dataflow_variable_tree_leaves(graph: DataflowGraph,
                                       value_node: Node) -> None:
    x: AssignableNodeReference = get_dataflow_node(graph, "x")
    y: AssignableNodeReference = get_dataflow_node(graph, "y")
    z: AssignableNodeReference = get_dataflow_node(graph, "z")

    x.assign(y, Statement(), graph)
    y.assign(z, Statement(), graph)
    y.assign(value_node.reference(), Statement(), graph)

    leaves: Set[AssignableNode] = set(x.leaf_nodes())
    assert isinstance(y, DirectNodeReference)
    assert isinstance(z, DirectNodeReference)
    assert leaves == {y.node, z.node}
Beispiel #13
0
    Node,
    NodeReference,
    ValueNode,
)


def entity_instance(entity: str) -> InstanceNode:
    node: InstanceNode = InstanceNode([])
    node.entity = Entity(entity, Namespace("__config__", Namespace("__root_ns__")))
    return node


@pytest.mark.parametrize(
    "instance,expected_repr",
    [
        (ValueNode(42), "42"),
        (ValueNode("42"), "'42'"),
        (ValueNode(42).reference(), "42"),
        (ValueNode("Hello World!"), repr("Hello World!")),
        (AssignableNode("x"), "x"),
        (AssignableNode("x").reference(), "x"),
        (AttributeNodeReference(AttributeNodeReference(AssignableNode("x").reference(), "y"), "z"), "x.y.z"),
        (entity_instance("MyEntity"), "__config__::MyEntity instance"),
        (entity_instance("MyEntity").reference(), "__config__::MyEntity instance"),
        (AttributeNode(entity_instance("MyEntity"), "n"), "attribute n on __config__::MyEntity instance"),
    ],
)
def test_dataflow_repr(instance: Union[Node, NodeReference], expected_repr: str) -> None:
    assert repr(instance) == expected_repr
    assert str(instance) == expected_repr