def test_bytearray(self, size): enc = msgspec.Encoder() dec = msgspec.Decoder(bytearray) x = bytearray(size) res = dec.decode(enc.encode(x)) assert isinstance(res, bytearray) assert res == x
def test_bytes(self, size): enc = msgspec.Encoder() dec = msgspec.Decoder(bytes) x = b"a" * size res = dec.decode(enc.encode(x)) assert isinstance(res, bytes) assert res == x
def test_struct(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Person) x = Person(first="harry", last="potter", age=13) a = enc.encode(x) assert (enc.encode({ "first": "harry", "last": "potter", "age": 13, "prefect": False }) == a) assert dec.decode(a) == x with pytest.raises(msgspec.DecodingError, match="truncated"): dec.decode(a[:-2]) with pytest.raises(msgspec.DecodingError, match="expected `struct`"): dec.decode(enc.encode(1)) with pytest.raises( msgspec.DecodingError, match= r"Error decoding `Person` field `first` \(`str`\): expected `str`, got `int`", ): dec.decode(enc.encode({1: "harry"}))
def test_encode_default_errors(self): def default(x): raise TypeError("bad") enc = msgspec.Encoder(default=default) with pytest.raises(TypeError, match="bad"): enc.encode(object())
def test_dict_any_val(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Dict[str, Any]) x = {"a": 1, "b": "two", "c": b"three"} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.DecodingError, match="expected `str`"): dec.decode(enc.encode({1: 2}))
def __init__(self, loop: asyncio.AbstractEventLoop = None): self.loop = loop or asyncio.get_event_loop() self.closing = self.loop.create_future() self.transport = None self.last_id = 1 self.waiting = defaultdict(dict) self.encoder = msgspec.Encoder() self.decoder = msgspec.Decoder(Response)
def check(self, x): msgpack = pytest.importorskip("msgpack") enc = msgspec.Encoder() dec = msgspec.Decoder() assert_eq(dec.decode(msgpack.dumps(x)), x) assert_eq(msgpack.loads(enc.encode(x)), x)
def test_struct_defaults_missing_fields(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Person) a = enc.encode({"first": "harry", "last": "potter", "age": 13}) res = dec.decode(a) assert res == Person("harry", "potter", 13) assert res.prefect is False
def test_dict_any_any(self, typ): enc = msgspec.Encoder() dec = msgspec.Decoder(typ) x = {1: "one", "two": 2, b"three": 3.0} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.DecodingError, match="expected `dict`"): dec.decode(enc.encode(1))
def test_vartuple_typed(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Tuple[int, ...]) x = (1, 2, 3) res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.DecodingError, match="expected `int`"): dec.decode(enc.encode((1, 2, "three")))
def test_struct_recursive_definition(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Node) x = Node(Node(Node(), Node(Node()))) s = enc.encode(x) res = dec.decode(s) assert res == x
def test_vartuple_any(self, typ): enc = msgspec.Encoder() dec = msgspec.Decoder(typ) x = (1, "two", b"three") res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.DecodingError, match="expected `tuple`"): dec.decode(enc.encode(1))
def test_set_typed(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Set[int]) x = {1, 2, 3} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.DecodingError, match="expected `int`"): dec.decode(enc.encode({1, 2, "three"}))
def test_list_typed(self): enc = msgspec.Encoder() dec = msgspec.Decoder(List[int]) x = [1, 2, 3] res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.DecodingError, match="expected `int`"): dec.decode(enc.encode([1, 2, "three"]))
def test_dict_any_key(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Dict[Any, str]) x = {1: "a", "two": "b", b"three": "c"} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.DecodingError, match="expected `str`"): dec.decode(enc.encode({1: 2}))
def test_decoding_error_no_struct_toplevel(self): b = msgspec.Encoder().encode([{"a": 1}]) dec = msgspec.Decoder(List[Dict[str, str]]) with pytest.raises( msgspec.DecodingError, match= r"Error decoding `List\[Dict\[str, str\]\]`: expected `str`, got `int`", ): dec.decode(b)
def test_float(self, x): enc = msgspec.Encoder() dec = msgspec.Decoder(float) res = dec.decode(enc.encode(x)) sol = float(x) if math.isnan(sol): assert math.isnan(res) else: assert res == sol
def test_dict_typed(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Dict[str, int]) x = {"a": 1, "b": 2} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.DecodingError, match="expected `str`"): dec.decode(enc.encode({1: 2})) with pytest.raises(msgspec.DecodingError, match="expected `int`"): dec.decode(enc.encode({"a": "two"}))
def test_struct_field_wrong_type(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Person) bad = enc.encode({ "first": "harry", "last": "potter", "age": "thirteen" }) with pytest.raises(msgspec.DecodingError, match="expected `int`"): dec.decode(bad)
def test_encode_no_default(self): class Foo: pass enc = msgspec.Encoder() assert enc.default is None with pytest.raises( TypeError, match="Encoding objects of type Foo is unsupported"): enc.encode(Foo())
def test_optional(self, typ, value): enc = msgspec.Encoder() dec = msgspec.Decoder(Optional[typ]) s = enc.encode(value) s2 = enc.encode(None) assert dec.decode(s) == value assert dec.decode(s2) is None dec = msgspec.Decoder(typ) with pytest.raises(msgspec.DecodingError): dec.decode(s2)
def test_struct_missing_fields(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Person) bad = enc.encode({"first": "harry", "last": "potter"}) with pytest.raises(msgspec.DecodingError, match="missing required field `age`"): dec.decode(bad) bad = enc.encode({}) with pytest.raises(msgspec.DecodingError, match="missing required field `first`"): dec.decode(bad)
def __init__(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter, loop: asyncio.AbstractEventLoop = None): self.reader = reader self.writer = writer self.encoder = msgspec.Encoder() self.decoder = msgspec.Decoder(Response) self.serial = 0 self.futures = {} self.loop = loop or asyncio.get_event_loop() self.reader_task = self.loop.create_task(self._response_reader())
def test_encode_default_recurses(self): class Node: def __init__(self, a): self.a = a def default(x): return {"type": "Node", "a": x.a} enc = msgspec.Encoder(default=default) msg = enc.encode(Node(Node(1))) res = msgspec.decode(msg) assert res == {"type": "Node", "a": {"type": "Node", "a": 1}}
def test_fixtuple_any(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Tuple[Any, Any, Any]) x = (1, "two", b"three") res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.DecodingError, match="expected `tuple`"): dec.decode(enc.encode(1)) with pytest.raises( msgspec.DecodingError, match= r"Error decoding `Tuple\[Any, Any, Any\]`: expected tuple of length 3, got 2", ): dec.decode(enc.encode((1, 2)))
def test_fixtuple_typed(self): enc = msgspec.Encoder() dec = msgspec.Decoder(Tuple[int, str, bytes]) x = (1, "two", b"three") res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.DecodingError, match="expected `bytes`"): dec.decode(enc.encode((1, "two", "three"))) with pytest.raises( msgspec.DecodingError, match= r"Error decoding `Tuple\[int, str, bytes\]`: expected tuple of length 3, got 2", ): dec.decode(enc.encode((1, 2)))
def test_struct_ignore_extra_fields(self, extra): enc = msgspec.Encoder() dec = msgspec.Decoder(Person) a = enc.encode({ "extra1": extra, "first": "harry", "extra2": extra, "last": "potter", "age": 13, "extra3": extra, }) res = dec.decode(a) assert res == Person("harry", "potter", 13)
def bench_msgspec(n, no_gc, validate=False): enc = msgspec.Encoder() dec = msgspec.Decoder(Person if n == 1 else List[Person]) def convert_one(addresses=None, **kwargs): addrs = [Address(**a) for a in addresses] if addresses else None return Person(addresses=addrs, **kwargs) def convert(data): return ([convert_one(**d) for d in data] if isinstance(data, list) else convert_one( **data)) return bench(enc.encode, dec.decode, n, convert, no_gc=no_gc)
def test_enum(self): enc = msgspec.Encoder() dec = msgspec.Decoder(FruitStr) a = enc.encode(FruitStr.APPLE) assert enc.encode("APPLE") == a assert dec.decode(a) == FruitStr.APPLE with pytest.raises(msgspec.DecodingError, match="truncated"): dec.decode(a[:-2]) with pytest.raises(msgspec.DecodingError, match="Error decoding enum `FruitStr`"): dec.decode(enc.encode("MISSING")) with pytest.raises(msgspec.DecodingError): dec.decode(enc.encode(1))
def test_int_enum(self): enc = msgspec.Encoder() dec = msgspec.Decoder(FruitInt) a = enc.encode(FruitInt.APPLE) assert enc.encode(1) == a assert dec.decode(a) == FruitInt.APPLE with pytest.raises(msgspec.DecodingError, match="truncated"): dec.decode(a[:-2]) with pytest.raises(msgspec.DecodingError, match="Error decoding enum `FruitInt`"): dec.decode(enc.encode(1000)) with pytest.raises(msgspec.DecodingError): dec.decode(enc.encode("INVALID"))