Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

无法从 dict 反序列化为 Message #127

Closed
MeetWq opened this issue Sep 15, 2024 · 5 comments · Fixed by #128
Closed

无法从 dict 反序列化为 Message #127

MeetWq opened this issue Sep 15, 2024 · 5 comments · Fixed by #128

Comments

@MeetWq
Copy link
Contributor

MeetWq commented Sep 15, 2024

如以下的代码:

def test_message_deserialize():
    """测试消息反序列化"""
    from nonebot.adapters.qq import Message, MessageSegment
    from nonebot.compat import type_validate_python

    msg = type_validate_python(Message, [{"type": "text", "data": {"text": "test"}}])
    assert msg == Message(MessageSegment.text("test"))

会出现如下报错:

_________________________________________ test_message_deserialize _________________________________________

    def test_message_deserialize():
        """测试消息反序列化"""
        from nonebot.adapters.qq import Message, MessageSegment
        from nonebot.compat import type_validate_python

>       msg = type_validate_python(Message, [{"type": "text", "data": {"text": "test"}}])

tests/test_qq.py:338:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.10/site-packages/nonebot/compat.py:225: in type_validate_python
    return TypeAdapter(type_).validate_python(data)
.venv/lib/python3.10/site-packages/pydantic/type_adapter.py:135: in wrapped
    return func(self, *args, **kwargs)
.venv/lib/python3.10/site-packages/pydantic/type_adapter.py:366: in validate_python
    return self.validator.validate_python(object, strict=strict, from_attributes=from_attributes, context=context)
.venv/lib/python3.10/site-packages/nonebot/internal/adapter/message.py:166: in _validate
    value = [type_validate_python(cls.get_segment_class(), v) for v in value]
.venv/lib/python3.10/site-packages/nonebot/internal/adapter/message.py:166: in <listcomp>
    value = [type_validate_python(cls.get_segment_class(), v) for v in value]
.venv/lib/python3.10/site-packages/nonebot/compat.py:225: in type_validate_python
    return TypeAdapter(type_).validate_python(data)
.venv/lib/python3.10/site-packages/pydantic/type_adapter.py:135: in wrapped
    return func(self, *args, **kwargs)
.venv/lib/python3.10/site-packages/pydantic/type_adapter.py:366: in validate_python
    return self.validator.validate_python(object, strict=strict, from_attributes=from_attributes, context=context)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'nonebot.adapters.qq.message.MessageSegment'>
value = {'data': {'text': 'test'}, 'type': 'text'}

    @classmethod
    def _validate(cls, value) -> Self:
        if isinstance(value, cls):
            return value
        if isinstance(value, MessageSegment):
            raise ValueError(f"Type {type(value)} can not be converted to {cls}")
        if not isinstance(value, dict):
            raise ValueError(f"Expected dict for MessageSegment, got {type(value)}")
        if "type" not in value:
            raise ValueError(
                f"Expected dict with 'type' for MessageSegment, got {value}"
            )
>       return cls(type=value["type"], data=value.get("data", {}))
E       TypeError: Can't instantiate abstract class MessageSegment with abstract method __str__

.venv/lib/python3.10/site-packages/nonebot/internal/adapter/message.py:76: TypeError

预期结果:
希望如下关系成立:

type_validate_python(Message, [{"type": "text", "data": {"text": "test"}}]) == Message(MessageSegment.text("test"))
@yanyongyu
Copy link
Member

QQ 适配器的 MessageSegment 是 abstract class 所以是无法实例化的,需要使用子类型才行

@MeetWq
Copy link
Contributor Author

MeetWq commented Sep 15, 2024

QQ 适配器的 MessageSegment 是 abstract class 所以是无法实例化的,需要使用子类型才行

不能根据 type 实例化成对应的子类型吗?

@yanyongyu
Copy link
Member

看了下似乎可以覆盖掉 segment 父类的 validate 方法来做到,不过这就是体力活了。

@MeetWq
Copy link
Contributor Author

MeetWq commented Sep 15, 2024

不太确定这个是否应该由适配器实现,还是让需要反序列化的插件自行实现?

@yanyongyu
Copy link
Member

欢迎PR到适配器(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants