jcrist / msgspec

A fast serialization and validation library, with builtin support for JSON, MessagePack, YAML, and TOML

Home Page:https://jcristharif.com/msgspec/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

typing.Annotated not working as expected.

MPlatypus opened this issue · comments

commented

Question

Basically, I am trying to set the alias of the Struct field, via typing.Annotated[], however, the following code fails.

from __future__ import annotations

import msgspec
import hikari
import json
import typing as t


class PayloadBase(msgspec.Struct):
    @classmethod
    def _from_payload(cls, payload: str) -> t.Self:
        return msgspec.json.decode(payload, type=cls, strict=False, dec_hook=cls._decode_hook)

    @property
    def _to_payload(self) -> str:
        return msgspec.json.encode(self, enc_hook=self._encode_hook).decode()

    @classmethod
    def _decode_hook(cls, type: t.Type[t.Any], obj: t.Any) -> t.Any:
        if type == hikari.Snowflake:
            return hikari.Snowflake(int(obj))
        raise ValueError("Sorry, but this value does not exist.")

    @classmethod
    def _encode_hook(cls, type: t.Type[hikari.Snowflake]) -> t.Any:
        return str(type)


class Ready(PayloadBase):
    session_id: str = msgspec.field(name="sessionId")
    resumed: bool = msgspec.field()
    guild_id: t.Annotated[hikari.Snowflake, msgspec.field(name="guildId")]


bot = hikari.GatewayBot("...", banner=None, suppress_optimization_warning=True)

payload = {
    "sessionId":"beanos",
    "resumed":True,
    "guildId":"1234567890"
}

ready = Ready._from_payload(json.dumps(payload))

print(ready.guild_id, type(ready.guild_id))

print(ready.session_id)
assert ready.session_id == "beanos"
assert ready.resumed is True
assert ready.guild_id == hikari.Snowflake(1234567890)

It decodes the session properly, however, it does not decode the guild properly, and fails on it, because its using t.Annotated. Am I doing something wrong, or is this expected behavior?