Beispiel #1
0
def test_binding_data_map():
    b1 = literals.BindingData(scalar=literals.Scalar(
        primitive=literals.Primitive(integer=5)))
    b2 = literals.BindingData(scalar=literals.Scalar(
        primitive=literals.Primitive(integer=57)))
    b3 = literals.BindingData(scalar=literals.Scalar(
        primitive=literals.Primitive(integer=2)))
    binding_map_sub = literals.BindingDataMap(bindings={
        "first": b1,
        "second": b2
    })
    binding_map = literals.BindingDataMap(
        bindings={
            "three": b3,
            "sample_map": literals.BindingData(map=binding_map_sub)
        })
    obj = literals.BindingData(map=binding_map)
    assert obj.scalar is None
    assert obj.promise is None
    assert obj.collection is None
    assert obj.value.bindings["three"].value.value.value == 2
    assert obj.value.bindings["sample_map"].value.bindings[
        "second"].value.value.value == 57

    obj2 = literals.BindingData.from_flyte_idl(obj.to_flyte_idl())
    assert obj == obj2
    assert obj2.scalar is None
    assert obj2.promise is None
    assert obj2.collection is None
    assert obj2.value.bindings["three"].value.value.value == 2
    assert obj2.value.bindings["sample_map"].value.bindings[
        "first"].value.value.value == 5
Beispiel #2
0
def binding_data_from_python_std(
    ctx: _flyte_context.FlyteContext,
    expected_literal_type: _type_models.LiteralType,
    t_value: typing.Any,
    t_value_type: type,
) -> _literals_models.BindingData:
    # This handles the case where the given value is the output of another task
    if isinstance(t_value, Promise):
        if not t_value.is_ready:
            return _literals_models.BindingData(promise=t_value.ref)

    elif isinstance(t_value, VoidPromise):
        raise AssertionError(
            f"Cannot pass output from task {t_value.task_name} that produces no outputs to a downstream task"
        )

    elif isinstance(t_value, list):
        if expected_literal_type.collection_type is None:
            raise AssertionError(
                f"this should be a list and it is not: {type(t_value)} vs {expected_literal_type}"
            )

        sub_type = ListTransformer.get_sub_type(t_value_type)
        collection = _literals_models.BindingDataCollection(bindings=[
            binding_data_from_python_std(
                ctx, expected_literal_type.collection_type, t, sub_type)
            for t in t_value
        ])

        return _literals_models.BindingData(collection=collection)

    elif isinstance(t_value, dict):
        if (expected_literal_type.map_value_type is None
                and expected_literal_type.simple !=
                _type_models.SimpleType.STRUCT):
            raise AssertionError(
                f"this should be a Dictionary type and it is not: {type(t_value)} vs {expected_literal_type}"
            )
        k_type, v_type = DictTransformer.get_dict_types(t_value_type)
        if expected_literal_type.simple == _type_models.SimpleType.STRUCT:
            lit = TypeEngine.to_literal(ctx, t_value, type(t_value),
                                        expected_literal_type)
            return _literals_models.BindingData(scalar=lit.scalar)
        else:
            m = _literals_models.BindingDataMap(
                bindings={
                    k: binding_data_from_python_std(
                        ctx, expected_literal_type.map_value_type, v, v_type)
                    for k, v in t_value.items()
                })
        return _literals_models.BindingData(map=m)

    # This is the scalar case - e.g. my_task(in1=5)
    scalar = TypeEngine.to_literal(ctx, t_value, t_value_type,
                                   expected_literal_type).scalar
    return _literals_models.BindingData(scalar=scalar)
Beispiel #3
0
def binding_data_from_python_std(
    ctx: _flyte_context.FlyteContext,
    expected_literal_type: _type_models.LiteralType,
    t_value: typing.Any,
    t_value_type: type,
) -> _literals_models.BindingData:
    # This handles the case where the given value is the output of another task
    if isinstance(t_value, Promise):
        if not t_value.is_ready:
            return _literals_models.BindingData(promise=t_value.ref)

    elif isinstance(t_value, VoidPromise):
        raise AssertionError(
            f"Cannot pass output from task {t_value.task_name} that produces no outputs to a downstream task"
        )

    elif isinstance(t_value, list):
        if expected_literal_type.collection_type is None:
            raise AssertionError(
                f"this should be a list and it is not: {type(t_value)} vs {expected_literal_type}"
            )

        sub_type = ListTransformer.get_sub_type(t_value_type)
        collection = _literals_models.BindingDataCollection(bindings=[
            binding_data_from_python_std(
                ctx, expected_literal_type.collection_type, t, sub_type)
            for t in t_value
        ])

        return _literals_models.BindingData(collection=collection)

    elif isinstance(t_value, dict):
        if (expected_literal_type.map_value_type is None
                and expected_literal_type.simple !=
                _type_models.SimpleType.STRUCT):
            raise AssertionError(
                f"this should be a Dictionary type and it is not: {type(t_value)} vs {expected_literal_type}"
            )
        k_type, v_type = DictTransformer.get_dict_types(t_value_type)
        if expected_literal_type.simple == _type_models.SimpleType.STRUCT:
            lit = TypeEngine.to_literal(ctx, t_value, type(t_value),
                                        expected_literal_type)
            return _literals_models.BindingData(scalar=lit.scalar)
        else:
            m = _literals_models.BindingDataMap(
                bindings={
                    k: binding_data_from_python_std(
                        ctx, expected_literal_type.map_value_type, v, v_type)
                    for k, v in t_value.items()
                })
        return _literals_models.BindingData(map=m)

    elif isinstance(t_value, tuple):
        raise AssertionError(
            "Tuples are not a supported type for individual values in Flyte - got a tuple -"
            f" {t_value}. If using named tuple in an inner task, please, de-reference the"
            "actual attribute that you want to use. For example, in NamedTuple('OP', x=int) then"
            "return v.x, instead of v, even if this has a single element")

    # This is the scalar case - e.g. my_task(in1=5)
    scalar = TypeEngine.to_literal(ctx, t_value, t_value_type,
                                   expected_literal_type).scalar
    return _literals_models.BindingData(scalar=scalar)