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,14 +1,14 @@
1
- from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView
2
- from telegrinder.bot.dispatch.view.base import BaseStateView, BaseView
3
- from telegrinder.bot.dispatch.view.box import ViewBox
4
- from telegrinder.bot.dispatch.view.callback_query import CallbackQueryView
5
- from telegrinder.bot.dispatch.view.chat_join_request import ChatJoinRequestView
6
- from telegrinder.bot.dispatch.view.chat_member import ChatMemberView
7
- from telegrinder.bot.dispatch.view.inline_query import InlineQueryView
8
- from telegrinder.bot.dispatch.view.message import MessageView
9
- from telegrinder.bot.dispatch.view.raw import RawEventView
10
-
11
- __all__ = (
1
+ from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView
2
+ from telegrinder.bot.dispatch.view.base import BaseStateView, BaseView
3
+ from telegrinder.bot.dispatch.view.box import ViewBox
4
+ from telegrinder.bot.dispatch.view.callback_query import CallbackQueryView
5
+ from telegrinder.bot.dispatch.view.chat_join_request import ChatJoinRequestView
6
+ from telegrinder.bot.dispatch.view.chat_member import ChatMemberView
7
+ from telegrinder.bot.dispatch.view.inline_query import InlineQueryView
8
+ from telegrinder.bot.dispatch.view.message import MessageView
9
+ from telegrinder.bot.dispatch.view.raw import RawEventView
10
+
11
+ __all__ = (
12
12
  "ABCStateView",
13
13
  "ABCView",
14
14
  "BaseStateView",
@@ -19,5 +19,5 @@ __all__ = (
19
19
  "InlineQueryView",
20
20
  "MessageView",
21
21
  "RawEventView",
22
- "ViewBox",
23
- )
22
+ "ViewBox",
23
+ )
@@ -1,43 +1,43 @@
1
- import typing
2
- from abc import ABC, abstractmethod
3
-
4
- from telegrinder.api.api import API
5
- from telegrinder.bot.cute_types.base import BaseCute
6
- from telegrinder.bot.dispatch.handler.abc import ABCHandler
7
- from telegrinder.types.objects import Update
8
-
9
- Event = typing.TypeVar("Event", bound=BaseCute)
10
-
11
-
12
- class ABCView(ABC):
13
- def __repr__(self) -> str:
14
- return "<{}>".format(self.__class__.__name__)
15
-
16
- @abstractmethod
17
- async def check(self, event: Update) -> bool:
18
- pass
19
-
20
- @abstractmethod
21
- async def process(self, event: Update, api: API) -> bool:
22
- pass
23
-
24
- @abstractmethod
25
- def load(self, external: typing.Self) -> None:
26
- pass
27
-
28
-
29
- class ABCEventRawView(ABCView, ABC, typing.Generic[Event]):
30
- handlers: list[ABCHandler[Event]]
31
-
32
-
33
- class ABCStateView(ABCView, typing.Generic[Event]):
34
- @abstractmethod
35
- def get_state_key(self, event: Event) -> int | None:
36
- pass
37
-
38
-
39
- __all__ = (
1
+ import typing
2
+ from abc import ABC, abstractmethod
3
+
4
+ from telegrinder.api.api import API
5
+ from telegrinder.bot.cute_types.base import BaseCute
6
+ from telegrinder.bot.dispatch.handler.abc import ABCHandler
7
+ from telegrinder.types.objects import Update
8
+
9
+ Event = typing.TypeVar("Event", bound=BaseCute)
10
+
11
+
12
+ class ABCView(ABC):
13
+ def __repr__(self) -> str:
14
+ return "<{}>".format(self.__class__.__name__)
15
+
16
+ @abstractmethod
17
+ async def check(self, event: Update) -> bool:
18
+ pass
19
+
20
+ @abstractmethod
21
+ async def process(self, event: Update, api: API) -> bool:
22
+ pass
23
+
24
+ @abstractmethod
25
+ def load(self, external: typing.Self) -> None:
26
+ pass
27
+
28
+
29
+ class ABCEventRawView(ABCView, ABC, typing.Generic[Event]):
30
+ handlers: list[ABCHandler[Event]]
31
+
32
+
33
+ class ABCStateView(ABCView, typing.Generic[Event]):
34
+ @abstractmethod
35
+ def get_state_key(self, event: Event) -> int | None:
36
+ pass
37
+
38
+
39
+ __all__ = (
40
40
  "ABCEventRawView",
41
41
  "ABCStateView",
42
- "ABCView",
43
- )
42
+ "ABCView",
43
+ )
@@ -1,211 +1,200 @@
1
- import typing
2
- from abc import ABC, abstractmethod
3
- from functools import cached_property
4
-
5
- from fntypes.option import Nothing, Some
6
-
7
- from telegrinder.api.api import API
8
- from telegrinder.bot.cute_types.base import BaseCute
9
- from telegrinder.bot.dispatch.handler.abc import ABCHandler
10
- from telegrinder.bot.dispatch.handler.func import FuncHandler
11
- from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
12
- from telegrinder.bot.dispatch.process import process_inner
13
- from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
14
- from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView
15
- from telegrinder.bot.rules.abc import ABCRule
16
- from telegrinder.model import Model
17
- from telegrinder.msgspec_utils import Option
18
- from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
19
- from telegrinder.types.objects import Update
20
-
21
- if typing.TYPE_CHECKING:
22
- from telegrinder.node.base import Node
23
-
24
- T = typing.TypeVar("T", contravariant=True, bound="BaseCute | Node")
25
- Event = typing.TypeVar("Event", bound=BaseCute)
26
- ErrorHandlerT = typing.TypeVar("ErrorHandlerT", bound=ABCErrorHandler)
27
- MiddlewareT = typing.TypeVar("MiddlewareT", bound=ABCMiddleware)
28
-
29
-
30
- class Func(typing.Protocol[T]):
31
- __name__: str
32
-
33
- async def __call__(self, event_or_node: T, /, *args: typing.Any, **kwargs: typing.Any) -> typing.Any: ...
34
-
35
-
36
- FuncType: typing.TypeAlias = Func[Event] | Func[T]
37
-
38
-
39
- def get_event_model_class(view: "BaseView[Event]") -> Option[type[Event]]:
40
- for base in view.__class__.__bases__ + (view.__class__,):
41
- if "__orig_bases__" not in base.__dict__:
42
- continue
43
-
44
- for orig_base in base.__dict__["__orig_bases__"]:
45
- origin_base = typing.get_origin(orig_base) or orig_base
46
- if not isinstance(origin_base, type) and not issubclass(origin_base, object):
47
- continue
48
-
49
- for generic_type in typing.get_args(orig_base):
50
- orig_generic_type = typing.get_origin(generic_type) or generic_type
51
- if isinstance(orig_generic_type, type) and issubclass(orig_generic_type, BaseCute):
52
- return Some(generic_type)
53
-
54
- return Nothing()
55
-
56
-
57
- class BaseView(ABCView, typing.Generic[Event]):
58
- auto_rules: list[ABCRule]
59
- handlers: list[ABCHandler[Event]]
60
- middlewares: list[ABCMiddleware[Event]]
61
- return_manager: ABCReturnManager[Event] | None = None
62
-
63
- @staticmethod
64
- def get_raw_event(update: Update) -> Option[Model]:
65
- return getattr(update, update.update_type.value)
66
-
67
- @cached_property
68
- def event_model_class(self) -> Option[type[Event]]:
69
- return get_event_model_class(self)
70
-
71
- @typing.overload
72
- @classmethod
73
- def to_handler(
74
- cls,
75
- *rules: ABCRule,
76
- ) -> typing.Callable[
77
- [FuncType[Event, T]],
78
- FuncHandler[Event, FuncType[Event, T], ErrorHandler[Event]],
79
- ]: ...
80
-
81
- @typing.overload
82
- @classmethod
83
- def to_handler(
84
- cls,
85
- *rules: ABCRule,
86
- error_handler: ErrorHandlerT,
87
- is_blocking: bool = True,
88
- ) -> typing.Callable[[FuncType[Event, T]], FuncHandler[Event, FuncType[Event, T], ErrorHandlerT]]: ...
89
-
90
- @typing.overload
91
- @classmethod
92
- def to_handler(
93
- cls,
94
- *rules: ABCRule,
95
- error_handler: typing.Literal[None] = None,
96
- is_blocking: bool = True,
97
- ) -> typing.Callable[
98
- [FuncType[Event, T]],
99
- FuncHandler[Event, FuncType[Event, T], ErrorHandler[Event]],
100
- ]: ...
101
-
102
- @classmethod
103
- def to_handler(
104
- cls,
105
- *rules: ABCRule,
106
- error_handler: ABCErrorHandler | None = None,
107
- is_blocking: bool = True,
108
- ) -> typing.Callable[..., typing.Any]:
109
- def wrapper(func):
110
- return FuncHandler(
111
- func,
112
- list(rules),
113
- is_blocking=is_blocking,
114
- dataclass=None,
115
- error_handler=error_handler or ErrorHandler(),
116
- )
117
-
118
- return wrapper
119
-
120
- @typing.overload
121
- def __call__(
122
- self,
123
- *rules: ABCRule,
124
- ) -> typing.Callable[
125
- [FuncType[Event, T]],
126
- FuncHandler[Event, FuncType[Event, T], ErrorHandler[Event]],
127
- ]: ...
128
-
129
- @typing.overload
130
- def __call__( # type: ignore
131
- self,
132
- *rules: ABCRule,
133
- error_handler: ErrorHandlerT,
134
- is_blocking: bool = True,
135
- ) -> typing.Callable[[FuncType[Event, T]], FuncHandler[Event, FuncType[Event, T], ErrorHandlerT]]: ...
136
-
137
- @typing.overload
138
- def __call__(
139
- self,
140
- *rules: ABCRule,
141
- error_handler: typing.Literal[None] = None,
142
- is_blocking: bool = True,
143
- ) -> typing.Callable[
144
- [FuncType[Event, T]],
145
- FuncHandler[Event, FuncType[Event, T], ErrorHandler[Event]],
146
- ]: ...
147
-
148
- def __call__(
149
- self,
150
- *rules: ABCRule,
151
- error_handler: ABCErrorHandler | None = None,
152
- is_blocking: bool = True,
153
- ) -> typing.Callable[..., typing.Any]:
154
- def wrapper(func):
155
- func_handler = FuncHandler(
156
- func,
157
- [*self.auto_rules, *rules],
158
- is_blocking=is_blocking,
159
- dataclass=None,
160
- error_handler=error_handler or ErrorHandler(),
161
- )
162
- self.handlers.append(func_handler)
163
- return func_handler
164
-
165
- return wrapper
166
-
167
- def register_middleware(self, *args: typing.Any, **kwargs: typing.Any):
168
- def wrapper(cls: type[MiddlewareT]) -> type[MiddlewareT]:
169
- self.middlewares.append(cls(*args, **kwargs))
170
- return cls
171
-
172
- return wrapper
173
-
174
- async def check(self, event: Update) -> bool:
175
- match self.get_raw_event(event):
176
- case Some(e) if issubclass(
177
- self.event_model_class.expect(
178
- "{!r} has no event model class in generic.".format(self.__class__.__qualname__),
179
- ),
180
- e.__class__,
181
- ) and (self.handlers or self.middlewares):
182
- return True
183
- case _:
184
- return False
185
-
186
- async def process(self, event: Update, api: API) -> bool:
187
- return await process_inner(
188
- api,
189
- self.event_model_class.unwrap().from_update(
190
- update=self.get_raw_event(event).unwrap(),
191
- bound_api=api,
192
- ),
193
- event,
194
- self.middlewares,
195
- self.handlers,
196
- self.return_manager,
197
- )
198
-
199
- def load(self, external: typing.Self) -> None:
200
- self.auto_rules.extend(external.auto_rules)
201
- self.handlers.extend(external.handlers)
202
- self.middlewares.extend(external.middlewares)
203
-
204
-
205
- class BaseStateView(ABCStateView[Event], BaseView[Event], ABC, typing.Generic[Event]):
206
- @abstractmethod
207
- def get_state_key(self, event: Event) -> int | None:
208
- pass
209
-
210
-
211
- __all__ = ("ABCStateView", "ABCView", "BaseStateView", "BaseView")
1
+ import typing
2
+ from abc import ABC, abstractmethod
3
+ from functools import cached_property
4
+
5
+ from fntypes.option import Nothing, Some
6
+
7
+ from telegrinder.api.api import API
8
+ from telegrinder.bot.cute_types.base import BaseCute
9
+ from telegrinder.bot.dispatch.handler.abc import ABCHandler
10
+ from telegrinder.bot.dispatch.handler.func import Func, FuncHandler
11
+ from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
12
+ from telegrinder.bot.dispatch.process import process_inner
13
+ from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
14
+ from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView
15
+ from telegrinder.bot.rules.abc import ABCRule
16
+ from telegrinder.model import Model
17
+ from telegrinder.msgspec_utils import Option
18
+ from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
19
+ from telegrinder.types.objects import Update
20
+
21
+ P = typing.ParamSpec("P")
22
+ R = typing.TypeVar("R", covariant=True)
23
+ Event = typing.TypeVar("Event", bound=BaseCute)
24
+ ErrorHandlerT = typing.TypeVar("ErrorHandlerT", bound=ABCErrorHandler)
25
+ MiddlewareT = typing.TypeVar("MiddlewareT", bound=ABCMiddleware)
26
+
27
+
28
+ def get_event_model_class(view: "BaseView[Event]") -> Option[type[Event]]:
29
+ for base in view.__class__.__bases__ + (view.__class__,):
30
+ if "__orig_bases__" not in base.__dict__:
31
+ continue
32
+
33
+ for orig_base in base.__dict__["__orig_bases__"]:
34
+ origin_base = typing.get_origin(orig_base) or orig_base
35
+ if not isinstance(origin_base, type) and not issubclass(origin_base, object):
36
+ continue
37
+
38
+ for generic_type in typing.get_args(orig_base):
39
+ orig_generic_type = typing.get_origin(generic_type) or generic_type
40
+ if isinstance(orig_generic_type, type) and issubclass(orig_generic_type, BaseCute):
41
+ return Some(generic_type)
42
+
43
+ return Nothing()
44
+
45
+
46
+ class BaseView(ABCView, typing.Generic[Event]):
47
+ auto_rules: list[ABCRule]
48
+ handlers: list[ABCHandler[Event]]
49
+ middlewares: list[ABCMiddleware[Event]]
50
+ return_manager: ABCReturnManager[Event] | None = None
51
+
52
+ @staticmethod
53
+ def get_raw_event(update: Update) -> Option[Model]:
54
+ return getattr(update, update.update_type.value)
55
+
56
+ @cached_property
57
+ def event_model_class(self) -> Option[type[Event]]:
58
+ return get_event_model_class(self)
59
+
60
+ @typing.overload
61
+ @classmethod
62
+ def to_handler(
63
+ cls,
64
+ *rules: ABCRule,
65
+ ) -> typing.Callable[
66
+ [Func[P, R]],
67
+ FuncHandler[Event, Func[P, R], ErrorHandler[Event]],
68
+ ]: ...
69
+
70
+ @typing.overload
71
+ @classmethod
72
+ def to_handler(
73
+ cls,
74
+ *rules: ABCRule,
75
+ error_handler: ErrorHandlerT,
76
+ is_blocking: bool = True,
77
+ ) -> typing.Callable[[Func[P, R]], FuncHandler[Event, Func[P, R], ErrorHandlerT]]: ...
78
+
79
+ @typing.overload
80
+ @classmethod
81
+ def to_handler(
82
+ cls,
83
+ *rules: ABCRule,
84
+ error_handler: typing.Literal[None] = None,
85
+ is_blocking: bool = True,
86
+ ) -> typing.Callable[
87
+ [Func[P, R]],
88
+ FuncHandler[Event, Func[P, R], ErrorHandler[Event]],
89
+ ]: ...
90
+
91
+ @classmethod
92
+ def to_handler(
93
+ cls,
94
+ *rules: ABCRule,
95
+ error_handler: ABCErrorHandler | None = None,
96
+ is_blocking: bool = True,
97
+ ) -> typing.Callable[..., typing.Any]:
98
+ def wrapper(func):
99
+ return FuncHandler(
100
+ func,
101
+ list(rules),
102
+ is_blocking=is_blocking,
103
+ dataclass=None,
104
+ error_handler=error_handler or ErrorHandler(),
105
+ )
106
+
107
+ return wrapper
108
+
109
+ @typing.overload
110
+ def __call__(
111
+ self,
112
+ *rules: ABCRule,
113
+ ) -> typing.Callable[
114
+ [Func[P, R]],
115
+ FuncHandler[Event, Func[P, R], ErrorHandler[Event]],
116
+ ]: ...
117
+
118
+ @typing.overload
119
+ def __call__( # type: ignore
120
+ self,
121
+ *rules: ABCRule,
122
+ error_handler: ErrorHandlerT,
123
+ is_blocking: bool = True,
124
+ ) -> typing.Callable[[Func[P, R]], FuncHandler[Event, Func[P, R], ErrorHandlerT]]: ...
125
+
126
+ @typing.overload
127
+ def __call__(
128
+ self,
129
+ *rules: ABCRule,
130
+ error_handler: typing.Literal[None] = None,
131
+ is_blocking: bool = True,
132
+ ) -> typing.Callable[
133
+ [Func[P, R]],
134
+ FuncHandler[Event, Func[P, R], ErrorHandler[Event]],
135
+ ]: ...
136
+
137
+ def __call__(
138
+ self,
139
+ *rules: ABCRule,
140
+ error_handler: ABCErrorHandler | None = None,
141
+ is_blocking: bool = True,
142
+ ) -> typing.Callable[..., typing.Any]:
143
+ def wrapper(func):
144
+ func_handler = FuncHandler(
145
+ func,
146
+ [*self.auto_rules, *rules],
147
+ is_blocking=is_blocking,
148
+ dataclass=None,
149
+ error_handler=error_handler or ErrorHandler(),
150
+ )
151
+ self.handlers.append(func_handler)
152
+ return func_handler
153
+
154
+ return wrapper
155
+
156
+ def register_middleware(self, *args: typing.Any, **kwargs: typing.Any):
157
+ def wrapper(cls: type[MiddlewareT]) -> type[MiddlewareT]:
158
+ self.middlewares.append(cls(*args, **kwargs))
159
+ return cls
160
+
161
+ return wrapper
162
+
163
+ async def check(self, event: Update) -> bool:
164
+ match self.get_raw_event(event):
165
+ case Some(e) if issubclass(
166
+ self.event_model_class.expect(
167
+ "{!r} has no event model class in generic.".format(self.__class__.__qualname__),
168
+ ),
169
+ e.__class__,
170
+ ) and (self.handlers or self.middlewares):
171
+ return True
172
+ case _:
173
+ return False
174
+
175
+ async def process(self, event: Update, api: API) -> bool:
176
+ return await process_inner(
177
+ api,
178
+ self.event_model_class.unwrap().from_update(
179
+ update=self.get_raw_event(event).unwrap(),
180
+ bound_api=api,
181
+ ),
182
+ event,
183
+ self.middlewares,
184
+ self.handlers,
185
+ self.return_manager,
186
+ )
187
+
188
+ def load(self, external: typing.Self) -> None:
189
+ self.auto_rules.extend(external.auto_rules)
190
+ self.handlers.extend(external.handlers)
191
+ self.middlewares.extend(external.middlewares)
192
+
193
+
194
+ class BaseStateView(ABCStateView[Event], BaseView[Event], ABC, typing.Generic[Event]):
195
+ @abstractmethod
196
+ def get_state_key(self, event: Event) -> int | None:
197
+ pass
198
+
199
+
200
+ __all__ = ("ABCStateView", "ABCView", "BaseStateView", "BaseView")