Ejemplo n.º 1
0
def test_union_field_roundtrip(cl_and_vals_a, cl_and_vals_b, strat):
    """
    Classes with union fields can be unstructured and structured.
    """
    converter = Converter(unstruct_strat=strat)
    cl_a, vals_a = cl_and_vals_a
    cl_b, vals_b = cl_and_vals_b
    a_field_names = {a.name for a in fields(cl_a)}
    b_field_names = {a.name for a in fields(cl_b)}
    assume(a_field_names)
    assume(b_field_names)

    common_names = a_field_names & b_field_names
    assume(len(a_field_names) > len(common_names))

    @dataclass
    class C(object):
        a: Union[cl_a, cl_b]

    inst = C(a=cl_a(*vals_a))

    if strat is UnstructureStrategy.AS_DICT:
        assert inst == converter.structure(converter.unstructure(inst), C)
    else:
        # Our disambiguation functions only support dictionaries for now.
        with pytest.raises(ValueError):
            converter.structure(converter.unstructure(inst), C)

        def handler(obj, _):
            return converter.structure(obj, cl_a)

        converter._union_registry[Union[cl_a, cl_b]] = handler
        assert inst == converter.structure(converter.unstructure(inst), C)
        del converter._union_registry[Union[cl_a, cl_b]]
Ejemplo n.º 2
0
def test_structuring_seqs(seq_and_type):
    """Test structuring sequence generic types."""
    converter = Converter()
    iterable, t = seq_and_type
    converted = converter.structure(iterable, t)
    for x, y in zip(iterable, converted):
        assert x == y
Ejemplo n.º 3
0
def test_structuring_dicts(dict_and_type):
    converter = Converter()
    d, t = dict_and_type

    converted = converter.structure(d, t)

    assert converted == d
    assert converted is not d
Ejemplo n.º 4
0
def test_simple_roundtrip(cls_and_vals, strat):
    """
    Simple classes with metadata can be unstructured and restructured.
    """
    converter = Converter(unstruct_strat=strat)
    cl, vals = cls_and_vals
    inst = cl(*vals)
    assert inst == converter.structure(converter.unstructure(inst), cl)
Ejemplo n.º 5
0
def test_nested_roundtrip(cls_and_vals, strat):
    """
    Nested classes with metadata can be unstructured and restructured.
    """
    converter = Converter(unstruct_strat=strat)
    cl, vals = cls_and_vals
    # Vals are a tuple, convert into a dictionary.
    inst = cl(*vals)
    assert inst == converter.structure(converter.unstructure(inst), cl)
Ejemplo n.º 6
0
def test_simple_roundtrip_defaults(cls_and_vals, strat):
    """
    Simple classes with metadata can be unstructured and restructured.
    """
    a, _ = cls_and_vals
    cl = make_dataclass("HypClass", [("a", a.type, a)])
    converter = Converter(unstruct_strat=strat)
    inst = cl()
    assert inst == converter.structure(converter.unstructure(inst), cl)
Ejemplo n.º 7
0
def test_stringifying_sets(set_and_type):
    """Test structuring generic sets and converting the contents to str."""
    converter = Converter()
    set_, input_set_type = set_and_type

    if is_bare(input_set_type):
        input_set_type = input_set_type[str]
    else:
        input_set_type.__args__ = (str, )
    converted = converter.structure(set_, input_set_type)
    assert len(converted) == len(set_)
    for e in set_:
        assert str(e) in converted
Ejemplo n.º 8
0
def test_simple_name_modifiers(cls_and_vals):
    """
    Simple classes with metadata can be unstructured and restructured.
    """
    a, vals = cls_and_vals
    converter = Converter()
    if len(fields(a)) > 0:
        fld = mod.name("t-t", fields(a)[0])
        cl = make_dataclass("HypClass", [("t_t", fld.type, fld)])
        inst = cl(vals[0])
        assert converter.unstructure(inst).get("t-t", MISSING) is not MISSING
    else:
        cl = make_dataclass("HypClass", [])
        inst = cl()
    assert inst == converter.structure(converter.unstructure(inst), cl)
Ejemplo n.º 9
0
def test_individual_overrides(cl_and_vals):
    """
    Test omitting default values on a per-class basis, but with individual
    overrides.
    """
    converter = Converter()
    cl, vals = cl_and_vals

    for attr, val in zip(
        tuple(v for _, v in cl.__dataclass_fields__.items()), vals
    ):
        if attr.default is not MISSING:
            break
    else:
        assume(False)

    chosen = attr

    converter.register_unstructure_hook(
        cl,
        make_dict_unstructure_fn(
            cl,
            converter,
            omit_if_default=True,
            **{attr.name: override(omit_if_default=False)}
        ),
    )

    inst = cl(*vals)

    res = converter.unstructure(inst)

    for attr, val in zip(
        tuple(v for _, v in cl.__dataclass_fields__.items()), vals
    ):
        if attr is chosen:
            assert attr.name in res
        elif attr.default is not MISSING:
            if val == attr.default:
                assert attr.name not in res
            else:
                assert attr.name in res
        elif attr.default_factory is not MISSING:
            if val == attr.default_factory():
                assert attr.name not in res
            else:
                assert attr.name in res
Ejemplo n.º 10
0
def test_optional_field_roundtrip(cl_and_vals):
    """
    Classes with optional fields can be unstructured and structured.
    """
    converter = Converter()
    cl, vals = cl_and_vals

    @dataclass
    class C(object):
        a: Optional[cl]

    inst = C(a=cl(*vals))
    assert inst == converter.structure(converter.unstructure(inst), C)

    inst = C(a=None)
    unstructured = converter.unstructure(inst)

    assert inst == converter.structure(unstructured, C)
Ejemplo n.º 11
0
def test_structuring_sets(set_and_type, set_type):
    """Test structuring generic sets."""
    converter = Converter()
    set_, input_set_type = set_and_type

    if input_set_type not in (Set, FrozenSet, MutableSet):
        set_type = set_type[input_set_type.__args__[0]]

    converted = converter.structure(set_, set_type)
    assert converted == set_

    # Set[int] can't be used with isinstance any more.
    non_generic = (set_type.__origin__
                   if set_type.__origin__ is not None else set_type)
    assert isinstance(converted, non_generic)

    converted = converter.structure(set_, Any)
    assert converted == set_
    assert isinstance(converted, type(set_))
Ejemplo n.º 12
0
def converter():
    return Converter()