telegrinder 0.2.0__tar.gz → 0.2.0.post1__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.
Potentially problematic release.
This version of telegrinder might be problematic. Click here for more details.
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/PKG-INFO +1 -1
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/pyproject.toml +1 -1
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/base.py +13 -14
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/update.py +6 -5
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/callback_data.py +8 -2
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/model.py +8 -6
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/base.py +8 -1
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/command.py +3 -3
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/composer.py +1 -1
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/event.py +12 -9
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/me.py +3 -4
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/polymorphic.py +3 -3
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/LICENSE +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/readme.md +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/api/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/api/api.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/api/error.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/api/response.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/api/token.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/bot.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/callback_query.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/chat_join_request.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/chat_member_updated.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/inline_query.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/message.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/utils.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/context.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/dispatch.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/handler/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/handler/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/handler/func.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/handler/message_reply.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/middleware/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/middleware/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/process.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/callback_query.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/inline_query.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/message.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/box.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/callback_query.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/chat_join_request.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/chat_member.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/inline_query.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/message.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/raw.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/waiter_machine/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/waiter_machine/machine.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/waiter_machine/middleware.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/waiter_machine/short_state.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/polling/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/polling/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/polling/polling.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/adapter/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/adapter/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/adapter/errors.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/adapter/event.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/adapter/node.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/adapter/raw_update.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/chat_join.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/command.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/enum_text.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/func.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/fuzzy.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/inline.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/integer.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/is_from.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/markup.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/mention.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/message.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/message_entities.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/node.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/regex.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/rule_enum.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/start.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/text.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/update.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/scenario/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/scenario/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/scenario/checkbox.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/scenario/choice.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/client/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/client/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/client/aiohttp.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/modules.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/msgspec_json.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/msgspec_utils.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/attachment.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/callback_query.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/container.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/message.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/rule.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/scope.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/source.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/text.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/tools/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/tools/generator.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/node/update.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/py.typed +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/rules.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/buttons.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/error_handler/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/error_handler/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/error_handler/error.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/error_handler/error_handler.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/formatting/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/formatting/html.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/formatting/links.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/formatting/spec_html_formats.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/global_context/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/global_context/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/global_context/global_context.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/global_context/telegrinder_ctx.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/i18n/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/i18n/base.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/i18n/middleware/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/i18n/middleware/base.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/i18n/simple.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/kb_set/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/kb_set/base.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/kb_set/yaml.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/keyboard.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/limited_dict.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/loop_wrapper/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/loop_wrapper/abc.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/loop_wrapper/loop_wrapper.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/magic.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/parse_mode.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/types/__init__.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/types/enums.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/types/methods.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/types/objects.py +0 -0
- {telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/verification_utils.py +0 -0
|
@@ -55,22 +55,21 @@ if typing.TYPE_CHECKING:
|
|
|
55
55
|
...
|
|
56
56
|
|
|
57
57
|
else:
|
|
58
|
-
from fntypes.co import Some, Variative
|
|
58
|
+
from fntypes.co import Nothing, Some, Variative
|
|
59
59
|
|
|
60
60
|
from telegrinder.msgspec_utils import Option, decoder
|
|
61
61
|
from telegrinder.msgspec_utils import get_class_annotations as _get_class_annotations
|
|
62
62
|
|
|
63
|
-
def
|
|
64
|
-
for
|
|
65
|
-
|
|
66
|
-
hint = typing.get_origin(hint) or hint
|
|
67
|
-
if not isinstance(hint, type):
|
|
68
|
-
continue
|
|
63
|
+
def _get_cute_from_generic(generic_args):
|
|
64
|
+
for arg in generic_args:
|
|
65
|
+
orig_arg = typing.get_origin(arg) or arg
|
|
69
66
|
|
|
70
|
-
if
|
|
71
|
-
|
|
72
|
-
if
|
|
73
|
-
return
|
|
67
|
+
if not isinstance(orig_arg, type):
|
|
68
|
+
continue
|
|
69
|
+
if orig_arg in (Variative, Some, Option):
|
|
70
|
+
return _get_cute_from_generic(typing.get_args(arg))
|
|
71
|
+
if issubclass(arg, BaseCute):
|
|
72
|
+
return arg
|
|
74
73
|
|
|
75
74
|
return None
|
|
76
75
|
|
|
@@ -79,8 +78,8 @@ else:
|
|
|
79
78
|
|
|
80
79
|
for key, hint in annotations.items():
|
|
81
80
|
if not isinstance(hint, type):
|
|
82
|
-
if (
|
|
83
|
-
cute_annotations[key] =
|
|
81
|
+
if (cute := _get_cute_from_generic(typing.get_args(hint))) is not None:
|
|
82
|
+
cute_annotations[key] = cute
|
|
84
83
|
|
|
85
84
|
elif issubclass(hint, BaseCute):
|
|
86
85
|
cute_annotations[key] = hint
|
|
@@ -120,7 +119,7 @@ else:
|
|
|
120
119
|
cls.__cute_annotations__[field].from_update(_get_value(value), bound_api=bound_api),
|
|
121
120
|
type=cls.__annotations__[field],
|
|
122
121
|
)
|
|
123
|
-
if field in cls.__cute_annotations__ and value
|
|
122
|
+
if field in cls.__cute_annotations__ and not isinstance(value, Nothing)
|
|
124
123
|
else value
|
|
125
124
|
for field, value in update.to_dict().items()
|
|
126
125
|
},
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import typing
|
|
2
|
+
from functools import cached_property
|
|
2
3
|
|
|
3
4
|
from fntypes.co import Nothing, Some
|
|
4
5
|
|
|
5
|
-
from telegrinder.api import API
|
|
6
|
+
from telegrinder.api.api import API
|
|
6
7
|
from telegrinder.bot.cute_types.base import BaseCute
|
|
7
8
|
from telegrinder.bot.cute_types.callback_query import CallbackQueryCute
|
|
8
9
|
from telegrinder.bot.cute_types.chat_join_request import ChatJoinRequestCute
|
|
@@ -10,9 +11,9 @@ from telegrinder.bot.cute_types.chat_member_updated import ChatMemberUpdatedCute
|
|
|
10
11
|
from telegrinder.bot.cute_types.inline_query import InlineQueryCute
|
|
11
12
|
from telegrinder.bot.cute_types.message import MessageCute
|
|
12
13
|
from telegrinder.msgspec_utils import Option
|
|
13
|
-
from telegrinder.types import Model, Update
|
|
14
|
+
from telegrinder.types.objects import Model, Update
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
EventModel = typing.TypeVar("EventModel", bound=Model)
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class UpdateCute(BaseCute[Update], Update, kw_only=True):
|
|
@@ -61,11 +62,11 @@ class UpdateCute(BaseCute[Update], Update, kw_only=True):
|
|
|
61
62
|
"""Optional. A request to join the chat has been sent. The bot must have the can_invite_users
|
|
62
63
|
administrator right in the chat to receive these updates."""
|
|
63
64
|
|
|
64
|
-
@
|
|
65
|
+
@cached_property
|
|
65
66
|
def incoming_update(self) -> Model:
|
|
66
67
|
return getattr(self, self.update_type.value).unwrap()
|
|
67
68
|
|
|
68
|
-
def get_event(self, event_model: type[
|
|
69
|
+
def get_event(self, event_model: type[EventModel]) -> Option[EventModel]:
|
|
69
70
|
if isinstance(self.incoming_update, event_model):
|
|
70
71
|
return Some(self.incoming_update)
|
|
71
72
|
return Nothing()
|
|
@@ -135,12 +135,18 @@ class CallbackDataJsonEq(CallbackQueryDataRule):
|
|
|
135
135
|
|
|
136
136
|
|
|
137
137
|
class CallbackDataJsonModel(CallbackQueryDataRule):
|
|
138
|
-
def __init__(
|
|
138
|
+
def __init__(
|
|
139
|
+
self,
|
|
140
|
+
model: type[msgspec.Struct] | type[DataclassInstance],
|
|
141
|
+
*,
|
|
142
|
+
alias: str | None = None,
|
|
143
|
+
) -> None:
|
|
139
144
|
self.model = model
|
|
145
|
+
self.alias = alias or "data"
|
|
140
146
|
|
|
141
147
|
async def check(self, event: CallbackQuery, ctx: Context) -> bool:
|
|
142
148
|
with suppress(BaseException):
|
|
143
|
-
ctx.
|
|
149
|
+
ctx.set(self.alias, decoder.decode(event.data.unwrap().encode(), type=self.model))
|
|
144
150
|
return True
|
|
145
151
|
return False
|
|
146
152
|
|
|
@@ -16,10 +16,17 @@ if typing.TYPE_CHECKING:
|
|
|
16
16
|
|
|
17
17
|
T = typing.TypeVar("T")
|
|
18
18
|
|
|
19
|
+
|
|
20
|
+
def rename_field(name: str) -> str:
|
|
21
|
+
if name.endswith("_") and name.removesuffix("_") in keyword.kwlist:
|
|
22
|
+
return name.removesuffix("_")
|
|
23
|
+
return name if not keyword.iskeyword(name) else name + "_"
|
|
24
|
+
|
|
25
|
+
|
|
19
26
|
MODEL_CONFIG: typing.Final[dict[str, typing.Any]] = {
|
|
20
27
|
"omit_defaults": True,
|
|
21
28
|
"dict": True,
|
|
22
|
-
"rename":
|
|
29
|
+
"rename": rename_field,
|
|
23
30
|
}
|
|
24
31
|
|
|
25
32
|
|
|
@@ -58,11 +65,6 @@ def get_params(params: dict[str, typing.Any]) -> dict[str, typing.Any]:
|
|
|
58
65
|
return validated_params
|
|
59
66
|
|
|
60
67
|
|
|
61
|
-
def encode_name(name: str) -> str:
|
|
62
|
-
# TODO
|
|
63
|
-
return MODEL_CONFIG.get("rename", {}).get(name, name)
|
|
64
|
-
|
|
65
|
-
|
|
66
68
|
class Model(msgspec.Struct, **MODEL_CONFIG):
|
|
67
69
|
@classmethod
|
|
68
70
|
def from_data(cls, data: dict[str, typing.Any]) -> typing.Self:
|
|
@@ -33,7 +33,9 @@ def is_generator(function: typing.Callable[..., typing.Any]) -> typing.TypeGuard
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
def get_node_calc_lst(node: type["Node"]) -> list[type["Node"]]:
|
|
36
|
-
"""
|
|
36
|
+
"""Returns flattened list of node types in ordering required to calculate given node.
|
|
37
|
+
Provides caching for passed node type"""
|
|
38
|
+
|
|
37
39
|
if calc_lst := getattr(node, "__nodes_calc_lst__", None):
|
|
38
40
|
return calc_lst
|
|
39
41
|
nodes_lst: list[type["Node"]] = []
|
|
@@ -101,6 +103,10 @@ if typing.TYPE_CHECKING:
|
|
|
101
103
|
pass
|
|
102
104
|
|
|
103
105
|
else:
|
|
106
|
+
def __init_subclass__(cls, *args, **kwargs): # noqa: N807
|
|
107
|
+
if any(issubclass(base, ScalarNode) for base in cls.__bases__ if base is not ScalarNode):
|
|
108
|
+
raise RuntimeError("Scalar nodes do not support inheritance.")
|
|
109
|
+
|
|
104
110
|
def create_node(cls, bases, dct):
|
|
105
111
|
dct.update(cls.__dict__)
|
|
106
112
|
return type(cls.__name__, bases, dct)
|
|
@@ -112,6 +118,7 @@ else:
|
|
|
112
118
|
{
|
|
113
119
|
"as_node": classmethod(lambda cls: create_node(cls, bases, dct)),
|
|
114
120
|
"scope": Node.scope,
|
|
121
|
+
"__init_subclass__": __init_subclass__,
|
|
115
122
|
},
|
|
116
123
|
)
|
|
117
124
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
from dataclasses import dataclass, field
|
|
3
3
|
|
|
4
|
-
from fntypes import Nothing, Option, Some
|
|
4
|
+
from fntypes.option import Nothing, Option, Some
|
|
5
5
|
|
|
6
|
-
from .base import DataNode
|
|
7
|
-
from .text import Text
|
|
6
|
+
from telegrinder.node.base import DataNode
|
|
7
|
+
from telegrinder.node.text import Text
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def single_split(s: str, separator: str) -> tuple[str, str]:
|
|
@@ -46,7 +46,7 @@ async def compose_nodes(
|
|
|
46
46
|
logger.debug("Composing nodes: {!r}...", nodes)
|
|
47
47
|
|
|
48
48
|
parent_nodes: dict[type[Node], NodeSession] = {}
|
|
49
|
-
event_nodes: dict[type[Node],
|
|
49
|
+
event_nodes: dict[type[Node], NodeSession] = ctx.get_or_set(CONTEXT_STORE_NODES_KEY, {})
|
|
50
50
|
data = {Context: ctx} | (data or {})
|
|
51
51
|
|
|
52
52
|
# Create flattened list of ordered nodes to be calculated
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import dataclasses
|
|
1
2
|
import typing
|
|
2
3
|
|
|
3
4
|
import msgspec
|
|
@@ -5,21 +6,18 @@ import msgspec
|
|
|
5
6
|
from telegrinder.api import API
|
|
6
7
|
from telegrinder.bot.cute_types import BaseCute
|
|
7
8
|
from telegrinder.bot.dispatch.context import Context
|
|
8
|
-
from telegrinder.msgspec_utils import DataclassInstance
|
|
9
|
-
from telegrinder.node.base import ComposeError,
|
|
9
|
+
from telegrinder.msgspec_utils import DataclassInstance, decoder
|
|
10
|
+
from telegrinder.node.base import ComposeError, Node
|
|
10
11
|
from telegrinder.node.update import UpdateNode
|
|
11
12
|
|
|
12
13
|
if typing.TYPE_CHECKING:
|
|
13
14
|
Dataclass = typing.TypeVar("Dataclass", bound="DataclassType")
|
|
14
15
|
|
|
15
|
-
DataclassType: typing.TypeAlias = DataclassInstance |
|
|
16
|
+
DataclassType: typing.TypeAlias = DataclassInstance | msgspec.Struct | dict[str, typing.Any]
|
|
16
17
|
|
|
17
18
|
EVENT_NODE_KEY = "_event_node"
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
from telegrinder.msgspec_utils import decoder
|
|
21
|
-
|
|
22
|
-
|
|
23
21
|
class _EventNode(Node):
|
|
24
22
|
dataclass: type["DataclassType"]
|
|
25
23
|
|
|
@@ -41,13 +39,17 @@ class _EventNode(Node):
|
|
|
41
39
|
dataclass = cls.dataclass(**raw_update.incoming_update.to_full_dict())
|
|
42
40
|
|
|
43
41
|
elif issubclass(dataclass_type, BaseCute):
|
|
44
|
-
|
|
42
|
+
if isinstance(raw_update.incoming_update, dataclass_type):
|
|
43
|
+
dataclass = raw_update.incoming_update
|
|
44
|
+
else:
|
|
45
|
+
dataclass = dataclass_type.from_update(raw_update.incoming_update, bound_api=api)
|
|
45
46
|
|
|
46
|
-
elif issubclass(dataclass_type,
|
|
47
|
-
# FIXME: must be used with
|
|
47
|
+
elif issubclass(dataclass_type, msgspec.Struct) or dataclasses.is_dataclass(dataclass_type):
|
|
48
|
+
# FIXME: must be used with rename_field
|
|
48
49
|
dataclass = decoder.convert(
|
|
49
50
|
raw_update.incoming_update.to_full_dict(),
|
|
50
51
|
type=cls.dataclass,
|
|
52
|
+
str_keys=True,
|
|
51
53
|
)
|
|
52
54
|
|
|
53
55
|
else:
|
|
@@ -61,6 +63,7 @@ class _EventNode(Node):
|
|
|
61
63
|
|
|
62
64
|
if typing.TYPE_CHECKING:
|
|
63
65
|
EventNode: typing.TypeAlias = typing.Annotated["Dataclass", ...]
|
|
66
|
+
|
|
64
67
|
else:
|
|
65
68
|
class EventNode(_EventNode):
|
|
66
69
|
pass
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
from telegrinder.api.api import API
|
|
2
|
-
from telegrinder.
|
|
3
|
-
|
|
4
|
-
from .
|
|
5
|
-
from .scope import GLOBAL
|
|
2
|
+
from telegrinder.node.base import ComposeError, ScalarNode
|
|
3
|
+
from telegrinder.node.scope import GLOBAL
|
|
4
|
+
from telegrinder.types.objects import User
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
class Me(ScalarNode, User):
|
|
@@ -22,12 +22,12 @@ class Polymorphic(Node):
|
|
|
22
22
|
composition = Composition(impl, True)
|
|
23
23
|
node_collection = await composition.compose_nodes(update, context)
|
|
24
24
|
if node_collection is None:
|
|
25
|
-
logger.debug("Impl {} composition failed", impl.__name__)
|
|
25
|
+
logger.debug("Impl {!r} composition failed", impl.__name__)
|
|
26
26
|
continue
|
|
27
27
|
|
|
28
28
|
# To determine whether this is a right morph, all subnodes must be resolved
|
|
29
29
|
if scope is NodeScope.PER_EVENT and (cls, i) in node_ctx:
|
|
30
|
-
logger.debug("Morph is already cached as per_event node, using its value. Impl {} succeeded", impl.__name__)
|
|
30
|
+
logger.debug("Morph is already cached as per_event node, using its value. Impl {!r} succeeded", impl.__name__)
|
|
31
31
|
res: NodeSession = node_ctx[(cls, i)]
|
|
32
32
|
await node_collection.close_all()
|
|
33
33
|
return res.value
|
|
@@ -40,7 +40,7 @@ class Polymorphic(Node):
|
|
|
40
40
|
node_ctx[(cls, i)] = NodeSession(cls, result, {})
|
|
41
41
|
|
|
42
42
|
await node_collection.close_all(with_value=result)
|
|
43
|
-
logger.debug("Impl {} succeeded with value {}", impl.__name__, result)
|
|
43
|
+
logger.debug("Impl {!r} succeeded with value {}", impl.__name__, result)
|
|
44
44
|
return result
|
|
45
45
|
|
|
46
46
|
raise ComposeError("No implementation found.")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/chat_join_request.py
RENAMED
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/chat_member_updated.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/handler/message_reply.py
RENAMED
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/middleware/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/__init__.py
RENAMED
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/abc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/message.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/callback_query.py
RENAMED
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/chat_join_request.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/waiter_machine/__init__.py
RENAMED
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/waiter_machine/machine.py
RENAMED
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/waiter_machine/middleware.py
RENAMED
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/waiter_machine/short_state.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/error_handler/error_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/formatting/spec_html_formats.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/global_context/global_context.py
RENAMED
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/global_context/telegrinder_ctx.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{telegrinder-0.2.0 → telegrinder-0.2.0.post1}/telegrinder/tools/loop_wrapper/loop_wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|