示例#1
0
 def test_stack_frame_basic(self):
     plan = uberjob.Plan()
     stack_frame = get_stack_frame(1)
     x = plan.call(operator.truediv, 1, 0)
     with self.assert_call_exception(
         expected_stack_frame=copy_with_line_offset(stack_frame, 1)
     ):
         uberjob.run(plan, output=x)
示例#2
0
 def test_stack_frame_registry_add(self):
     plan = uberjob.Plan()
     registry = uberjob.Registry()
     x = plan.call(operator.add, 2, 2)
     stack_frame = get_stack_frame(1)
     registry.add(x, TestStore(can_write=False))
     with self.assert_call_exception(
             expected_stack_frame=copy_with_line_offset(stack_frame, 1)):
         uberjob.run(plan, registry=registry, output=x)
示例#3
0
 def test_stack_frame_registry_source(self):
     plan = uberjob.Plan()
     registry = uberjob.Registry()
     stack_frame = get_stack_frame(1)
     x = registry.source(plan, TestStore())
     with self.assert_call_exception(
             expected_stack_frame=copy_with_line_offset(stack_frame, 1)):
         uberjob.run(plan, output=x)
     with self.assert_call_exception(
             expected_stack_frame=copy_with_line_offset(stack_frame, 1)):
         uberjob.run(plan, registry=registry, output=x)
示例#4
0
    def add(self, node: Node, value_store: ValueStore) -> None:
        """
        Assign a :class:`~uberjob.graph.Node` to a :class:`~uberjob.ValueStore`.

        :param node: The plan node.
        :param value_store: The value store for the node.
        """
        validation.assert_is_instance(node, "node", Node)
        validation.assert_is_instance(value_store, "value_store", ValueStore)
        if node in self.mapping:
            raise Exception("The node already has a value store.")
        self.mapping[node] = RegistryValue(value_store,
                                           is_source=False,
                                           stack_frame=get_stack_frame())
示例#5
0
    def gather(self, value) -> Node:
        """
        Gather a structured value that may contain instances of :class:`~uberjob.graph.Node` into a single
        :class:`~uberjob.graph.Node` representing the entire structured value.

        If the value is already a :class:`~uberjob.graph.Node`, it will be returned unchanged.

        When navigating the structured value, gather will only recognize Python's general purpose built-in containers:
        :class:`dict`, :class:`list`, :class:`set`, and :class:`tuple`.

        :param value: A structured value that may contain instances of :class:`~uberjob.graph.Node`.
        :return: A single :class:`~uberjob.graph.Node` representing the gathered input value.
        """
        return self._gather(get_stack_frame(), value)
示例#6
0
    def call(self, fn: Callable, *args, **kwargs) -> Call:
        """
        Add a function call to this :class:`~uberjob.Plan`.

        Non-symbolic arguments are automatically converted to symbolic arguments using :func:`~uberjob.Plan.gather`.

        :param fn: The function to be called.
        :param args: The symbolic positional arguments.
        :param kwargs: The symbolic keyword arguments.
        :return: The symbolic result of the function call.
        :raises TypeError: If arguments fail to bind to parameters.
        """
        validation.assert_is_callable(fn, "fn")
        validation.assert_can_bind(fn, *args, **kwargs)
        return self._call(get_stack_frame(), fn, *args, **kwargs)
示例#7
0
    def unpack(self, iterable, length: int) -> Tuple[Node, ...]:
        """
        Unpack a symbolic iterable into a tuple of symbolic values.

        :param iterable: The symbolic iterable.
        :param length: The number of values in the iterable.
        :return: A tuple of :class:`~uberjob.graph.Node`.
        """
        if not isinstance(length, int) or length < 0:
            raise ValueError("length must be a non-negative integer.")
        stack_frame = get_stack_frame()
        t = self._call(stack_frame, _builtins.unpack, iterable, length)
        return tuple(
            self._call(stack_frame, operator.getitem, t, index)
            for index in range(length))
示例#8
0
    def source(self, plan: Plan, value_store: ValueStore) -> Node:
        """
        Create a :class:`~uberjob.graph.Node` in the :class:`~uberjob.Plan` that reads from the
        given :class:`~uberjob.ValueStore`.

        :param plan: The plan to add a source node to.
        :param value_store: The value store to read from.
        :return: The newly added plan node.
        """
        validation.assert_is_instance(plan, "plan", Plan)
        validation.assert_is_instance(value_store, "value_store", ValueStore)
        stack_frame = get_stack_frame()
        node = plan._call(stack_frame, source)
        self.mapping[node] = RegistryValue(value_store,
                                           is_source=True,
                                           stack_frame=stack_frame)
        return node
示例#9
0
 def test_stack_frame_function(self):
     stack_frame1 = get_stack_frame(1)
     stack_frame2 = get_stack_frame(1)
     self.assertEqual(stack_frame1.path, __file__)
     self.assertEqual(stack_frame1.line + 1, stack_frame2.line)