telegrinder 0.3.1__py3-none-any.whl → 0.3.3__py3-none-any.whl

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.

Potentially problematic release.


This version of telegrinder might be problematic. Click here for more details.

Files changed (164) hide show
  1. telegrinder/__init__.py +144 -144
  2. telegrinder/api/__init__.py +8 -8
  3. telegrinder/api/api.py +93 -93
  4. telegrinder/api/error.py +16 -16
  5. telegrinder/api/response.py +20 -20
  6. telegrinder/api/token.py +36 -36
  7. telegrinder/bot/__init__.py +66 -66
  8. telegrinder/bot/bot.py +76 -76
  9. telegrinder/bot/cute_types/__init__.py +17 -17
  10. telegrinder/bot/cute_types/base.py +258 -234
  11. telegrinder/bot/cute_types/callback_query.py +385 -382
  12. telegrinder/bot/cute_types/chat_join_request.py +61 -61
  13. telegrinder/bot/cute_types/chat_member_updated.py +160 -160
  14. telegrinder/bot/cute_types/inline_query.py +43 -53
  15. telegrinder/bot/cute_types/message.py +2637 -2631
  16. telegrinder/bot/cute_types/update.py +109 -75
  17. telegrinder/bot/cute_types/utils.py +95 -95
  18. telegrinder/bot/dispatch/__init__.py +55 -55
  19. telegrinder/bot/dispatch/abc.py +77 -77
  20. telegrinder/bot/dispatch/context.py +98 -92
  21. telegrinder/bot/dispatch/dispatch.py +202 -201
  22. telegrinder/bot/dispatch/handler/__init__.py +13 -13
  23. telegrinder/bot/dispatch/handler/abc.py +24 -24
  24. telegrinder/bot/dispatch/handler/audio_reply.py +44 -44
  25. telegrinder/bot/dispatch/handler/base.py +57 -57
  26. telegrinder/bot/dispatch/handler/document_reply.py +44 -44
  27. telegrinder/bot/dispatch/handler/func.py +135 -123
  28. telegrinder/bot/dispatch/handler/media_group_reply.py +43 -43
  29. telegrinder/bot/dispatch/handler/message_reply.py +36 -36
  30. telegrinder/bot/dispatch/handler/photo_reply.py +44 -44
  31. telegrinder/bot/dispatch/handler/sticker_reply.py +37 -37
  32. telegrinder/bot/dispatch/handler/video_reply.py +44 -44
  33. telegrinder/bot/dispatch/middleware/__init__.py +3 -3
  34. telegrinder/bot/dispatch/middleware/abc.py +16 -16
  35. telegrinder/bot/dispatch/process.py +132 -132
  36. telegrinder/bot/dispatch/return_manager/__init__.py +13 -13
  37. telegrinder/bot/dispatch/return_manager/abc.py +108 -108
  38. telegrinder/bot/dispatch/return_manager/callback_query.py +20 -20
  39. telegrinder/bot/dispatch/return_manager/inline_query.py +15 -15
  40. telegrinder/bot/dispatch/return_manager/message.py +36 -36
  41. telegrinder/bot/dispatch/view/__init__.py +13 -13
  42. telegrinder/bot/dispatch/view/abc.py +41 -41
  43. telegrinder/bot/dispatch/view/base.py +200 -211
  44. telegrinder/bot/dispatch/view/box.py +129 -129
  45. telegrinder/bot/dispatch/view/callback_query.py +17 -17
  46. telegrinder/bot/dispatch/view/chat_join_request.py +16 -16
  47. telegrinder/bot/dispatch/view/chat_member.py +39 -39
  48. telegrinder/bot/dispatch/view/inline_query.py +17 -17
  49. telegrinder/bot/dispatch/view/message.py +44 -44
  50. telegrinder/bot/dispatch/view/raw.py +114 -118
  51. telegrinder/bot/dispatch/waiter_machine/__init__.py +17 -17
  52. telegrinder/bot/dispatch/waiter_machine/actions.py +13 -13
  53. telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +8 -8
  54. telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +55 -55
  55. telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +57 -57
  56. telegrinder/bot/dispatch/waiter_machine/hasher/message.py +51 -51
  57. telegrinder/bot/dispatch/waiter_machine/hasher/state.py +19 -19
  58. telegrinder/bot/dispatch/waiter_machine/machine.py +167 -170
  59. telegrinder/bot/dispatch/waiter_machine/middleware.py +89 -89
  60. telegrinder/bot/dispatch/waiter_machine/short_state.py +68 -65
  61. telegrinder/bot/polling/__init__.py +4 -4
  62. telegrinder/bot/polling/abc.py +25 -25
  63. telegrinder/bot/polling/polling.py +131 -131
  64. telegrinder/bot/rules/__init__.py +62 -62
  65. telegrinder/bot/rules/abc.py +213 -238
  66. telegrinder/bot/rules/adapter/__init__.py +9 -9
  67. telegrinder/bot/rules/adapter/abc.py +29 -29
  68. telegrinder/bot/rules/adapter/errors.py +5 -5
  69. telegrinder/bot/rules/adapter/event.py +67 -76
  70. telegrinder/bot/rules/adapter/node.py +48 -48
  71. telegrinder/bot/rules/adapter/raw_update.py +30 -30
  72. telegrinder/bot/rules/callback_data.py +170 -171
  73. telegrinder/bot/rules/chat_join.py +46 -48
  74. telegrinder/bot/rules/command.py +126 -126
  75. telegrinder/bot/rules/enum_text.py +36 -36
  76. telegrinder/bot/rules/func.py +26 -26
  77. telegrinder/bot/rules/fuzzy.py +24 -24
  78. telegrinder/bot/rules/inline.py +60 -60
  79. telegrinder/bot/rules/integer.py +20 -20
  80. telegrinder/bot/rules/is_from.py +127 -127
  81. telegrinder/bot/rules/markup.py +43 -43
  82. telegrinder/bot/rules/mention.py +14 -14
  83. telegrinder/bot/rules/message.py +17 -17
  84. telegrinder/bot/rules/message_entities.py +35 -35
  85. telegrinder/bot/rules/node.py +27 -27
  86. telegrinder/bot/rules/regex.py +37 -37
  87. telegrinder/bot/rules/rule_enum.py +72 -72
  88. telegrinder/bot/rules/start.py +42 -42
  89. telegrinder/bot/rules/state.py +37 -37
  90. telegrinder/bot/rules/text.py +33 -33
  91. telegrinder/bot/rules/update.py +15 -15
  92. telegrinder/bot/scenario/__init__.py +5 -5
  93. telegrinder/bot/scenario/abc.py +19 -19
  94. telegrinder/bot/scenario/checkbox.py +167 -147
  95. telegrinder/bot/scenario/choice.py +46 -44
  96. telegrinder/client/__init__.py +4 -4
  97. telegrinder/client/abc.py +75 -75
  98. telegrinder/client/aiohttp.py +130 -130
  99. telegrinder/model.py +295 -244
  100. telegrinder/modules.py +237 -237
  101. telegrinder/msgspec_json.py +14 -14
  102. telegrinder/msgspec_utils.py +410 -410
  103. telegrinder/node/__init__.py +7 -3
  104. telegrinder/node/attachment.py +87 -87
  105. telegrinder/node/base.py +166 -144
  106. telegrinder/node/callback_query.py +53 -14
  107. telegrinder/node/command.py +33 -33
  108. telegrinder/node/composer.py +198 -184
  109. telegrinder/node/container.py +27 -27
  110. telegrinder/node/event.py +65 -73
  111. telegrinder/node/me.py +16 -16
  112. telegrinder/node/message.py +14 -14
  113. telegrinder/node/polymorphic.py +48 -52
  114. telegrinder/node/rule.py +76 -76
  115. telegrinder/node/scope.py +38 -38
  116. telegrinder/node/source.py +71 -71
  117. telegrinder/node/text.py +41 -21
  118. telegrinder/node/tools/__init__.py +3 -3
  119. telegrinder/node/tools/generator.py +40 -40
  120. telegrinder/node/update.py +15 -15
  121. telegrinder/rules.py +0 -0
  122. telegrinder/tools/__init__.py +74 -74
  123. telegrinder/tools/buttons.py +79 -79
  124. telegrinder/tools/error_handler/__init__.py +7 -7
  125. telegrinder/tools/error_handler/abc.py +33 -33
  126. telegrinder/tools/error_handler/error.py +9 -9
  127. telegrinder/tools/error_handler/error_handler.py +193 -193
  128. telegrinder/tools/formatting/__init__.py +46 -46
  129. telegrinder/tools/formatting/html.py +283 -283
  130. telegrinder/tools/formatting/links.py +33 -33
  131. telegrinder/tools/formatting/spec_html_formats.py +111 -111
  132. telegrinder/tools/functional.py +12 -12
  133. telegrinder/tools/global_context/__init__.py +7 -7
  134. telegrinder/tools/global_context/abc.py +63 -63
  135. telegrinder/tools/global_context/global_context.py +412 -412
  136. telegrinder/tools/global_context/telegrinder_ctx.py +27 -27
  137. telegrinder/tools/i18n/__init__.py +7 -7
  138. telegrinder/tools/i18n/abc.py +30 -30
  139. telegrinder/tools/i18n/middleware/__init__.py +3 -3
  140. telegrinder/tools/i18n/middleware/abc.py +25 -25
  141. telegrinder/tools/i18n/simple.py +43 -43
  142. telegrinder/tools/kb_set/__init__.py +4 -4
  143. telegrinder/tools/kb_set/base.py +15 -15
  144. telegrinder/tools/kb_set/yaml.py +63 -63
  145. telegrinder/tools/keyboard.py +132 -132
  146. telegrinder/tools/limited_dict.py +37 -37
  147. telegrinder/tools/loop_wrapper/__init__.py +4 -4
  148. telegrinder/tools/loop_wrapper/abc.py +15 -15
  149. telegrinder/tools/loop_wrapper/loop_wrapper.py +224 -216
  150. telegrinder/tools/magic.py +157 -157
  151. telegrinder/tools/parse_mode.py +6 -6
  152. telegrinder/tools/state_storage/__init__.py +4 -4
  153. telegrinder/tools/state_storage/abc.py +35 -35
  154. telegrinder/tools/state_storage/memory.py +25 -25
  155. telegrinder/types/__init__.py +260 -260
  156. telegrinder/types/enums.py +701 -701
  157. telegrinder/types/methods.py +4633 -4633
  158. telegrinder/types/objects.py +8561 -6541
  159. telegrinder/verification_utils.py +32 -32
  160. {telegrinder-0.3.1.dist-info → telegrinder-0.3.3.dist-info}/LICENSE +22 -22
  161. {telegrinder-0.3.1.dist-info → telegrinder-0.3.3.dist-info}/METADATA +1 -1
  162. telegrinder-0.3.3.dist-info/RECORD +164 -0
  163. telegrinder-0.3.1.dist-info/RECORD +0 -164
  164. {telegrinder-0.3.1.dist-info → telegrinder-0.3.3.dist-info}/WHEEL +0 -0
