satori-python-core 0.13.2__tar.gz → 0.14.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satori-python-core
3
- Version: 0.13.2
3
+ Version: 0.14.0
4
4
  Summary: Satori Protocol SDK for python, specify common part
5
5
  Home-page: https://github.com/RF-Tar-Railt/satori-python
6
6
  Author-Email: RF-Tar-Railt <rf_tar_railt@qq.com>
@@ -23,7 +23,7 @@ classifiers = [
23
23
  "Programming Language :: Python :: 3.12",
24
24
  "Operating System :: OS Independent",
25
25
  ]
26
- version = "0.13.2"
26
+ version = "0.14.0"
27
27
 
28
28
  [project.license]
29
29
  text = "MIT"
@@ -85,7 +85,7 @@ extra_standard_library = [
85
85
 
86
86
  [tool.ruff]
87
87
  line-length = 110
88
- target-version = "py38"
88
+ target-version = "py39"
89
89
  exclude = [
90
90
  "exam.py",
91
91
  ]
@@ -110,7 +110,7 @@ ignore = [
110
110
 
111
111
  [tool.pyright]
112
112
  pythonPlatform = "All"
113
- pythonVersion = "3.8"
113
+ pythonVersion = "3.9"
114
114
  typeCheckingMode = "basic"
115
115
  reportShadowedImports = false
116
116
  disableBytesTypePromotions = true
@@ -43,4 +43,4 @@ from .model import Role as Role
43
43
  from .model import Upload as Upload
44
44
  from .model import User as User
45
45
 
46
- __version__ = "0.13.2"
46
+ __version__ = "0.14.0"
@@ -2,7 +2,7 @@ from base64 import b64encode
2
2
  from dataclasses import InitVar, dataclass, field, fields
3
3
  from io import BytesIO
4
4
  from pathlib import Path
5
- from typing import Any, ClassVar, Dict, List, Optional, Tuple, Type, TypeVar, Union, get_args, overload
5
+ from typing import Any, ClassVar, Optional, TypeVar, Union, get_args, overload
6
6
  from typing_extensions import override
7
7
 
8
8
  from .parser import Element as RawElement
@@ -14,13 +14,13 @@ TE = TypeVar("TE", bound="Element")
14
14
 
15
15
  @dataclass(repr=False)
16
16
  class Element:
17
- _attrs: Dict[str, Any] = field(init=False, default_factory=dict)
18
- _children: List["Element"] = field(init=False, default_factory=list)
17
+ _attrs: dict[str, Any] = field(init=False, default_factory=dict)
18
+ _children: list["Element"] = field(init=False, default_factory=list)
19
19
 
20
- __names__: ClassVar[Tuple[str, ...]]
20
+ __names__: ClassVar[tuple[str, ...]]
21
21
 
22
22
  @property
23
- def children(self) -> List["Element"]:
23
+ def children(self) -> list["Element"]:
24
24
  return self._children
25
25
 
26
26
  @property
@@ -28,7 +28,7 @@ class Element:
28
28
  return self.__class__.__name__.lower()
29
29
 
30
30
  @classmethod
31
- def unpack(cls, attrs: Dict[str, Any]):
31
+ def unpack(cls, attrs: dict[str, Any]):
32
32
  obj = cls(**{k: v for k, v in attrs.items() if k in cls.__names__}) # type: ignore
33
33
  obj._attrs.update({k: v for k, v in attrs.items() if k not in cls.__names__})
34
34
  return obj
@@ -166,7 +166,7 @@ class Link(Element):
166
166
  class Resource(Element):
167
167
  src: str
168
168
  title: Optional[str] = None
169
- extra: InitVar[Optional[Dict[str, Any]]] = None
169
+ extra: InitVar[Optional[dict[str, Any]]] = None
170
170
  cache: Optional[bool] = None
171
171
  timeout: Optional[int] = None
172
172
 
@@ -181,19 +181,19 @@ class Resource(Element):
181
181
  mime: Optional[str] = None,
182
182
  name: Optional[str] = None,
183
183
  poster: Optional[str] = None,
184
- extra: Optional[Dict[str, Any]] = None,
184
+ extra: Optional[dict[str, Any]] = None,
185
185
  cache: Optional[bool] = None,
186
186
  timeout: Optional[int] = None,
187
187
  **kwargs,
188
188
  ):
189
- data: Dict[str, Any] = {"extra": extra}
189
+ data: dict[str, Any] = {"extra": extra or kwargs}
190
190
  if url is not None:
191
- data = {"src": url}
191
+ data |= {"src": url}
192
192
  elif path:
193
- data = {"src": Path(path).as_uri()}
193
+ data |= {"src": Path(path).as_uri()}
194
194
  elif raw and mime:
195
195
  bd = raw.getvalue() if isinstance(raw, BytesIO) else raw
196
- data = {"src": f"data:{mime};base64,{b64encode(bd).decode('utf-8')}"}
196
+ data |= {"src": f"data:{mime};base64,{b64encode(bd).decode('utf-8')}"}
197
197
  else:
198
198
  raise ValueError(f"{cls} need at least one of url, path and raw")
199
199
  if name is not None:
@@ -206,7 +206,7 @@ class Resource(Element):
206
206
  data["timeout"] = timeout
207
207
  return cls(**data)
208
208
 
209
- def __post_init__(self, extra: Optional[Dict[str, Any]] = None):
209
+ def __post_init__(self, extra: Optional[dict[str, Any]] = None):
210
210
  super().__post_init__()
211
211
  if extra:
212
212
  self._attrs.update(extra)
@@ -380,7 +380,7 @@ class Message(Element):
380
380
  self,
381
381
  id: Optional[str] = None,
382
382
  forward: Optional[bool] = None,
383
- content: Optional[List[Union[str, Element]]] = None,
383
+ content: Optional[list[Union[str, Element]]] = None,
384
384
  ):
