Esempio n. 1
0
def test_type_with_unions():
    class VariantA(NamedTuple):
        variant_a: int

    class VariantB(NamedTuple):
        variant_b: int
        variant_b_attr: int

    class X(NamedTuple):
        x: Union[None, VariantA, VariantB]
        y: Union[str, VariantA]

    mk_x, serialize_x = typeit.TypeConstructor(X)

    x = mk_x({'x': {'variant_a': 1}, 'y': 'y'})
    assert isinstance(x.x, VariantA)

    data = {'x': {'variant_b': 1, 'variant_b_attr': 1}, 'y': 'y'}
    x = mk_x(data)
    assert isinstance(x.x, VariantB)

    assert data == serialize_x(x)

    assert mk_x({'x': None, 'y': 'y'}) == mk_x({'y': 'y'})
    with pytest.raises(typeit.Error):
        # this is not the same as mk_x({}),
        # the empty structure is passed as attribute x,
        # which should match with only an empty named tuple definition,
        # which is not the same as None.
        mk_x({'x': {}})
Esempio n. 2
0
def test_type_with_set():
    class X(NamedTuple):
        a: FrozenSet
        b: FrozenSet[Any]
        c: frozenset
        d: FrozenSet[int]
        e: set
        f: Set
        g: Set[Any]
        h: Set[int]

    mk_x, serializer = typeit.TypeConstructor(X)

    x = mk_x({
        'a': [],
        'b': [],
        'c': [],
        'd': [1],
        'e': [],
        'f': [],
        'g': [],
        'h': [1],
    })
    assert x.a == x.b == x.c == frozenset()
    assert isinstance(x.d, frozenset)
    assert isinstance(x.e, set)
    assert x.h == {1}
    assert x.d == x.h
Esempio n. 3
0
def test_iter_invalid_data():
    class ItemType(Enum):
        ONE = 'one'
        TWO = 'two'

    class Item(NamedTuple):
        val: ItemType

    class X(NamedTuple):
        items: Sequence[Item]
        item: Item

    mk_x, serialize_x = typeit.TypeConstructor(X)

    data = {
        'items': [
            {'val': 'one'},
            {'val': 'two'},
            {'val': 'three'},
            {'val': 'four'},
        ]
    }

    try:
        x = mk_x(data)
    except typeit.Error as e:
        for inv in e:
            assert isinstance(inv, InvalidData)
Esempio n. 4
0
def test_type_with_sequence():
    class X(NamedTuple):
        x: int
        y: Sequence[Any]
        z: Sequence[str]

    mk_main, serializer = typeit.TypeConstructor(X)

    x = mk_main({'x': 1, 'y': [], 'z': ['Hello']})
    assert x.y == []
    assert x.z[0] == 'Hello'
Esempio n. 5
0
def test_parse_sequence():
    class X(NamedTuple):
        x: int
        y: Dict[str, Any]

    XS = Sequence[X]

    data = [{'x': 1, 'y': {}}]
    mk_xs, serialize_xs = typeit.TypeConstructor(XS)
    z = mk_xs(data)
    assert z[0].x == 1
    assert serialize_xs(z) == data

    # Sequences with primitives
    XS = Sequence[int]

    data = [1, 2, 3]
    mk_xs, serialize_xs = typeit.TypeConstructor(XS)

    z = mk_xs(data)
    assert z[0] == 1
    assert serialize_xs(z) == data
Esempio n. 6
0
def test_type_with_empty_enum_variant():
    class Types(Enum):
        A = ''
        B = 'b'

    class X(NamedTuple):
        x: int
        y: Types

    mk_x, serializer = typeit.TypeConstructor(X)

    for variant in Types:
        x = mk_x({'x': 1, 'y': variant.value})
        assert x.y is variant

    with pytest.raises(typeit.Error):
        x = mk_x({'x': 1, 'y': None})
Esempio n. 7
0
def test_enum_unions_serialization():
    class E0(Enum):
        A = 'a'
        B = 'b'
        C = 'C'

    class E1(Enum):
        X = 'x'
        Y = 'y'
        Z = 'z'

    class MyType(NamedTuple):
        val: Union[E0, E1]

    __, serializer = typeit.TypeConstructor(MyType)

    assert serializer(MyType(val=E1.Z)) == {'val': 'z'}