@@ -1,132 +1,132 @@
1
- import dataclasses
2
- import typing
3
- from abc import ABC, abstractmethod
4
- from types import NoneType
5
-
6
- from fntypes.option import Nothing, Some
7
-
8
- from telegrinder.types.objects import (
9
- InlineKeyboardMarkup,
10
- ReplyKeyboardMarkup,
11
- ReplyKeyboardRemove,
12
- )
13
-
14
- from .buttons import Button, InlineButton, KeyboardButton, RowButtons
15
-
16
- DictStrAny: typing.TypeAlias = dict[str, typing.Any]
17
- AnyMarkup: typing.TypeAlias = InlineKeyboardMarkup | ReplyKeyboardMarkup
18
-
19
-
20
- def copy_keyboard(keyboard: list[list[DictStrAny]]) -> list[list[DictStrAny]]:
21
- return [row.copy() for row in keyboard]
22
-
23
-
24
- @dataclasses.dataclass(kw_only=True, slots=True)
25
- class KeyboardModel:
26
- resize_keyboard: bool
27
- one_time_keyboard: bool
28
- selective: bool
29
- is_persistent: bool
30
- keyboard: list[list[DictStrAny]]
31
-
32
-
33
- class ABCMarkup(ABC, typing.Generic[KeyboardButton]):
34
- BUTTON: type[KeyboardButton]
35
- keyboard: list[list[DictStrAny]]
36
-
37
- @abstractmethod
38
- def dict(self) -> DictStrAny:
39
- pass
40
-
41
- @abstractmethod
42
- def get_markup(self) -> AnyMarkup:
43
- pass
44
-
45
- @classmethod
46
- def get_empty_markup(cls) -> AnyMarkup:
47
- return cls().get_markup()
48
-
49
- def add(self, row_or_button: RowButtons[KeyboardButton] | KeyboardButton) -> typing.Self:
50
- if not len(self.keyboard):
51
- self.row()
52
-
53
- if isinstance(row_or_button, RowButtons):
54
- self.keyboard[-1].extend(row_or_button.get_data())
55
- if row_or_button.auto_row:
56
- self.row()
57
- return self
58
-
59
- self.keyboard[-1].append(row_or_button.get_data())
60
- return self
61
-
62
- def row(self) -> typing.Self:
63
- if len(self.keyboard) and not len(self.keyboard[-1]):
64
- raise RuntimeError("Last row is empty!")
65
-
66
- self.keyboard.append([])
67
- return self
68
-
69
- def format(self, **format_data: str) -> typing.Self:
70
- copy_keyboard = self.__class__()
71
- for row in self.keyboard:
72
- for button in row:
73
- copy_button = button.copy()
74
- copy_button["text"] = copy_button["text"].format(**format_data)
75
- copy_keyboard.add(self.BUTTON(**copy_button))
76
- copy_keyboard.row()
77
- return copy_keyboard
78
-
79
- def merge(self, other: typing.Self) -> typing.Self:
80
- self.keyboard.extend(copy_keyboard(other.keyboard))
81
- return self
82
-
83
-
84
- @dataclasses.dataclass(kw_only=True, slots=True)
85
- class Keyboard(ABCMarkup[Button], KeyboardModel):
86
- BUTTON = Button
87
-
88
- keyboard: list[list[DictStrAny]] = dataclasses.field(
89
- default_factory=lambda: [[]],
90
- init=False,
91
- )
92
- resize_keyboard: bool = dataclasses.field(default=True)
93
- one_time_keyboard: bool = dataclasses.field(default=False)
94
- selective: bool = dataclasses.field(default=False)
95
- is_persistent: bool = dataclasses.field(default=False)
96
-
97
- def dict(self) -> DictStrAny:
98
- self.keyboard = [row for row in self.keyboard if row]
99
- return {
100
- k: v.unwrap() if v and isinstance(v, Some) else v
101
- for k, v in dataclasses.asdict(self).items()
102
- if type(v) not in (NoneType, Nothing)
103
- }
104
-
105
- def get_markup(self) -> ReplyKeyboardMarkup:
106
- return ReplyKeyboardMarkup(**self.dict())
107
-
108
- def keyboard_remove(self, *, selective: bool = False) -> ReplyKeyboardRemove:
109
- return ReplyKeyboardRemove(remove_keyboard=True, selective=Some(selective))
110
-
111
-
112
- class InlineKeyboard(ABCMarkup[InlineButton]):
113
- BUTTON = InlineButton
114
-
115
- def __init__(self) -> None:
116
- self.keyboard = [[]]
117
-
118
- def dict(self) -> DictStrAny:
119
- self.keyboard = [row for row in self.keyboard if row]
120
- return dict(inline_keyboard=self.keyboard)
121
-
122
- def get_markup(self) -> InlineKeyboardMarkup:
123
- return InlineKeyboardMarkup(**self.dict())
124
-
125
-
126
- __all__ = (
127
- "ABCMarkup",
128
- "InlineKeyboard",
129
- "Keyboard",
130
- "KeyboardModel",
131
- "copy_keyboard",
132
- )
1
+ import dataclasses
2
+ import typing
3
+ from abc import ABC, abstractmethod
4
+ from types import NoneType
5
+
6
+ from fntypes.option import Nothing, Some
7
+
8
+ from telegrinder.types.objects import (
9
+ InlineKeyboardMarkup,
10
+ ReplyKeyboardMarkup,
11
+ ReplyKeyboardRemove,
12
+ )
13
+
14
+ from .buttons import Button, InlineButton, KeyboardButton, RowButtons
15
+
16
+ DictStrAny: typing.TypeAlias = dict[str, typing.Any]
17
+ AnyMarkup: typing.TypeAlias = InlineKeyboardMarkup | ReplyKeyboardMarkup
18
+
19
+
20
+ def copy_keyboard(keyboard: list[list[DictStrAny]]) -> list[list[DictStrAny]]:
21
+ return [row.copy() for row in keyboard]
22
+
23
+
24
+ @dataclasses.dataclass(kw_only=True, slots=True)
25
+ class KeyboardModel:
26
+ resize_keyboard: bool
27
+ one_time_keyboard: bool
28
+ selective: bool
29
+ is_persistent: bool
30
+ keyboard: list[list[DictStrAny]]
31
+
32
+
33
+ class ABCMarkup(ABC, typing.Generic[KeyboardButton]):
34
+ BUTTON: type[KeyboardButton]
35
+ keyboard: list[list[DictStrAny]]
36
+
37
+ @abstractmethod
38
+ def dict(self) -> DictStrAny:
39
+ pass
40
+
41
+ @abstractmethod
42
+ def get_markup(self) -> AnyMarkup:
43
+ pass
44
+
45
+ @classmethod
46
+ def get_empty_markup(cls) -> AnyMarkup:
47
+ return cls().get_markup()
48
+
49
+ def add(self, row_or_button: RowButtons[KeyboardButton] | KeyboardButton) -> typing.Self:
50
+ if not len(self.keyboard):
51
+ self.row()
52
+
53
+ if isinstance(row_or_button, RowButtons):
54
+ self.keyboard[-1].extend(row_or_button.get_data())
55
+ if row_or_button.auto_row:
56
+ self.row()
57
+ return self
58
+
59
+ self.keyboard[-1].append(row_or_button.get_data())
60
+ return self
61
+
62
+ def row(self) -> typing.Self:
63
+ if len(self.keyboard) and not len(self.keyboard[-1]):
64
+ raise RuntimeError("Last row is empty!")
65
+
66
+ self.keyboard.append([])
67
+ return self
68
+
69
+ def format(self, **format_data: str) -> typing.Self:
70
+ copy_keyboard = self.__class__()
71
+ for row in self.keyboard:
72
+ for button in row:
73
+ copy_button = button.copy()
74
+ copy_button["text"] = copy_button["text"].format(**format_data)
75
+ copy_keyboard.add(self.BUTTON(**copy_button))
76
+ copy_keyboard.row()
77
+ return copy_keyboard
78
+
79
+ def merge(self, other: typing.Self) -> typing.Self:
80
+ self.keyboard.extend(copy_keyboard(other.keyboard))
81
+ return self
82
+
83
+
84
+ @dataclasses.dataclass(kw_only=True, slots=True)
85
+ class Keyboard(ABCMarkup[Button], KeyboardModel):
86
+ BUTTON = Button
87
+
88
+ keyboard: list[list[DictStrAny]] = dataclasses.field(
89
+ default_factory=lambda: [[]],
90
+ init=False,
91
+ )
92
+ resize_keyboard: bool = dataclasses.field(default=True)
93
+ one_time_keyboard: bool = dataclasses.field(default=False)
94
+ selective: bool = dataclasses.field(default=False)
95
+ is_persistent: bool = dataclasses.field(default=False)
96
+
97
+ def dict(self) -> DictStrAny:
98
+ self.keyboard = [row for row in self.keyboard if row]
99
+ return {
100
+ k: v.unwrap() if v and isinstance(v, Some) else v
101
+ for k, v in dataclasses.asdict(self).items()
102
+ if type(v) not in (NoneType, Nothing)
103
+ }
104
+
105
+ def get_markup(self) -> ReplyKeyboardMarkup:
106
+ return ReplyKeyboardMarkup(**self.dict())
107
+
108
+ def keyboard_remove(self, *, selective: bool = False) -> ReplyKeyboardRemove:
109
+ return ReplyKeyboardRemove(remove_keyboard=True, selective=selective)
110
+
111
+
112
+ class InlineKeyboard(ABCMarkup[InlineButton]):
113
+ BUTTON = InlineButton
114
+
115
+ def __init__(self) -> None:
116
+ self.keyboard = [[]]
117
+
118
+ def dict(self) -> DictStrAny:
119
+ self.keyboard = [row for row in self.keyboard if row]
120
+ return dict(inline_keyboard=self.keyboard)
121
+
122
+ def get_markup(self) -> InlineKeyboardMarkup:
123
+ return InlineKeyboardMarkup(**self.dict())
124
+
125
+
126
+ __all__ = (
127
+ "ABCMarkup",
128
+ "InlineKeyboard",
129
+ "Keyboard",
130
+ "KeyboardModel",
131
+ "copy_keyboard",
132
+ )
@@ -1,37 +1,37 @@
1
- import typing
2
- from collections import UserDict, deque
3
-
4
- KT = typing.TypeVar("KT")
5
- VT = typing.TypeVar("VT")
6
-
7
-
8
- class LimitedDict(UserDict[KT, VT]):
9
- def __init__(self, *, maxlimit: int = 1000) -> None:
10
- super().__init__()
11
- self.maxlimit = maxlimit
12
- self.queue: deque[KT] = deque(maxlen=maxlimit)
13
-
14
- def set(self, key: KT, value: VT, /) -> VT | None:
15
- """Set item in the dictionary.
16
- Returns a value that was deleted when the limit in the dictionary
17
- was reached, otherwise None.
18
- """
19
-
20
- deleted_item = None
21
- if len(self.queue) >= self.maxlimit:
22
- deleted_item = self.pop(self.queue.popleft(), None)
23
- if key not in self.queue:
24
- self.queue.append(key)
25
- super().__setitem__(key, value)
26
- return deleted_item
27
-
28
- def __setitem__(self, key: KT, value: VT, /) -> None:
29
- self.set(key, value)
30
-
31
- def __delitem__(self, key: KT) -> None:
32
- if key in self.queue:
33
- self.queue.remove(key)
34
- return super().__delitem__(key)
35
-
36
-
37
- __all__ = ("LimitedDict",)
1
+ import typing
2
+ from collections import UserDict, deque
3
+
4
+ KT = typing.TypeVar("KT")
5
+ VT = typing.TypeVar("VT")
6
+
7
+
8
+ class LimitedDict(UserDict[KT, VT]):
9
+ def __init__(self, *, maxlimit: int = 1000) -> None:
10
+ super().__init__()
11
+ self.maxlimit = maxlimit
12
+ self.queue: deque[KT] = deque(maxlen=maxlimit)
13
+
14
+ def set(self, key: KT, value: VT, /) -> VT | None:
15
+ """Set item in the dictionary.
16
+ Returns a value that was deleted when the limit in the dictionary
17
+ was reached, otherwise None.
18
+ """
19
+
20
+ deleted_item = None
21
+ if len(self.queue) >= self.maxlimit:
22
+ deleted_item = self.pop(self.queue.popleft(), None)
23
+ if key not in self.queue:
24
+ self.queue.append(key)
25
+ super().__setitem__(key, value)
26
+ return deleted_item
27
+
28
+ def __setitem__(self, key: KT, value: VT, /) -> None:
29
+ self.set(key, value)
30
+
31
+ def __delitem__(self, key: KT) -> None:
32
+ if key in self.queue:
33
+ self.queue.remove(key)
34
+ return super().__delitem__(key)
35
+
36
+
37
+ __all__ = ("LimitedDict",)
@@ -1,4 +1,4 @@
1
- from .abc import ABCLoopWrapper
2
- from .loop_wrapper import DelayedTask, Lifespan, LoopWrapper
3
-
4
- __all__ = ("ABCLoopWrapper", "DelayedTask", "Lifespan", "LoopWrapper")
1
+ from .abc import ABCLoopWrapper
2
+ from .loop_wrapper import DelayedTask, Lifespan, LoopWrapper
3
+
4
+ __all__ = ("ABCLoopWrapper", "DelayedTask", "Lifespan", "LoopWrapper")
@@ -1,15 +1,15 @@
1
- import typing
2
- from abc import ABC, abstractmethod
3
-
4
-
5
- class ABCLoopWrapper(ABC):
6
- @abstractmethod
7
- def add_task(self, task: typing.Any) -> None:
8
- pass
9
-
10
- @abstractmethod
11
- def run_event_loop(self) -> None:
12
- pass
13
-
14
-
15
- __all__ = ("ABCLoopWrapper",)
1
+ import typing
2
+ from abc import ABC, abstractmethod
3
+
4
+
5
+ class ABCLoopWrapper(ABC):
6
+ @abstractmethod
7
+ def add_task(self, task: typing.Any) -> None:
8
+ pass
9
+
10
+ @abstractmethod
11
+ def run_event_loop(self) -> None:
12
+ pass
13
+
14
+
15
+ __all__ = ("ABCLoopWrapper",)