385
385
  self.id = id
386
386
  self.forward = forward
@@ -464,8 +464,8 @@ class Custom(Element):
464
464
  def __init__(
465
465
  self,
466
466
  type: str,
467
- attrs: Optional[Dict[str, Any]] = None,
468
- children: Optional[List[Union[str, Element]]] = None,
467
+ attrs: Optional[dict[str, Any]] = None,
468
+ children: Optional[list[Union[str, Element]]] = None,
469
469
  ):
470
470
  self.type = type
471
471
  super().__init__()
@@ -536,7 +536,7 @@ STYLE_TYPE_MAP = {
536
536
  }
537
537
 
538
538
 
539
- def transform(elements: List[RawElement]) -> List[Element]:
539
+ def transform(elements: list[RawElement]) -> list[Element]:
540
540
  msg = []
541
541
  for elem in elements:
542
542
  tag = elem.tag()
@@ -568,14 +568,14 @@ def transform(elements: List[RawElement]) -> List[Element]:
568
568
 
569
569
 
570
570
  @overload
571
- def select(elements: Union[Element, List[Element]], query: Type[TE]) -> List[TE]: ...
571
+ def select(elements: Union[Element, list[Element]], query: type[TE]) -> list[TE]: ...
572
572
 
573
573
 
574
574
  @overload
575
- def select(elements: Union[Element, List[Element]], query: str) -> List[Element]: ...
575
+ def select(elements: Union[Element, list[Element]], query: str) -> list[Element]: ...
576
576
 
577
577
 
578
- def select(elements: Union[Element, List[Element]], query: Union[Type[TE], str]):
578
+ def select(elements: Union[Element, list[Element]], query: Union[type[TE], str]):
579
579
  if not elements:
580
580
  return []
581
581
  if isinstance(elements, Element):
@@ -4,7 +4,7 @@ from datetime import datetime
4
4
  from enum import IntEnum
5
5
  from os import PathLike
6
6
  from pathlib import Path
7
- from typing import IO, Any, Callable, ClassVar, Dict, Generic, List, Literal, Optional, TypeVar, Union
7
+ from typing import IO, Any, Callable, ClassVar, Generic, Literal, Optional, TypeVar, Union
8
8
  from typing_extensions import TypeAlias
9
9
 
10
10
  from .element import Element, transform
@@ -14,7 +14,7 @@ from .parser import parse
14
14
 
15
15
  @dataclass
16
16
  class ModelBase:
17
- __converter__: ClassVar[Dict[str, Callable[[Any], Any]]] = {}
17
+ __converter__: ClassVar[dict[str, Callable[[Any], Any]]] = {}
18
18
 
19
19
  @classmethod
20
20
  def parse(cls, raw: dict):
@@ -81,7 +81,7 @@ class User(ModelBase):
81
81
  is_bot: Optional[bool] = None
82
82
 
83
83
  def dump(self):
84
- res: Dict[str, Any] = {"id": self.id}
84
+ res: dict[str, Any] = {"id": self.id}
85
85
  if self.name:
86
86
  res["name"] = self.name
87
87
  if self.nick:
@@ -141,13 +141,13 @@ class Login(ModelBase):
141
141
  user: Optional[User] = None
142
142
  self_id: Optional[str] = None
