def test_renaming(cl_and_vals, data): converter = Converter() cl, vals = cl_and_vals attrs = fields(cl) to_replace = data.draw(sampled_from(attrs)) u_fn = make_dict_unstructure_fn( cl, converter, **{to_replace.name: override(rename="class")} ) s_fn = make_dict_structure_fn( cl, converter, **{to_replace.name: override(rename="class")} ) converter.register_structure_hook(cl, s_fn) converter.register_unstructure_hook(cl, u_fn) inst = cl(*vals) raw = converter.unstructure(inst) assert "class" in raw new_inst = converter.structure(raw, cl) assert inst == new_inst
def test_no_linecache(): """Linecaching should be disableable.""" @define class A: a: int c = GenConverter() before = len(linecache.cache) c.structure(c.unstructure(A(1)), A) after = len(linecache.cache) assert after == before + 2 @define class B: a: int before = len(linecache.cache) c.register_structure_hook( B, make_dict_structure_fn(B, c, _cattrs_use_linecache=False)) c.register_unstructure_hook( B, make_dict_unstructure_fn(B, c, _cattrs_use_linecache=False)) c.structure(c.unstructure(B(1)), B) assert len(linecache.cache) == before
def test_forbid_extra_keys_nested_override(): @attr.s class C: a = attr.ib(type=int, default=1) @attr.s class A: c = attr.ib(type=C) a = attr.ib(type=int, default=2) converter = Converter(forbid_extra_keys=True) unstructured = {"a": 3, "c": {"a": 4}} # at this point, structuring should still work converter.structure(unstructured, A) # if we break it in the subclass, we need it to raise unstructured["c"]["aa"] = 5 with pytest.raises(Exception): converter.structure(unstructured, A) # we can "fix" that by disabling forbid_extra_keys on the subclass hook = make_dict_structure_fn(C, converter, _cattr_forbid_extra_keys=False) converter.register_structure_hook(C, hook) converter.structure(unstructured, A) # but we should still raise at the top level unstructured["b"] = 6 with pytest.raises(Exception): converter.structure(unstructured, A)
def test_unmodified_generated_structuring(cl_and_vals): converter = Converter() cl, vals = cl_and_vals fn = make_dict_structure_fn(cl, converter) inst = cl(*vals) unstructured = converter.unstructure(inst) converter.register_structure_hook(cl, fn) res = converter.structure(unstructured, cl) assert inst == res
make_dict_unstructure_fn( cls, dataset_converter, **{ a.name: override(omit_if_default=True, rename=snake_to_camel_case(a.name)) for a in attr.fields(cls) # pylint: disable=not-an-iterable }, ), ) dataset_converter.register_structure_hook( cls, make_dict_structure_fn( cls, dataset_converter, **{ a.name: override(rename=snake_to_camel_case(a.name)) for a in attr.fields(cls) # pylint: disable=not-an-iterable }, ), ) # The serialization of `LayerProperties` differs slightly based on whether it is a `wkw` or `zarr` layer. # These post-unstructure and pre-structure functions perform the conditional field renames. def mag_view_properties_post_structure(d: Dict[str, Any]) -> Dict[str, Any]: d["resolution"] = d["mag"] del d["mag"] return d def mag_view_properties_pre_unstructure(d: Dict[str, Any]) -> Dict[str, Any]:
def structure_adapt_to_camel_case(type): overrides = { a.name: override(rename=to_camel_case(a.name)) for a in fields(type) } return make_dict_structure_fn(type, converter, **overrides)
def __typed_structure(self, obj_data, cls, cls_fn): cls = cls_fn(obj_data["__type__"]) structure_fn = make_dict_structure_fn(cls, self) return structure_fn(obj_data, cls)