Skip to content

Commit

Permalink
feat: 更新到 Pydantic v2 (#42)
Browse files Browse the repository at this point in the history
* feat: 更新到 Pydantic v2

* chore: 更新依赖
  • Loading branch information
st1020 committed Jul 16, 2023
1 parent 1cde1ef commit 6f7243b
Show file tree
Hide file tree
Showing 24 changed files with 620 additions and 585 deletions.
19 changes: 10 additions & 9 deletions alicebot/adapter/utils.py
Expand Up @@ -69,15 +69,16 @@ class WebSocketClientAdapter(Adapter[T_Event, T_Config], metaclass=ABCMeta):

async def run(self):
"""运行适配器。"""
async with aiohttp.ClientSession() as session:
async with session.ws_connect(self.url) as ws:
msg: aiohttp.WSMessage
async for msg in ws:
if self.bot.should_exit.is_set():
break
if msg.type == aiohttp.WSMsgType.ERROR:
break
await self.handle_response(msg)
async with aiohttp.ClientSession() as session, session.ws_connect(
self.url
) as ws:
msg: aiohttp.WSMessage
async for msg in ws:
if self.bot.should_exit.is_set():
break
if msg.type == aiohttp.WSMsgType.ERROR:
break
await self.handle_response(msg)

@abstractmethod
async def handle_response(self, msg: aiohttp.WSMessage):
Expand Down
10 changes: 4 additions & 6 deletions alicebot/bot.py
Expand Up @@ -360,7 +360,7 @@ def update_config(
source: Union[List[Type[Plugin[Any, Any, Any]]], List[Adapter[Any, Any]]],
name: str,
base: Type[ConfigModel],
) -> ConfigModel:
) -> Type[ConfigModel]:
config_update_dict = {}
for i in source:
config_class = getattr(i, "Config", None)
Expand All @@ -373,14 +373,12 @@ def update_config(
config_class,
default_value,
)
return create_model(name, **config_update_dict, __base__=base)(
**self._raw_config_dict
)
return create_model(name, **config_update_dict, __base__=base)

self.config = create_model(
"Config",
plugin=update_config(self.plugins, "PluginConfig", PluginConfig),
adapter=update_config(self.adapters, "AdapterConfig", AdapterConfig),
plugin=(update_config(self.plugins, "PluginConfig", PluginConfig), {}),
adapter=(update_config(self.adapters, "AdapterConfig", AdapterConfig), {}),
__base__=MainConfig,
)(**self._raw_config_dict)
# 更新 log 级别
Expand Down
7 changes: 3 additions & 4 deletions alicebot/config.py
Expand Up @@ -4,7 +4,7 @@
"""
from typing import Set, Union

from pydantic import BaseModel, DirectoryPath, Extra, Field
from pydantic import BaseModel, ConfigDict, DirectoryPath, Extra, Field

__all__ = [
"ConfigModel",
Expand All @@ -23,10 +23,9 @@ class ConfigModel(BaseModel):
__config_name__: 配置名称。
"""

__config_name__: str = ""
model_config = ConfigDict(extra=Extra.allow)

class Config:
extra = Extra.allow
__config_name__: str = ""


class LogConfig(ConfigModel):
Expand Down
44 changes: 9 additions & 35 deletions alicebot/event.py
Expand Up @@ -3,14 +3,12 @@
事件类的基类。适配器开发者应实现此事件类基类的子类。
"""
from abc import ABC, abstractmethod
from typing import Any, Generic, Optional, Union, final
from typing import TYPE_CHECKING, Any, Generic, Optional, Union
from typing_extensions import Self

from pydantic import BaseModel, PrivateAttr
from pydantic import BaseModel, ConfigDict, Extra

from alicebot.message import Message
from alicebot.typing import T_Adapter
from alicebot.utils import DataclassEncoder

__all__ = ["Event", "MessageEvent"]

Expand All @@ -24,47 +22,23 @@ class Event(ABC, BaseModel, Generic[T_Adapter]):
__handled__: 表示事件是否被处理过了,用于适配器处理。警告:请勿手动更改此属性的值。
"""

adapter: T_Adapter # type: ignore
# 这里的 adapter 类型定义只是为了 IDE 的类型检查工具能够正常工作,这个字段将永远不会被实际使用
# IDE 对 BaseModel 实例化时的提示会将 BaseModel 视为 dataclasses,而忽略 __init__ 定义
# 因此需要此定义防止类型提示出错
# 参考:
# https://pydantic-docs.helpmanual.io/visual_studio_code/#technical-details
# https://koxudaxi.github.io/pydantic-pycharm-plugin/ignore-init-arguments/
model_config = ConfigDict(extra=Extra.allow)

if TYPE_CHECKING:
adapter: T_Adapter
else:
adapter: Any
type: Optional[str]

_adapter: T_Adapter = PrivateAttr() # adapter 实际上放在这里
__handled__: bool = PrivateAttr(default=False)

def __init__(self, adapter: T_Adapter, **data: Any):
"""初始化。
Args:
adapter: 产生此事件的适配器对象。
**data: 事件数据。
"""
self._adapter = adapter
super().__init__(**data)

@final
@property
def adapter(self) -> T_Adapter:
"""产生当前事件的适配器对象。"""
return self._adapter
__handled__: bool = False

def __str__(self) -> str:
return f"Event<{self.type}>"

def __repr__(self) -> str:
return self.__str__()

class Config:
extra = "allow"
json_encoders = {Message: DataclassEncoder}


class MessageEvent(Event[T_Adapter]):
class MessageEvent(Event[T_Adapter], Generic[T_Adapter]):
"""通用的消息事件类的基类。"""

@abstractmethod
Expand Down

0 comments on commit 6f7243b

Please sign in to comment.