Module mirai.models.base
此模块提供 YiriMirai 中使用的 pydantic 模型的基类。
Expand source code
# -*- coding: utf-8 -*-
"""
此模块提供 YiriMirai 中使用的 pydantic 模型的基类。
"""
from typing import Dict, List, Type
import pydantic.main as pdm
from pydantic import BaseModel
class MiraiMetaclass(pdm.ModelMetaclass):
"""此类是 YiriMirai 中使用的 pydantic 模型的元类的基类。"""
def to_camel(name: str) -> str:
"""将下划线命名风格转换为小驼峰命名。"""
if name[:2] == '__': # 不处理双下划线开头的特殊命名。
return name
name_parts = name.split('_')
return ''.join(name_parts[:1] + [x.title() for x in name_parts[1:]])
class MiraiBaseModel(BaseModel, metaclass=MiraiMetaclass):
"""模型基类。
启用了三项配置:
1. 允许解析时传入额外的值,并将额外值保存在模型中。
2. 允许通过别名访问字段。
3. 自动生成小驼峰风格的别名,以符合 mirai-api-http 的命名。
"""
def __init__(self, *args, **kwargs):
""""""
super().__init__(*args, **kwargs)
def __repr__(self) -> str:
return self.__class__.__name__ + '(' + ', '.join(
(f'{k}={repr(v)}' for k, v in self.__dict__.items() if v)
) + ')'
class Config:
extra = 'allow'
allow_population_by_field_name = True
alias_generator = to_camel
class MiraiIndexedMetaclass(MiraiMetaclass):
"""可以通过子类名获取子类的类的元类。"""
__indexedbases__: List[Type['MiraiIndexedModel']] = []
__indexedmodel__ = None
def __new__(cls, name, bases, attrs, **kwargs):
new_cls = super().__new__(cls, name, bases, attrs, **kwargs)
# 第一类:MiraiIndexedModel
if name == 'MiraiIndexedModel':
cls.__indexedmodel__ = new_cls
new_cls.__indexes__ = {}
return new_cls
# 第二类:MiraiIndexedModel 的直接子类,这些是可以通过子类名获取子类的类。
if cls.__indexedmodel__ in bases:
cls.__indexedbases__.append(new_cls)
new_cls.__indexes__ = {}
return new_cls
# 第三类:MiraiIndexedModel 的直接子类的子类,这些添加到直接子类的索引中。
for base in cls.__indexedbases__:
if issubclass(new_cls, base):
base.__indexes__[name] = new_cls
return new_cls
def __getitem__(cls, name):
return cls.get_subtype(name)
class MiraiIndexedModel(MiraiBaseModel, metaclass=MiraiIndexedMetaclass):
"""可以通过子类名获取子类的类。"""
__indexes__: Dict[str, Type['MiraiIndexedModel']]
@classmethod
def get_subtype(cls, name: str) -> Type['MiraiIndexedModel']:
"""根据类名称,获取相应的子类类型。
Args:
name: 类名称。
Returns:
Type['MiraiIndexedModel']: 子类类型。
"""
try:
type_ = cls.__indexes__.get(name)
if not (type_ and issubclass(type_, cls)):
raise ValueError(f'`{name}` 不是 `{cls.__name__}` 的子类!')
return type_
except AttributeError as e:
raise ValueError(f'`{name}` 不是 `{cls.__name__}` 的子类!') from None
@classmethod
def parse_subtype(cls, obj: dict) -> 'MiraiIndexedModel':
"""通过字典,构造对应的模型对象。
Args:
obj: 一个字典,包含了模型对象的属性。
Returns:
MiraiIndexedModel: 构造的对象。
"""
if cls in MiraiIndexedModel.__subclasses__():
ModelType = cls.get_subtype(obj['type'])
return ModelType.parse_obj(obj)
return super().parse_obj(obj)
Functions
def to_camel(name: str) ‑> str
-
将下划线命名风格转换为小驼峰命名。
Expand source code
def to_camel(name: str) -> str: """将下划线命名风格转换为小驼峰命名。""" if name[:2] == '__': # 不处理双下划线开头的特殊命名。 return name name_parts = name.split('_') return ''.join(name_parts[:1] + [x.title() for x in name_parts[1:]])
Classes
class MiraiBaseModel (*args, **kwargs)
-
模型基类。
启用了三项配置: 1. 允许解析时传入额外的值,并将额外值保存在模型中。 2. 允许通过别名访问字段。 3. 自动生成小驼峰风格的别名,以符合 mirai-api-http 的命名。
Expand source code
class MiraiBaseModel(BaseModel, metaclass=MiraiMetaclass): """模型基类。 启用了三项配置: 1. 允许解析时传入额外的值,并将额外值保存在模型中。 2. 允许通过别名访问字段。 3. 自动生成小驼峰风格的别名,以符合 mirai-api-http 的命名。 """ def __init__(self, *args, **kwargs): """""" super().__init__(*args, **kwargs) def __repr__(self) -> str: return self.__class__.__name__ + '(' + ', '.join( (f'{k}={repr(v)}' for k, v in self.__dict__.items() if v) ) + ')' class Config: extra = 'allow' allow_population_by_field_name = True alias_generator = to_camel
Ancestors
- pydantic.main.BaseModel
- pydantic.utils.Representation
Subclasses
- DownloadInfo
- FileProperties
- ProfileResponse
- Response
- SessionInfoResponse.Data
- MiraiIndexedModel
- Config
- Entity
- Subject
- mirai.models.message.ForwardMessageDiaplay
- ForwardMessageNode
- MessageChain
Class variables
var Config
class MiraiIndexedMetaclass (*args, **kwargs)
-
可以通过子类名获取子类的类的元类。
Expand source code
class MiraiIndexedMetaclass(MiraiMetaclass): """可以通过子类名获取子类的类的元类。""" __indexedbases__: List[Type['MiraiIndexedModel']] = [] __indexedmodel__ = None def __new__(cls, name, bases, attrs, **kwargs): new_cls = super().__new__(cls, name, bases, attrs, **kwargs) # 第一类:MiraiIndexedModel if name == 'MiraiIndexedModel': cls.__indexedmodel__ = new_cls new_cls.__indexes__ = {} return new_cls # 第二类:MiraiIndexedModel 的直接子类,这些是可以通过子类名获取子类的类。 if cls.__indexedmodel__ in bases: cls.__indexedbases__.append(new_cls) new_cls.__indexes__ = {} return new_cls # 第三类:MiraiIndexedModel 的直接子类的子类,这些添加到直接子类的索引中。 for base in cls.__indexedbases__: if issubclass(new_cls, base): base.__indexes__[name] = new_cls return new_cls def __getitem__(cls, name): return cls.get_subtype(name)
Ancestors
- MiraiMetaclass
- pydantic.main.ModelMetaclass
- abc.ABCMeta
- builtins.type
Subclasses
- ApiMetaclass
- mirai.models.message.MessageComponentMetaclass
class MiraiIndexedModel (*args, **kwargs)
-
可以通过子类名获取子类的类。
Expand source code
class MiraiIndexedModel(MiraiBaseModel, metaclass=MiraiIndexedMetaclass): """可以通过子类名获取子类的类。""" __indexes__: Dict[str, Type['MiraiIndexedModel']] @classmethod def get_subtype(cls, name: str) -> Type['MiraiIndexedModel']: """根据类名称,获取相应的子类类型。 Args: name: 类名称。 Returns: Type['MiraiIndexedModel']: 子类类型。 """ try: type_ = cls.__indexes__.get(name) if not (type_ and issubclass(type_, cls)): raise ValueError(f'`{name}` 不是 `{cls.__name__}` 的子类!') return type_ except AttributeError as e: raise ValueError(f'`{name}` 不是 `{cls.__name__}` 的子类!') from None @classmethod def parse_subtype(cls, obj: dict) -> 'MiraiIndexedModel': """通过字典,构造对应的模型对象。 Args: obj: 一个字典,包含了模型对象的属性。 Returns: MiraiIndexedModel: 构造的对象。 """ if cls in MiraiIndexedModel.__subclasses__(): ModelType = cls.get_subtype(obj['type']) return ModelType.parse_obj(obj) return super().parse_obj(obj)
Ancestors
- MiraiBaseModel
- pydantic.main.BaseModel
- pydantic.utils.Representation
Subclasses
Static methods
def get_subtype(name: str) ‑> Type[MiraiIndexedModel]
-
根据类名称,获取相应的子类类型。
Args
name
- 类名称。
Returns
Type['MiraiIndexedModel']: 子类类型。
Expand source code
@classmethod def get_subtype(cls, name: str) -> Type['MiraiIndexedModel']: """根据类名称,获取相应的子类类型。 Args: name: 类名称。 Returns: Type['MiraiIndexedModel']: 子类类型。 """ try: type_ = cls.__indexes__.get(name) if not (type_ and issubclass(type_, cls)): raise ValueError(f'`{name}` 不是 `{cls.__name__}` 的子类!') return type_ except AttributeError as e: raise ValueError(f'`{name}` 不是 `{cls.__name__}` 的子类!') from None
def parse_subtype(obj: dict) ‑> MiraiIndexedModel
-
Expand source code
@classmethod def parse_subtype(cls, obj: dict) -> 'MiraiIndexedModel': """通过字典,构造对应的模型对象。 Args: obj: 一个字典,包含了模型对象的属性。 Returns: MiraiIndexedModel: 构造的对象。 """ if cls in MiraiIndexedModel.__subclasses__(): ModelType = cls.get_subtype(obj['type']) return ModelType.parse_obj(obj) return super().parse_obj(obj)
class MiraiMetaclass (*args, **kwargs)
-
此类是 YiriMirai 中使用的 pydantic 模型的元类的基类。
Expand source code
class MiraiMetaclass(pdm.ModelMetaclass): """此类是 YiriMirai 中使用的 pydantic 模型的元类的基类。"""
Ancestors
- pydantic.main.ModelMetaclass
- abc.ABCMeta
- builtins.type
Subclasses