예제 #1
0
def adjust_context_window(op, timecontext: Optional[TimeContext], **kwargs):
    new_timecontexts = [
        timecontext for arg in op.inputs if is_computable_input(arg)
    ]

    if not timecontext:
        return new_timecontexts

    # adjust time context by preceding and following
    begin, end = timecontext
    result = [begin, end]
    preceding = op.window.preceding
    following = op.window.following
    if preceding is not None:
        if isinstance(preceding, ir.IntervalScalar):
            new_preceding = execute(preceding)
        else:
            new_preceding = preceding
        if new_preceding:
            result[0] = begin - new_preceding
    if following is not None:
        if isinstance(following, ir.IntervalScalar):
            new_following = execute(following)
        else:
            new_following = following
        if new_following:
            result[1] = end + new_following
    new_timecontexts = [
        result for arg in op.inputs if is_computable_input(arg)
    ]
    return new_timecontexts
예제 #2
0
def test_is_computable_input():
    class MyObject:
        def __init__(self, value: float) -> None:
            self.value = value

        def __getattr__(self, name: str) -> Any:
            return getattr(self.value, name)

        def __hash__(self) -> int:
            return hash((type(self), self.value))

        def __eq__(self, other):
            return (isinstance(other, type(self))
                    and isinstance(self, type(other))
                    and self.value == other.value)

        def __float__(self) -> float:
            return self.value

    @execute_node.register(ops.Add, int, MyObject)
    def add_int_my_object(op, left, right, **kwargs):
        return left + right.value

    # This multimethod must be implemented to play nicely with other value
    # types like columns and literals. In other words, for a custom
    # non-expression object to play nicely it must somehow map to one of the
    # types in ibis/expr/datatypes.py
    @dt.infer.register(MyObject)
    def infer_my_object(_, **kwargs):
        return dt.float64

    @is_computable_input.register(MyObject)
    def is_computable_input_my_object(_):
        return True

    one = ibis.literal(1)
    two = MyObject(2.0)
    assert is_computable_input(two)

    three = one + two
    four = three + 1
    result = ibis.pandas.execute(four)
    assert result == 4.0

    del execute_node[ops.Add, int, MyObject]

    execute_node.reorder()
    execute_node._cache.clear()

    del dt.infer.funcs[(MyObject, )]
    dt.infer.reorder()
    dt.infer._cache.clear()
예제 #3
0
def adjust_context_asof_join(op, timecontext: Optional[TimeContext], **kwargs):
    new_timecontexts = [
        timecontext for arg in op.inputs if is_computable_input(arg)
    ]

    if not timecontext:
        return new_timecontexts
    begin, end = timecontext
    tolerance = op.tolerance
    if tolerance is not None:
        timedelta = execute(tolerance)
        # only backwards and adjust begin time only
        new_begin = begin - timedelta
        new_end = end
    # right table is the second node in children
    new_timecontexts[1] = (new_begin, new_end)
    return new_timecontexts