143
143
  platform: Optional[str] = None
144
- features: List[str] = field(default_factory=list)
145
- proxy_urls: List[str] = field(default_factory=list)
144
+ features: list[str] = field(default_factory=list)
145
+ proxy_urls: list[str] = field(default_factory=list)
146
146
 
147
147
  __converter__ = {"user": User.parse, "status": LoginStatus}
148
148
 
149
149
  def dump(self):
150
- res: Dict[str, Any] = {
150
+ res: dict[str, Any] = {
151
151
  "status": self.status.value,
152
152
  "features": self.features,
153
153
  "proxy_urls": self.proxy_urls,
@@ -195,7 +195,7 @@ class Identify(ModelBase):
195
195
 
196
196
  @dataclass
197
197
  class Ready(ModelBase):
198
- logins: List[Login]
198
+ logins: list[Login]
199
199
 
200
200
 
201
201
  @dataclass
@@ -213,7 +213,7 @@ class MessageObject(ModelBase):
213
213
  def from_elements(
214
214
  cls,
215
215
  id: str,
216
- content: List[Element],
216
+ content: list[Element],
217
217
  channel: Optional[Channel] = None,
218
218
  guild: Optional[Guild] = None,
219
219
  member: Optional[Member] = None,
@@ -224,7 +224,7 @@ class MessageObject(ModelBase):
224
224
  return cls(id, "".join(str(i) for i in content), channel, guild, member, user, created_at, updated_at)
225
225
 
226
226
  @property
227
- def message(self) -> List[Element]:
227
+ def message(self) -> list[Element]:
228
228
  return transform(parse(self.content))
229
229
 
230
230
  @classmethod
@@ -244,7 +244,7 @@ class MessageObject(ModelBase):
244
244
  }
245
245
 
246
246
  def dump(self):
247
- res: Dict[str, Any] = {"id": self.id, "content": self.content}
247
+ res: dict[str, Any] = {"id": self.id, "content": self.content}
248
248
  if self.channel:
249
249
  res["channel"] = self.channel.dump()
250
250
  if self.guild:
@@ -335,7 +335,7 @@ T = TypeVar("T", bound=ModelBase)
335
335
 
336
336
  @dataclass
337
337
  class PageResult(ModelBase, Generic[T]):
338
- data: List[T]
338
+ data: list[T]
339
339
  next: Optional[str] = None
340
340
 
341
341
  @classmethod
@@ -1,7 +1,8 @@
1
1
  import re
2
+ from collections.abc import Iterable
2
3
  from dataclasses import dataclass, field
3
4
  from enum import IntEnum
4
- from typing import Any, Callable, Dict, Iterable, List, Literal, Optional, TypedDict, TypeVar, Union, cast
5
+ from typing import Any, Callable, Literal, Optional, TypedDict, TypeVar, Union, cast
5
6
  from typing_extensions import TypeAlias
6
7
 
7
8
  T = TypeVar("T")
@@ -39,13 +40,13 @@ def snake_case(source: str) -> str:
39
40
  )
40
41
 
41
42
 
42
- def ensure_list(value: Union[T, List[T], None]) -> List[T]:
43
+ def ensure_list(value: Union[T, list[T], None]) -> list[T]:
43
44
  return value if isinstance(value, list) else [value] if value else []
44
45
 
45
46
 
46
47
  S = TypeVar("S")
47
- Fragment: TypeAlias = Union[str, "Element", List[Union[str, "Element"]]]
48
- Render: TypeAlias = Callable[[dict, List["Element"], S], T]
48
+ Fragment: TypeAlias = Union[str, "Element", list[Union[str, "Element"]]]
49
+ Render: TypeAlias = Callable[[dict, list["Element"], S], T]
49
50
  Visitor: TypeAlias = Callable[["Element", S], T]
50
51
 
51
52
 
@@ -60,7 +61,7 @@ def make_element(content: Union[str, bool, int, float, "Element"]) -> Optional["
60
61
  raise ValueError(f"Invalid content: {content!r}")
61
62
 
62
63
 
63
- def make_elements(content: Fragment) -> List["Element"]:
64
+ def make_elements(content: Fragment) -> list["Element"]:
64
65
  if isinstance(content, list):
65
66
  res = [make_element(c) for c in content]
66
67
  else:
@@ -70,14 +71,14 @@ def make_elements(content: Fragment) -> List["Element"]:
70
71
 
71
72
  class Element:
72
73
  type: str
73
- attrs: Dict[str, Any]
74
- children: List["Element"]
74
+ attrs: dict[str, Any]
75
+ children: list["Element"]
75
76
  source: Optional[str] = None
76
77
 
77
78
  def __init__(
78
79
  self,
79
80
  type: Union[str, Render[Fragment, Any]],
80
- attrs: Optional[Dict[str, Any]] = None,
81
+ attrs: Optional[dict[str, Any]] = None,
81
82
  *children: Fragment,
82
83
  ) -> None:
83
84
  self.attrs = {}
@@ -97,8 +98,11 @@ class Element:
97
98
  self.attrs["is"] = type
98
99
  else:
99
100
  self.type = type
100
- if self.tag() == "text" and "content" in self.attrs:
101
- self.attrs["text"] = self.attrs.pop("content")
101
+ if self.tag() == "text":
102
+ if "content" in self.attrs:
103
+ self.attrs["text"] = self.attrs.pop("content")
104
+ elif not self.attrs:
105
+ self.attrs["text"] = ""
102
106
 
103
107
  def tag(self):
104
108
  if self.type == "component":
@@ -151,8 +155,8 @@ class Selector:
151
155
  comb_pat = re.compile(" *([ >+~]) *")
152
156
 
153
157
 
154
- def parse_selector(input: str) -> List[List[Selector]]:
155
- def _quert(query: str) -> List[Selector]:
158
+ def parse_selector(input: str) -> list[list[Selector]]:
159
+ def _quert(query: str) -> list[Selector]:
156
160
  selectors = []
157
161
  combinator = " "
158
162
  while mat := comb_pat.search(query):
@@ -170,7 +174,7 @@ def parse_selector(input: str) -> List[List[Selector]]:
170
174
  return [_quert(q) for q in input.split(",")]
171
175
 
172
176
 
173
- def select(source: Union[str, List[Element]], query: Union[str, List[List[Selector]]]) -> List[Element]:
177
+ def select(source: Union[str, list[Element]], query: Union[str, list[list[Selector]]]) -> list[Element]:
174
178
  if not source or not query:
175
179
  return []
176
180
  if isinstance(source, str):
@@ -179,10 +183,10 @@ def select(source: Union[str, List[Element]], query: Union[str, List[List[Select
179
183
  query = parse_selector(query)
180
184
  if not query:
181
185
  return []
182
- adjacent: List[List[Selector]] = []
186
+ adjacent: list[list[Selector]] = []
183
187
  results = []
184
188
  for index, elem in enumerate(source):
185
- inner: List[List[Selector]] = []
189
+ inner: list[list[Selector]] = []
186
190
  local = [*query, *adjacent]
187
191
  adjacent = []
188
192
  matched = False
@@ -252,7 +256,7 @@ class Token:
252
256
  positon: Position
253
257
  source: str
254
258
  extra: str
255
- children: Dict[str, List[Union[str, "Token"]]] = field(default_factory=dict)
259
+ children: dict[str, list[Union[str, "Token"]]] = field(default_factory=dict)
256
260
 
257
261
 
258
262
  class StackItem(TypedDict):
@@ -260,8 +264,8 @@ class StackItem(TypedDict):
260
264
  slot: str
261
265
 
262
266
 
263
- def fold_tokens(tokens: List[Union[str, Token]]) -> List[Union[str, Token]]:
264
- stack: List[StackItem] = [
267
+ def fold_tokens(tokens: list[Union[str, Token]]) -> list[Union[str, Token]]:
268
+ stack: list[StackItem] = [
265
269
  {
266
270
  "token": Token(
267
271
  type="angle",
@@ -298,8 +302,8 @@ def fold_tokens(tokens: List[Union[str, Token]]) -> List[Union[str, Token]]:
298
302
  return stack[-1]["token"].children["default"]
299
303
 
300
304
 
301
- def parse_tokens(tokens: List[Union[str, Token]], context: Optional[dict] = None) -> List[Element]:
302
- result: List[Element] = []
305
+ def parse_tokens(tokens: list[Union[str, Token]], context: Optional[dict] = None) -> list[Element]:
306
+ result: list[Element] = []
303
307
  for token in tokens:
304
308
  if isinstance(token, str):
305
309
  result.append(Element(type="text", attrs={"text": token}))
@@ -345,7 +349,7 @@ def parse_tokens(tokens: List[Union[str, Token]], context: Optional[dict] = None
345
349
 
346
350
 
347
351
  def parse(src: str, context: Optional[dict] = None):
348
- tokens: List[Union[str, Token]] = []
352
+ tokens: list[Union[str, Token]] = []
349
353
 
350
354
  def push_text(text: str):
351
355
  if text: