Пример #1
0
def test_doesnt_load_non_iterable() -> None:
    non_iterable = '{"a": 1}'
    with pytest.raises(
            TypeError,
            match=
            r"{'a': 1} is a dict, expected a top-level list from JSON source",
    ):
        autotui.namedtuple_sequence_loads(non_iterable, X)
Пример #2
0
def test_basic_sequence_dumps_loads() -> None:
    x = [X(a=1), X(a=5)]
    xlist_str: str = autotui.namedtuple_sequence_dumps(x, indent=None)
    assert xlist_str == """[{"a": 1}, {"a": 5}]"""
    back_to_x: List[X] = autotui.namedtuple_sequence_loads(xlist_str, to=X)
    assert type(back_to_x) == list
    assert back_to_x[0] == X(a=1)
    assert back_to_x[1] == X(a=5)
Пример #3
0
def test_recursive() -> None:
    obj = Wrapper(y=5, z=Internal(x=10))
    [dumped_obj] = json.loads(autotui.namedtuple_sequence_dumps([obj]))
    assert dumped_obj["y"] == 5
    assert type(dumped_obj["z"]) == dict
    assert dumped_obj["z"]["x"] == 10

    # dump to JSON and re-load
    [reloaded] = autotui.namedtuple_sequence_loads(json.dumps([dumped_obj]),
                                                   to=Wrapper)
    assert obj == reloaded
Пример #4
0
def save_from(nt: Type[NamedTuple],
              use_input: TextIO,
              partial: bool = False) -> None:
    json_text: str = use_input.read()
    p = datafile(namedtuple_func_name(nt))
    items: List[NamedTuple] = load_from(nt, p, allow_empty=True)
    new_items: List[NamedTuple] = []
    if partial:
        # load the list as json blobs
        os.environ["AUTOTUI_DISABLE_WARNINGS"] = "1"  # ignore null warnings
        blobs: List[Dict[str, Any]] = []
        for b in namedtuple_sequence_loads(json_text, nt):
            blobs.append(
                {k: v
                 for k, v in b._asdict().items() if v is not None})
        del os.environ["AUTOTUI_DISABLE_WARNINGS"]
        for bd in blobs:
            new_nt = prompt_namedtuple(nt, attr_use_values=bd)
            new_items.append(new_nt)
    else:
        new_items.extend(namedtuple_sequence_loads(json_text, nt))
    items.extend(new_items)
    dump_to(items, p)
Пример #5
0
def test_custom_handles_serializers() -> None:
    t = Temperature("20C")
    assert t.celsius == 20.0
    # just test creating the namedtuple prompt
    handler = autotui.AutoHandler(func=Temperature,
                                  catch_errors=[TypeError, ValueError])
    funcs = autotui.namedtuple_prompt_funcs(
        Reading, type_validators={Temperature: handler})
    assert len(funcs.keys()) == 2
    f = tempfile.NamedTemporaryFile(delete=False)
    type_serializers = {Temperature: serialize_temp}
    attr_deserializers = {"temp": deserialize_temp}
    d1 = datetime.now()
    d2 = datetime.now()
    readings: List[Reading] = [
        Reading(when=d1, temp=Temperature("20C")),
        Reading(when=d2, temp=Temperature("19C")),
    ]
    with open(f.name, "w") as fp:
        autotui.namedtuple_sequence_dump(readings,
                                         fp,
                                         type_serializers=type_serializers)

    # loads first, check warning when no deserializer provided
    with open(f.name) as fp:
        str_contents = fp.read()

    with warnings.catch_warnings(record=True) as record:
        readings_back = autotui.namedtuple_sequence_loads(str_contents,
                                                          to=Reading)
    assert len(record) >= 1
    assert "No known way to deserialize" in str(record[0].message)
    assert len(readings_back) == 2
    assert readings_back[0].temp == 20.0

    # then load properly
    with open(f.name) as fp:
        rbr = autotui.namedtuple_sequence_load(
            fp, to=Reading, attr_deserializers=attr_deserializers)
    assert len(rbr) == 2
    assert int(rbr[0].when.timestamp()) == int(d1.timestamp())
    assert rbr[0].temp == Temperature("20C")

    # delete file
    os.unlink(f.name)
# the type of the value thats loaded from JSON

# dump to JSON
a_str: str = namedtuple_sequence_dumps(
    [a],
    type_serializers={
        timedelta: to_seconds,
    },
    indent=None,
)

# load from JSON
a_load = namedtuple_sequence_loads(
    a_str,
    to=Action,
    type_deserializers={
        timedelta: from_seconds,
    },
)[0]

# can also specify with attributes instead of types
a_load2 = namedtuple_sequence_loads(
    a_str,
    to=Action,
    attr_deserializers={
        "duration": from_seconds,
    },
)[0]

print(a)
print(a_str)
Пример #7
0
def complex_loads():
    namedtuple_sequence_loads(
        complex_json, Complex, type_deserializers=complex_type_deserializer
    )
Пример #8
0
def typical_loads():
    namedtuple_sequence_loads(typical_json, Typical)
Пример #9
0
import autotui
from typing import NamedTuple
from datetime import datetime

# something to persist to a file
class Water(NamedTuple):
    at: datetime
    glass_count: float


w = autotui.prompt_namedtuple(Water)
print(w)

s = autotui.namedtuple_sequence_dumps([w], indent=None)
print(s)

b = autotui.namedtuple_sequence_loads(s, to=Water)
print(b[0])