1111)
1212from nonebot import get_plugin
1313from nonebot .plugin import Plugin
14- from pydantic import BaseModel , Field
14+ from pydantic import BaseModel , ConfigDict , Field
1515
16+ from ..utils import normalize_plugin_name
1617from .pinyin import PinyinChunkSequence
1718
1819T = TypeVar ("T" )
1920
2021
2122if PYDANTIC_V2 :
23+ compat_model_config : ConfigDict = {}
2224 CompatModel = BaseModel
2325else :
24- CompatModel = get_model_with_config (
25- {
26- "arbitrary_types_allowed" : True ,
27- "keep_untouched" : (cached_property ,),
28- },
29- )
26+ compat_model_config : ConfigDict = {
27+ "arbitrary_types_allowed" : True ,
28+ "keep_untouched" : (cached_property ,),
29+ }
30+ CompatModel = get_model_with_config (compat_model_config )
3031
3132
3233class PMDataItem (CompatModel ):
@@ -77,6 +78,25 @@ def normalize_input(cls, values: Any): # noqa: N805
7778 return values
7879
7980
81+ class OptionalPMNPluginInfo (CompatModel ):
82+ name : str | None = None
83+ plugin_id : str | None = None
84+ author : str | None = None
85+ version : str | None = None
86+ description : str | None = None
87+ usage : str | None = None
88+ pm_data : list [PMDataItem ] | None = None
89+ pmn : PMNData = PMNData ()
90+
91+ def to_required (self , name : str | None = None ):
92+ if name is None and self .name is None :
93+ raise ValueError ("`name` is required for PMNPluginInfo" )
94+ data = {k : getattr (self , k ) for k in model_fields_set (self )}
95+ if name :
96+ data ["name" ] = name
97+ return PMNPluginInfo (** data )
98+
99+
80100class PMNPluginInfo (CompatModel ):
81101 name : str
82102 plugin_id : str | None = None
@@ -112,22 +132,37 @@ def plugin(self) -> Plugin | None:
112132
113133
114134class ExternalPluginInfo (CompatModel ):
115- name : str
135+ name : str | None = None
116136 author : str | None = None
117137 version : str | None = None
118138 description : str | None = None
119139 usage : str | None = None
120140 funcs : list [PMDataItem ] | None = None
121141 pmn : PMNData = PMNData ()
122142
123- def to_plugin_info (self , plugin_id : str | None = None ):
143+ def to_optional_plugin_info (self , plugin_id : str | None = None ):
124144 key_name_map = {"funcs" : "pm_data" }
125145 data = {
126146 key_name_map .get (k , k ): getattr (self , k ) for k in model_fields_set (self )
127147 }
128148 if plugin_id :
129149 data ["plugin_id" ] = plugin_id
130- return PMNPluginInfo (** data )
150+ return OptionalPMNPluginInfo (** data )
151+
152+ def to_plugin_info (self , plugin_id : str | None = None , name : str | None = None ):
153+ if name is None :
154+ if self .name is not None :
155+ name = self .name
156+ elif plugin_id :
157+ name = normalize_plugin_name (plugin_id )
158+ if name is None :
159+ raise ValueError (
160+ "`name` is required for PMNPluginInfo"
161+ ", please set `name` to this model instance or pass it in"
162+ ", or pass `plugin_id` to generate one" ,
163+ )
164+ info = self .to_optional_plugin_info (plugin_id )
165+ return info .to_required (name = name )
131166
132167 def merge_to (
133168 self ,
@@ -137,7 +172,7 @@ def merge_to(
137172 ):
138173 if copy :
139174 other = model_copy (other )
140- this = self .to_plugin_info (plugin_id )
175+ this = self .to_optional_plugin_info (plugin_id )
141176 for k in model_fields_set (this ):
142177 setattr (other , k , getattr (this , k ))
143178 return other
0 commit comments