def test_decoder_ext_hook_raises(self): class CustomError(Exception): pass def ext_hook(code, buf): raise CustomError msg = msgspec.encode(range(5), default=lambda x: msgspec.Ext(1, b"test")) with pytest.raises(CustomError): msgspec.decode(msg, ext_hook=ext_hook)
def test_decode_parse_arguments_errors(self): with pytest.raises(TypeError, match="Missing 1 required argument"): msgspec.decode() with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.decode(self.buf, List[int]) with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.decode(self.buf, 2, 3) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.decode(self.buf, bad=1) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.decode(self.buf, type=List[int], extra=1)
def test_roundtrip(self, size): data = b"x" * size code = 5 buf = msgspec.encode(msgspec.Ext(code, data)) out = msgspec.decode(buf) assert out.code == code assert out.data == data
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_decoder_ext_hook(self, use_function): obj = {"x": range(10)} exp_buf = pickle.dumps(range(10)) def default(x): return msgspec.Ext(5, pickle.dumps(x)) def ext_hook(code, buf): assert isinstance(buf, memoryview) assert bytes(buf) == exp_buf assert code == 5 return pickle.loads(buf) msg = msgspec.encode(obj, default=default) if use_function: out = msgspec.decode(msg, ext_hook=ext_hook) else: dec = msgspec.Decoder(ext_hook=ext_hook) out = dec.decode(msg) assert out == obj
def test_decoder_ext_hook_bad_signature(self): msg = msgspec.encode(range(5), default=lambda x: msgspec.Ext(1, b"test")) with pytest.raises(TypeError): msgspec.decode(msg, ext_hook=lambda: None)
def test_decode_invalid_buf(self): with pytest.raises(TypeError): msgspec.decode(1)
def test_decode_type_any(self): assert msgspec.decode(self.buf, type=Any) == [1, 2, 3]
def test_decode_invalid_type(self): with pytest.raises(TypeError, match="Type '1' is not supported"): msgspec.decode(self.buf, type=1)
def test_decode(self): assert msgspec.decode(self.buf) == [1, 2, 3]
def test_decode_type_keyword(self): assert msgspec.decode(self.buf, type=List[int]) == [1, 2, 3] with pytest.raises(msgspec.DecodingError): assert msgspec.decode(self.buf, type=List[str])
def test_decode_tuple_set_keys_as_tuples(self): orig = {(1, 2), (3, (4, 5)), 6} data = msgspec.encode(orig) out = msgspec.decode(data, type=set) assert orig == out
def test_decode_tuple_dict_keys_as_tuples(self): orig = {(1, 2): [1, 2, [3, 4]], (1, (2, 3)): [4, 5, 6]} data = msgspec.encode(orig) out = msgspec.decode(data) assert orig == out
def check_decode_ext_hook() -> None: def ext_hook(code: int, data: memoryview) -> Any: return pickle.loads(data) msgspec.decode(b"test", ext_hook=ext_hook) msgspec.Decoder(ext_hook=ext_hook)
def check_decode_typed() -> None: b = msgspec.encode([1, 2, 3]) o = msgspec.decode(b, type=List[int]) reveal_type(o) # assert ("List" in typ or "list" in typ) and "int" in typ
def check_decode_any() -> None: b = msgspec.encode([1, 2, 3]) o = msgspec.decode(b) reveal_type(o) # assert "Any" in typ