def test_decoder_ext_hook_attribute(self): def ext_hook(code, buf): pass dec = msgspec.Decoder() assert dec.ext_hook is None dec = msgspec.Decoder(ext_hook=None) assert dec.ext_hook is None dec = msgspec.Decoder(ext_hook=ext_hook) assert dec.ext_hook is ext_hook
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 check_Decoder_decode_any() -> None: dec = msgspec.Decoder() b = msgspec.encode([1, 2, 3]) o = dec.decode(b) reveal_type(dec) # assert "Decoder" in typ and "Any" in typ reveal_type(o) # assert "Any" in typ
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_decoder_validates_struct_definition_unsupported_types(self): """Struct definitions aren't validated until first use""" class Test(msgspec.Struct): a: slice with pytest.raises(TypeError): msgspec.Decoder(Test)
def test_roundtrip_typed_decoder(self, size): dec = msgspec.Decoder(msgspec.Ext) ext = msgspec.Ext(5, b"x" * size) buf = msgspec.encode(ext) out = dec.decode(buf) assert out == ext
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_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 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_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_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 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_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_typed_decoder_skips_ext_hook(self): def ext_hook(code, data): assert False, "shouldn't ever get called" msg = [None, msgspec.Ext(1, b"test")] dec = msgspec.Decoder(List[Optional[msgspec.Ext]]) buf = msgspec.encode(msg) out = dec.decode(buf) assert out == msg
def check_Decoder_decode_type_comment() -> None: dec = msgspec.Decoder() # type: msgspec.Decoder[List[int]] b = msgspec.encode([1, 2, 3]) o = dec.decode(b) reveal_type( dec ) # assert "Decoder" in typ and ("List" in typ or "list" in typ) and "int" in typ reveal_type(o) # assert ("List" in typ or "list" in typ) and "int" in typ
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_decode_hashable_struct_in_key(self): class Test(msgspec.Struct): data: List[int] def __hash__(self): return hash(tuple(self.data)) orig = {(1, Test([1, 2])): [1, 2]} data = msgspec.encode(orig) out = msgspec.Decoder(Dict[Tuple[int, Test], List[int]]).decode(data) assert orig == out
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 __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_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 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_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)