def test_resolve_struct(self): @infer(JSON_INTO) @dataclass class A: a: int @infer(JSON_INTO) @dataclass class B: a: int b: A self.assertEqual(Ref(JSON_INTO, __name__ + '.A'), Walker(JSON_INTO).resolve(A)) self.assertEqual( Ref(JSON_INTO, __name__ + '.B'), Walker(JSON_INTO).resolve(B), ) self.assertEqual( AnyIntoStruct([AnyAnyField('a', AnyAnyAttr('a', This(int)))], A), A.__serde__[JSON_INTO], ) self.assertEqual( AnyIntoStruct([ AnyAnyField('a', AnyAnyAttr('a', This(int))), AnyAnyField('b', AnyAnyAttr('b', Ref(JSON_INTO, __name__ + '.A'))), ], B), B.__serde__[JSON_INTO], )
def get_factories(name: str, *clss: Type) -> List[Fac]: walker = Walker(name) factories = [walker.resolve(cls) for cls in clss] node_objs, visit_node, root_nodes = walker._visit_objs(*factories) return [node_objs[x][1] for x in root_nodes]
def test_api_1(self): pkt = Packet(None, Service('ratelimiter')) wlkr1 = Walker(JSON_FROM) wlkr2 = Walker(JSON_INTO) fac1 = wlkr1.resolve(Packet) fac2 = wlkr2.resolve(Packet) json_from, = wlkr1.mappers(fac1) json_into, = wlkr2.mappers(fac2) out1 = json_into.serialize(pkt) trc('test_api_1').debug('%s', out1) out2 = json_from.serialize(out1) trc('test_api_2').debug('%s', out2) self.assertEqual( OrderedDict([('type', 'service'), ('stream', None), ('body', { 'version': '0.1.0', 'name': 'ratelimiter', 'proto': '0.1.0' })]), out1) self.assertEqual(pkt, out2)
def auto_callable_param_schema(params, par: T) -> T: schema = par.schema if schema is None: default, annot = params[par.name] if annot is None: raise ValueError( f'Schemaless definitions need a type annotation `{par.name}`') schema = auto_any(annot) if default != EMPTY: ctx = Walker(JSON_INTO) fac = ctx.resolve(par) mapper, = ctx.mappers(fac) schema.default = mapper.serialize(default) return replace(par, schema=schema)
def test_mapper_into(self): ctx = Walker(JSON_INTO) fac = ctx.resolve(Amber) mapper, = ctx.mappers(fac) self.assertEqual({ 'a': 555, 'b': { 'b': None } }, mapper.serialize(Amber(555, Bulky()))) try: self.assertEqual({ 'a': 'asd', 'b': { 'b': None } }, mapper.serialize(Amber('asd', Bulky()))) except SerializationError as e: self.assertEqual(['0', 'a', '$attr'], e.path)
def test_body_1(self): fac_from = AnyAnyWith( BinaryFromVarInt(), AnyAnyWith( BinaryFromBytes( AnyAnyAttr('val', This(int)), AnyAnyAttr('next', This()) ), AnyFromStruct( [ AnyAnyField( 'val', BinaryFromJson( AnyAnyAttr('val') ) ), AnyAnyField('next', AnyAnyAttr('next')) ], cls=BinaryNext ) ) ) fac_into = AnyAnyWith( BinaryIntoJson(This()), BinaryIntoConcat([ AnyAnyWith( AnyAnyLen(This()), BinaryIntoVarInt(), ), This() ]) ) bin_from, = Walker(BINARY_FROM).mappers(fac_from) bin_into, = Walker(BINARY_INTO).mappers(fac_into) x = bin_from.serialize(b'\x02{}abc') trc('0').debug(x) self.assertEqual( BinaryNext({}, b'abc'), x, ) try: x = bin_from.serialize(b'\x55{}abc') except SerializationError as e: self.assertEqual(BUFFER_NEEDED, e.reason) self.assertEqual( b'\x04null', bin_into.serialize(None) )
def get_serializers(name: str, *clss: Any) -> List[Mapper]: walker = Walker(name) factories = [walker.resolve(cls) for cls in clss] walker = Walker(None) return walker.mappers(*factories)
def test_mapper_from(self): ctx = Walker(JSON_FROM) fac = ctx.resolve(Amber) mapper, = ctx.mappers(fac) self.assertEqual(Amber(555, Bulky()), mapper.serialize({ 'a': 555, 'b': { 'b': None } })) try: self.assertEqual(Amber('asd', Bulky()), mapper.serialize({ 'a': 'asd', 'b': { 'b': None } })) except SerializationError as e: self.assertEqual(['0', 'a', '$item'], e.path)
def auto_dataclass(cls): r = schema.ObjectSchema( name=cls.__name__, extensions={'py-dataclass': cls.__module__ + '.' + cls.__name__}) flds: List[Field] = fields(cls) for field in flds: item = auto_any(field.type) if isinstance(item, schema.Defaulted): default = field.default default_set = None if default == MISSING: if field.default_factory != MISSING: default = field.default_factory() if default != MISSING: if default is None: if isinstance(item, schema.Nullable): item.nullable = True else: raise NotImplementedError(f'{field.name} {item} [1]') else: ctx = Walker(JSON_INTO) fac = ctx.resolve(field.type) mapper, = ctx.mappers(fac) default_set = mapper.serialize(default) item.default = default_set r.properties[field.name] = schema.ObjectSchemaProperty(item) return r
def mappify(self, name_req: str, name_rep: str) -> 'Endpoints': walker_req = Walker(name_req) factories_req = [] for endpoint in self.items: for arg in endpoint.arguments: factories_req.append(walker_req.resolve(arg.type)) if endpoint.body: factories_req.append(walker_req.resolve(endpoint.body)) mappers_req = iter(walker_req.mappers(*factories_req)) for endpoint in self.items: for arg in endpoint.arguments: arg.mapper = next(mappers_req) if endpoint.body: endpoint.body_mapper = next(mappers_req) walker_rep = Walker(name_rep) factories_rep = [] for endpoint in self.items: if endpoint.response: factories_rep.append(walker_rep.resolve(endpoint.response)) mappers_rep = iter(walker_rep.mappers(*factories_rep)) for endpoint in self.items: if endpoint.response: endpoint.response_mapper = next(mappers_rep) return self
def test_api_2(self): pkt = Packet(None, Service('ratelimiter')) wlkr1 = Walker(BINARY_FROM) wlkr2 = Walker(BINARY_INTO) fac1 = wlkr1.resolve(Packet) fac2 = wlkr2.resolve(Packet) json_from, = wlkr1.mappers(fac1) json_into, = wlkr2.mappers(fac2) out1 = json_into.serialize(pkt) trc('test_api_1').debug('%s', out1) out2 = json_from.serialize(out1) trc('test_api_2').debug('%s', out2) self.assertEqual(out1[0], len(out1[1:])) self.assertEqual(pkt, out2.val)
def test_resolve_atom(self): self.assertEqual(This(str), Walker(JSON_FROM).resolve(str)) self.assertEqual(JsonFromTimeDelta(), Walker(JSON_FROM).resolve(timedelta))
def get_factories_il(name: str, cls: Any) -> Fac: walker = Walker(name) return walker.resolve(cls)
def get_mappers(*facs: Fac) -> List[Mapper]: # todo specifically, walker is not required to have a name assigned to it. walker = Walker(None) return walker.mappers(*facs)
def __init__(self, *names: str, is_method=False): frame = inspect.currentframe().f_back self.ctxs = [Walker(name, frame=frame) for name in names] self.is_method = is_method