Esempio n. 8
0
def test_enum_like_types():
    class Enums(Enum):
        A = 'a'
        B = 'b'

    class X(NamedTuple):
        e: Enums

    mk_x, serialize_x = typeit.TypeConstructor(X)

    data = {'e': 'a'}
    x = mk_x(data)
    assert isinstance(x.e, Enums)
    assert data == serialize_x(x)

    with pytest.raises(typeit.Error):
        x = mk_x({'e': None})
Esempio n. 9
0
def test_type_with_dict():
    """ Create a type with an explicit dictionary value
    that can hold any kv pairs
    """
    class X(NamedTuple):
        x: int
        y: Dict[str, Any]

    mk_x, serializer = typeit.TypeConstructor(X)

    with pytest.raises(typeit.Error):
        mk_x({})

    with pytest.raises(typeit.Error):
        mk_x({'x': 1})

    x = mk_x({'x': 1, 'y': {'x': 1}})
    assert x.x == x.y['x']
Esempio n. 10
0
def test_type_with_tuple_primitives():
    # There are several forms of tuple declarations
    # https://docs.python.org/3/library/typing.html#typing.Tuple
    # We want to support all possible fixed-length tuples,
    # including empty one
    class X(NamedTuple):
        a: Tuple[str, int]  # fixed N-tuple
        b: Tuple  # the following are equivalent
        c: tuple

    mk_x, serializer = typeit.TypeConstructor(X)

    x = mk_x({
        'a': ['value', 5],
        'b': (),
        'c': [],
        'd': ['Hello', 'Random', 'Value', 5, None, True, {}],
    })
    assert x.a == ('value', 5)
    assert x.b == ()
    assert x.b == x.c

    with pytest.raises(typeit.Error):
        # 'abc' is not int
        x = mk_x({
            'a': ['value', 'abc'],
            'b': [],
            'c': [],
        })

    with pytest.raises(typeit.Error):
        # .c field is required
        x = mk_x({
            'a': ['value', 5],
            'b': [],
        })

    with pytest.raises(typeit.Error):
        # .c field is required to be fixed sequence
        x = mk_x({
            'a': ['value', 'abc'],
            'b': (),
            'c': None,
        })
Esempio n. 11
0
def test_parser_github_pull_request_payload():
    data = GITHUB_PR_PAYLOAD_JSON
    github_pr_dict = json.loads(data)
    parsed, overrides = cg.parse_mapping(github_pr_dict)
    typ, overrides_ = cg.construct_type('main', parsed)
    overrides = overrides.update(overrides_)

    python_source, __ = cg.codegen_py(TypeitSchema(typ, overrides))
    assert 'overrides' in python_source
    assert "PullRequest.links: '_links'," in python_source
    assert 'mk_main, serialize_main = TypeConstructor & overrides ^ Main' in python_source

    PullRequestType = get_type_hints(typ)['pull_request']

    assert PullRequestType.links in overrides
    assert overrides[PullRequestType.links] == '_links'

    constructor, serializer = typeit.TypeConstructor(typ, overrides=overrides)
    github_pr = constructor(github_pr_dict)
    assert github_pr.pull_request.links.comments.href.startswith('http')
    assert github_pr_dict == serializer(github_pr)
Esempio n. 12
0
def test_type_with_complex_tuples():
    class Y(NamedTuple):
        a: Dict

    class X(NamedTuple):
        a: Tuple[Tuple[Dict, Y], int]
        b: Optional[Any]

    mk_x, serializer = typeit.TypeConstructor(X)

    x = mk_x({
        'a': [[{}, {
            'a': {
                'inner': 'value'
            }
        }], 5],
    })
    assert isinstance(x.a[0][1], Y)
    assert isinstance(x.a[1], int)
    assert x.b is None

    x = mk_x({'a': [[{}, {'a': {'inner': 'value'}}], 5], 'b': Y(a={})})
    assert isinstance(x.b, Y)
Esempio n. 13
0
def test_parse_builtins(typ, data):
    mk_x, serialize_x = typeit.TypeConstructor(typ)

    z = mk_x(data)
    assert z == data
    assert serialize_x(z) == data
Esempio n. 14
0
def test_unsupported_variable_length_tuples():
    class X(NamedTuple):
        a: Tuple[int, ...]

    with pytest.raises(TypeError):
        mk_x, serialize_x = typeit.TypeConstructor(X)