telegrinder 0.3.4__py3-none-any.whl → 0.3.4.post1__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.
- telegrinder/__init__.py +144 -144
- telegrinder/api/__init__.py +8 -8
- telegrinder/api/api.py +93 -93
- telegrinder/api/error.py +16 -16
- telegrinder/api/response.py +20 -20
- telegrinder/api/token.py +36 -36
- telegrinder/bot/__init__.py +66 -66
- telegrinder/bot/bot.py +76 -76
- telegrinder/bot/cute_types/__init__.py +17 -17
- telegrinder/bot/cute_types/base.py +258 -258
- telegrinder/bot/cute_types/callback_query.py +385 -385
- telegrinder/bot/cute_types/chat_join_request.py +61 -61
- telegrinder/bot/cute_types/chat_member_updated.py +160 -160
- telegrinder/bot/cute_types/inline_query.py +43 -43
- telegrinder/bot/cute_types/message.py +2637 -2637
- telegrinder/bot/cute_types/update.py +104 -104
- telegrinder/bot/cute_types/utils.py +95 -95
- telegrinder/bot/dispatch/__init__.py +55 -55
- telegrinder/bot/dispatch/abc.py +77 -77
- telegrinder/bot/dispatch/context.py +98 -98
- telegrinder/bot/dispatch/dispatch.py +202 -202
- telegrinder/bot/dispatch/handler/__init__.py +13 -13
- telegrinder/bot/dispatch/handler/abc.py +24 -24
- telegrinder/bot/dispatch/handler/audio_reply.py +44 -44
- telegrinder/bot/dispatch/handler/base.py +57 -57
- telegrinder/bot/dispatch/handler/document_reply.py +44 -44
- telegrinder/bot/dispatch/handler/func.py +135 -135
- telegrinder/bot/dispatch/handler/media_group_reply.py +43 -43
- telegrinder/bot/dispatch/handler/message_reply.py +36 -36
- telegrinder/bot/dispatch/handler/photo_reply.py +44 -44
- telegrinder/bot/dispatch/handler/sticker_reply.py +37 -37
- telegrinder/bot/dispatch/handler/video_reply.py +44 -44
- telegrinder/bot/dispatch/middleware/__init__.py +3 -3
- telegrinder/bot/dispatch/middleware/abc.py +22 -22
- telegrinder/bot/dispatch/process.py +157 -157
- telegrinder/bot/dispatch/return_manager/__init__.py +13 -13
- telegrinder/bot/dispatch/return_manager/abc.py +108 -108
- telegrinder/bot/dispatch/return_manager/callback_query.py +20 -20
- telegrinder/bot/dispatch/return_manager/inline_query.py +15 -15
- telegrinder/bot/dispatch/return_manager/message.py +36 -36
- telegrinder/bot/dispatch/view/__init__.py +13 -13
- telegrinder/bot/dispatch/view/abc.py +41 -41
- telegrinder/bot/dispatch/view/base.py +200 -200
- telegrinder/bot/dispatch/view/box.py +129 -129
- telegrinder/bot/dispatch/view/callback_query.py +17 -17
- telegrinder/bot/dispatch/view/chat_join_request.py +16 -16
- telegrinder/bot/dispatch/view/chat_member.py +39 -39
- telegrinder/bot/dispatch/view/inline_query.py +17 -17
- telegrinder/bot/dispatch/view/message.py +44 -44
- telegrinder/bot/dispatch/view/raw.py +114 -114
- telegrinder/bot/dispatch/waiter_machine/__init__.py +17 -17
- telegrinder/bot/dispatch/waiter_machine/actions.py +13 -13
- telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +8 -8
- telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +55 -55
- telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +57 -57
- telegrinder/bot/dispatch/waiter_machine/hasher/message.py +51 -51
- telegrinder/bot/dispatch/waiter_machine/hasher/state.py +19 -19
- telegrinder/bot/dispatch/waiter_machine/machine.py +172 -172
- telegrinder/bot/dispatch/waiter_machine/middleware.py +89 -89
- telegrinder/bot/dispatch/waiter_machine/short_state.py +68 -68
- telegrinder/bot/polling/__init__.py +4 -4
- telegrinder/bot/polling/abc.py +25 -25
- telegrinder/bot/polling/polling.py +131 -131
- telegrinder/bot/rules/__init__.py +62 -62
- telegrinder/bot/rules/abc.py +206 -206
- telegrinder/bot/rules/adapter/__init__.py +17 -17
- telegrinder/bot/rules/adapter/abc.py +31 -31
- telegrinder/bot/rules/adapter/errors.py +5 -5
- telegrinder/bot/rules/adapter/event.py +65 -65
- telegrinder/bot/rules/adapter/node.py +48 -48
- telegrinder/bot/rules/adapter/raw_event.py +27 -27
- telegrinder/bot/rules/adapter/raw_update.py +30 -30
- telegrinder/bot/rules/callback_data.py +163 -163
- telegrinder/bot/rules/chat_join.py +43 -43
- telegrinder/bot/rules/command.py +126 -126
- telegrinder/bot/rules/enum_text.py +36 -36
- telegrinder/bot/rules/func.py +26 -26
- telegrinder/bot/rules/fuzzy.py +24 -24
- telegrinder/bot/rules/inline.py +56 -56
- telegrinder/bot/rules/integer.py +20 -20
- telegrinder/bot/rules/is_from.py +127 -127
- telegrinder/bot/rules/markup.py +43 -43
- telegrinder/bot/rules/mention.py +14 -14
- telegrinder/bot/rules/message.py +17 -17
- telegrinder/bot/rules/message_entities.py +35 -35
- telegrinder/bot/rules/node.py +27 -27
- telegrinder/bot/rules/regex.py +37 -37
- telegrinder/bot/rules/rule_enum.py +72 -72
- telegrinder/bot/rules/start.py +42 -42
- telegrinder/bot/rules/state.py +37 -37
- telegrinder/bot/rules/text.py +33 -33
- telegrinder/bot/rules/update.py +15 -15
- telegrinder/bot/scenario/__init__.py +5 -5
- telegrinder/bot/scenario/abc.py +19 -19
- telegrinder/bot/scenario/checkbox.py +176 -176
- telegrinder/bot/scenario/choice.py +51 -51
- telegrinder/client/__init__.py +4 -4
- telegrinder/client/abc.py +75 -75
- telegrinder/client/aiohttp.py +130 -130
- telegrinder/model.py +313 -313
- telegrinder/modules.py +237 -237
- telegrinder/msgspec_json.py +14 -14
- telegrinder/msgspec_utils.py +410 -410
- telegrinder/node/__init__.py +20 -20
- telegrinder/node/attachment.py +87 -87
- telegrinder/node/base.py +157 -157
- telegrinder/node/callback_query.py +53 -53
- telegrinder/node/command.py +33 -33
- telegrinder/node/composer.py +198 -198
- telegrinder/node/container.py +27 -27
- telegrinder/node/event.py +65 -65
- telegrinder/node/me.py +16 -16
- telegrinder/node/message.py +14 -14
- telegrinder/node/polymorphic.py +48 -48
- telegrinder/node/rule.py +76 -76
- telegrinder/node/scope.py +38 -38
- telegrinder/node/source.py +71 -71
- telegrinder/node/text.py +41 -41
- telegrinder/node/tools/__init__.py +3 -3
- telegrinder/node/tools/generator.py +40 -40
- telegrinder/node/update.py +15 -15
- telegrinder/rules.py +5 -5
- telegrinder/tools/__init__.py +74 -74
- telegrinder/tools/buttons.py +79 -79
- telegrinder/tools/error_handler/__init__.py +7 -7
- telegrinder/tools/error_handler/abc.py +33 -33
- telegrinder/tools/error_handler/error.py +9 -9
- telegrinder/tools/error_handler/error_handler.py +193 -193
- telegrinder/tools/formatting/__init__.py +46 -46
- telegrinder/tools/formatting/html.py +283 -283
- telegrinder/tools/formatting/links.py +33 -33
- telegrinder/tools/formatting/spec_html_formats.py +111 -111
- telegrinder/tools/functional.py +12 -12
- telegrinder/tools/global_context/__init__.py +7 -7
- telegrinder/tools/global_context/abc.py +63 -63
- telegrinder/tools/global_context/global_context.py +412 -412
- telegrinder/tools/global_context/telegrinder_ctx.py +27 -27
- telegrinder/tools/i18n/__init__.py +7 -7
- telegrinder/tools/i18n/abc.py +30 -30
- telegrinder/tools/i18n/middleware/__init__.py +3 -3
- telegrinder/tools/i18n/middleware/abc.py +25 -25
- telegrinder/tools/i18n/simple.py +43 -43
- telegrinder/tools/kb_set/__init__.py +4 -4
- telegrinder/tools/kb_set/base.py +15 -15
- telegrinder/tools/kb_set/yaml.py +63 -63
- telegrinder/tools/keyboard.py +128 -128
- telegrinder/tools/limited_dict.py +37 -37
- telegrinder/tools/loop_wrapper/__init__.py +4 -4
- telegrinder/tools/loop_wrapper/abc.py +15 -15
- telegrinder/tools/loop_wrapper/loop_wrapper.py +224 -224
- telegrinder/tools/magic.py +157 -157
- telegrinder/tools/parse_mode.py +6 -6
- telegrinder/tools/state_storage/__init__.py +4 -4
- telegrinder/tools/state_storage/abc.py +35 -35
- telegrinder/tools/state_storage/memory.py +25 -25
- telegrinder/types/__init__.py +260 -260
- telegrinder/types/enums.py +701 -701
- telegrinder/types/methods.py +4633 -4633
- telegrinder/types/objects.py +6950 -6950
- telegrinder/verification_utils.py +32 -32
- {telegrinder-0.3.4.dist-info → telegrinder-0.3.4.post1.dist-info}/LICENSE +22 -22
- {telegrinder-0.3.4.dist-info → telegrinder-0.3.4.post1.dist-info}/METADATA +1 -1
- telegrinder-0.3.4.post1.dist-info/RECORD +165 -0
- telegrinder-0.3.4.dist-info/RECORD +0 -165
- {telegrinder-0.3.4.dist-info → telegrinder-0.3.4.post1.dist-info}/WHEEL +0 -0
telegrinder/tools/magic.py
CHANGED
|
@@ -1,158 +1,158 @@
|
|
|
1
|
-
import enum
|
|
2
|
-
import types
|
|
3
|
-
import typing
|
|
4
|
-
from functools import wraps
|
|
5
|
-
|
|
6
|
-
if typing.TYPE_CHECKING:
|
|
7
|
-
from telegrinder.bot.rules.abc import ABCRule
|
|
8
|
-
from telegrinder.node.polymorphic import Polymorphic
|
|
9
|
-
|
|
10
|
-
T = typing.TypeVar("T", bound=ABCRule)
|
|
11
|
-
F = typing.TypeVar(
|
|
12
|
-
"F",
|
|
13
|
-
bound=typing.Callable[typing.Concatenate[typing.Callable[..., typing.Any], ...], typing.Any],
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
Impl: typing.TypeAlias = type[classmethod]
|
|
17
|
-
FuncType: typing.TypeAlias = types.FunctionType | typing.Callable[..., typing.Any]
|
|
18
|
-
|
|
19
|
-
TRANSLATIONS_KEY: typing.Final[str] = "_translations"
|
|
20
|
-
IMPL_MARK: typing.Final[str] = "_is_impl"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def cache_magic_value(mark_key: str, /):
|
|
24
|
-
def inner(func: "F") -> "F":
|
|
25
|
-
@wraps(func)
|
|
26
|
-
def wrapper(*args: typing.Any, **kwargs: typing.Any) -> typing.Any:
|
|
27
|
-
if mark_key not in args[0].__dict__:
|
|
28
|
-
args[0].__dict__[mark_key] = func(*args, **kwargs)
|
|
29
|
-
return args[0].__dict__[mark_key]
|
|
30
|
-
|
|
31
|
-
return wrapper # type: ignore
|
|
32
|
-
|
|
33
|
-
return inner
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def resolve_arg_names(func: FuncType, start_idx: int = 1) -> tuple[str, ...]:
|
|
37
|
-
return func.__code__.co_varnames[start_idx : func.__code__.co_argcount]
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
@cache_magic_value("__default_args__")
|
|
41
|
-
def get_default_args(func: FuncType) -> dict[str, typing.Any]:
|
|
42
|
-
kwdefaults = func.__kwdefaults__
|
|
43
|
-
if kwdefaults:
|
|
44
|
-
return kwdefaults
|
|
45
|
-
|
|
46
|
-
defaults = func.__defaults__
|
|
47
|
-
if not defaults:
|
|
48
|
-
return {}
|
|
49
|
-
|
|
50
|
-
return {k: defaults[i] for i, k in enumerate(resolve_arg_names(func, start_idx=0)[-len(defaults) :])}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def get_annotations(func: FuncType, *, return_type: bool = False) -> dict[str, typing.Any]:
|
|
54
|
-
annotations = func.__annotations__
|
|
55
|
-
if not return_type and "return" in func.__annotations__:
|
|
56
|
-
annotations.pop("return")
|
|
57
|
-
return annotations
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def to_str(s: str | enum.Enum) -> str:
|
|
61
|
-
if isinstance(s, enum.Enum):
|
|
62
|
-
return str(s.value)
|
|
63
|
-
return s
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
@typing.overload
|
|
67
|
-
def magic_bundle(handler: FuncType, kw: dict[str, typing.Any]) -> dict[str, typing.Any]: ...
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@typing.overload
|
|
71
|
-
def magic_bundle(handler: FuncType, kw: dict[enum.Enum, typing.Any]) -> dict[str, typing.Any]: ...
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
@typing.overload
|
|
75
|
-
def magic_bundle(
|
|
76
|
-
handler: FuncType,
|
|
77
|
-
kw: dict[str, typing.Any],
|
|
78
|
-
*,
|
|
79
|
-
start_idx: int = 1,
|
|
80
|
-
bundle_ctx: bool = True,
|
|
81
|
-
) -> dict[str, typing.Any]: ...
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
@typing.overload
|
|
85
|
-
def magic_bundle(
|
|
86
|
-
handler: FuncType,
|
|
87
|
-
kw: dict[enum.Enum, typing.Any],
|
|
88
|
-
*,
|
|
89
|
-
start_idx: int = 1,
|
|
90
|
-
bundle_ctx: bool = True,
|
|
91
|
-
) -> dict[str, typing.Any]: ...
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
@typing.overload
|
|
95
|
-
def magic_bundle(
|
|
96
|
-
handler: FuncType,
|
|
97
|
-
kw: dict[type, typing.Any],
|
|
98
|
-
*,
|
|
99
|
-
typebundle: typing.Literal[True] = True,
|
|
100
|
-
) -> dict[str, typing.Any]: ...
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def magic_bundle(
|
|
104
|
-
handler: FuncType,
|
|
105
|
-
kw: dict[typing.Any, typing.Any],
|
|
106
|
-
*,
|
|
107
|
-
start_idx: int = 1,
|
|
108
|
-
bundle_ctx: bool = True,
|
|
109
|
-
typebundle: bool = False,
|
|
110
|
-
) -> dict[str, typing.Any]:
|
|
111
|
-
if typebundle:
|
|
112
|
-
types = get_annotations(handler, return_type=False)
|
|
113
|
-
bundle: dict[str, typing.Any] = {}
|
|
114
|
-
for name, type in types.items():
|
|
115
|
-
bundle[name] = kw[type]
|
|
116
|
-
return bundle
|
|
117
|
-
|
|
118
|
-
names = resolve_arg_names(handler, start_idx=start_idx)
|
|
119
|
-
args = get_default_args(handler)
|
|
120
|
-
args.update({to_str(k): v for k, v in kw.items() if to_str(k) in names})
|
|
121
|
-
if "ctx" in names and bundle_ctx:
|
|
122
|
-
args["ctx"] = kw
|
|
123
|
-
return args
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def get_cached_translation(rule: "T", locale: str) -> "T | None":
|
|
127
|
-
return getattr(rule, TRANSLATIONS_KEY, {}).get(locale)
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def cache_translation(base_rule: "T", locale: str, translated_rule: "T") -> None:
|
|
131
|
-
translations = getattr(base_rule, TRANSLATIONS_KEY, {})
|
|
132
|
-
translations[locale] = translated_rule
|
|
133
|
-
setattr(base_rule, TRANSLATIONS_KEY, translations)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
@typing.cast(typing.Callable[..., Impl], lambda f: f)
|
|
137
|
-
def impl(method: typing.Callable[..., typing.Any]):
|
|
138
|
-
setattr(method, IMPL_MARK, True)
|
|
139
|
-
return classmethod(method)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
def get_impls(cls: type["Polymorphic"]) -> list[typing.Callable[..., typing.Any]]:
|
|
143
|
-
moprh_impls = getattr(cls, "__morph_impls__", None)
|
|
144
|
-
if moprh_impls is not None:
|
|
145
|
-
return moprh_impls
|
|
146
|
-
impls = [
|
|
147
|
-
func.__func__
|
|
148
|
-
for func in vars(cls).values()
|
|
149
|
-
if isinstance(func, classmethod) and getattr(func.__func__, IMPL_MARK, False)
|
|
150
|
-
]
|
|
151
|
-
setattr(cls, "__morph_impls__", impls)
|
|
152
|
-
return impls
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
__all__ = (
|
|
1
|
+
import enum
|
|
2
|
+
import types
|
|
3
|
+
import typing
|
|
4
|
+
from functools import wraps
|
|
5
|
+
|
|
6
|
+
if typing.TYPE_CHECKING:
|
|
7
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
8
|
+
from telegrinder.node.polymorphic import Polymorphic
|
|
9
|
+
|
|
10
|
+
T = typing.TypeVar("T", bound=ABCRule)
|
|
11
|
+
F = typing.TypeVar(
|
|
12
|
+
"F",
|
|
13
|
+
bound=typing.Callable[typing.Concatenate[typing.Callable[..., typing.Any], ...], typing.Any],
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
Impl: typing.TypeAlias = type[classmethod]
|
|
17
|
+
FuncType: typing.TypeAlias = types.FunctionType | typing.Callable[..., typing.Any]
|
|
18
|
+
|
|
19
|
+
TRANSLATIONS_KEY: typing.Final[str] = "_translations"
|
|
20
|
+
IMPL_MARK: typing.Final[str] = "_is_impl"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def cache_magic_value(mark_key: str, /):
|
|
24
|
+
def inner(func: "F") -> "F":
|
|
25
|
+
@wraps(func)
|
|
26
|
+
def wrapper(*args: typing.Any, **kwargs: typing.Any) -> typing.Any:
|
|
27
|
+
if mark_key not in args[0].__dict__:
|
|
28
|
+
args[0].__dict__[mark_key] = func(*args, **kwargs)
|
|
29
|
+
return args[0].__dict__[mark_key]
|
|
30
|
+
|
|
31
|
+
return wrapper # type: ignore
|
|
32
|
+
|
|
33
|
+
return inner
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def resolve_arg_names(func: FuncType, start_idx: int = 1) -> tuple[str, ...]:
|
|
37
|
+
return func.__code__.co_varnames[start_idx : func.__code__.co_argcount]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@cache_magic_value("__default_args__")
|
|
41
|
+
def get_default_args(func: FuncType) -> dict[str, typing.Any]:
|
|
42
|
+
kwdefaults = func.__kwdefaults__
|
|
43
|
+
if kwdefaults:
|
|
44
|
+
return kwdefaults
|
|
45
|
+
|
|
46
|
+
defaults = func.__defaults__
|
|
47
|
+
if not defaults:
|
|
48
|
+
return {}
|
|
49
|
+
|
|
50
|
+
return {k: defaults[i] for i, k in enumerate(resolve_arg_names(func, start_idx=0)[-len(defaults) :])}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_annotations(func: FuncType, *, return_type: bool = False) -> dict[str, typing.Any]:
|
|
54
|
+
annotations = func.__annotations__
|
|
55
|
+
if not return_type and "return" in func.__annotations__:
|
|
56
|
+
annotations.pop("return")
|
|
57
|
+
return annotations
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def to_str(s: str | enum.Enum) -> str:
|
|
61
|
+
if isinstance(s, enum.Enum):
|
|
62
|
+
return str(s.value)
|
|
63
|
+
return s
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@typing.overload
|
|
67
|
+
def magic_bundle(handler: FuncType, kw: dict[str, typing.Any]) -> dict[str, typing.Any]: ...
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@typing.overload
|
|
71
|
+
def magic_bundle(handler: FuncType, kw: dict[enum.Enum, typing.Any]) -> dict[str, typing.Any]: ...
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@typing.overload
|
|
75
|
+
def magic_bundle(
|
|
76
|
+
handler: FuncType,
|
|
77
|
+
kw: dict[str, typing.Any],
|
|
78
|
+
*,
|
|
79
|
+
start_idx: int = 1,
|
|
80
|
+
bundle_ctx: bool = True,
|
|
81
|
+
) -> dict[str, typing.Any]: ...
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@typing.overload
|
|
85
|
+
def magic_bundle(
|
|
86
|
+
handler: FuncType,
|
|
87
|
+
kw: dict[enum.Enum, typing.Any],
|
|
88
|
+
*,
|
|
89
|
+
start_idx: int = 1,
|
|
90
|
+
bundle_ctx: bool = True,
|
|
91
|
+
) -> dict[str, typing.Any]: ...
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@typing.overload
|
|
95
|
+
def magic_bundle(
|
|
96
|
+
handler: FuncType,
|
|
97
|
+
kw: dict[type, typing.Any],
|
|
98
|
+
*,
|
|
99
|
+
typebundle: typing.Literal[True] = True,
|
|
100
|
+
) -> dict[str, typing.Any]: ...
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def magic_bundle(
|
|
104
|
+
handler: FuncType,
|
|
105
|
+
kw: dict[typing.Any, typing.Any],
|
|
106
|
+
*,
|
|
107
|
+
start_idx: int = 1,
|
|
108
|
+
bundle_ctx: bool = True,
|
|
109
|
+
typebundle: bool = False,
|
|
110
|
+
) -> dict[str, typing.Any]:
|
|
111
|
+
if typebundle:
|
|
112
|
+
types = get_annotations(handler, return_type=False)
|
|
113
|
+
bundle: dict[str, typing.Any] = {}
|
|
114
|
+
for name, type in types.items():
|
|
115
|
+
bundle[name] = kw[type]
|
|
116
|
+
return bundle
|
|
117
|
+
|
|
118
|
+
names = resolve_arg_names(handler, start_idx=start_idx)
|
|
119
|
+
args = get_default_args(handler)
|
|
120
|
+
args.update({to_str(k): v for k, v in kw.items() if to_str(k) in names})
|
|
121
|
+
if "ctx" in names and bundle_ctx:
|
|
122
|
+
args["ctx"] = kw
|
|
123
|
+
return args
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def get_cached_translation(rule: "T", locale: str) -> "T | None":
|
|
127
|
+
return getattr(rule, TRANSLATIONS_KEY, {}).get(locale)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def cache_translation(base_rule: "T", locale: str, translated_rule: "T") -> None:
|
|
131
|
+
translations = getattr(base_rule, TRANSLATIONS_KEY, {})
|
|
132
|
+
translations[locale] = translated_rule
|
|
133
|
+
setattr(base_rule, TRANSLATIONS_KEY, translations)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@typing.cast(typing.Callable[..., Impl], lambda f: f)
|
|
137
|
+
def impl(method: typing.Callable[..., typing.Any]):
|
|
138
|
+
setattr(method, IMPL_MARK, True)
|
|
139
|
+
return classmethod(method)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def get_impls(cls: type["Polymorphic"]) -> list[typing.Callable[..., typing.Any]]:
|
|
143
|
+
moprh_impls = getattr(cls, "__morph_impls__", None)
|
|
144
|
+
if moprh_impls is not None:
|
|
145
|
+
return moprh_impls
|
|
146
|
+
impls = [
|
|
147
|
+
func.__func__
|
|
148
|
+
for func in vars(cls).values()
|
|
149
|
+
if isinstance(func, classmethod) and getattr(func.__func__, IMPL_MARK, False)
|
|
150
|
+
]
|
|
151
|
+
setattr(cls, "__morph_impls__", impls)
|
|
152
|
+
return impls
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
__all__ = (
|
|
156
156
|
"TRANSLATIONS_KEY",
|
|
157
157
|
"cache_magic_value",
|
|
158
158
|
"cache_translation",
|
|
@@ -164,5 +164,5 @@ __all__ = (
|
|
|
164
164
|
"impl",
|
|
165
165
|
"magic_bundle",
|
|
166
166
|
"resolve_arg_names",
|
|
167
|
-
"to_str",
|
|
168
|
-
)
|
|
167
|
+
"to_str",
|
|
168
|
+
)
|
telegrinder/tools/parse_mode.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
class ParseMode:
|
|
2
|
-
MARKDOWNV2 = "MarkdownV2"
|
|
3
|
-
HTML = "HTML"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
__all__ = ("ParseMode",)
|
|
1
|
+
class ParseMode:
|
|
2
|
+
MARKDOWNV2 = "MarkdownV2"
|
|
3
|
+
HTML = "HTML"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
__all__ = ("ParseMode",)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from telegrinder.tools.state_storage.abc import ABCStateStorage, StateData
|
|
2
|
-
from telegrinder.tools.state_storage.memory import MemoryStateStorage
|
|
3
|
-
|
|
4
|
-
__all__ = ("ABCStateStorage", "MemoryStateStorage", "StateData")
|
|
1
|
+
from telegrinder.tools.state_storage.abc import ABCStateStorage, StateData
|
|
2
|
+
from telegrinder.tools.state_storage.memory import MemoryStateStorage
|
|
3
|
+
|
|
4
|
+
__all__ = ("ABCStateStorage", "MemoryStateStorage", "StateData")
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import abc
|
|
2
|
-
import enum
|
|
3
|
-
import typing
|
|
4
|
-
from dataclasses import dataclass
|
|
5
|
-
|
|
6
|
-
from fntypes import Option
|
|
7
|
-
|
|
8
|
-
from telegrinder.bot.rules.state import State, StateMeta
|
|
9
|
-
|
|
10
|
-
Payload = typing.TypeVar("Payload")
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@dataclass(frozen=True, slots=True)
|
|
14
|
-
class StateData(typing.Generic[Payload]):
|
|
15
|
-
key: str | enum.Enum
|
|
16
|
-
payload: Payload
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class ABCStateStorage(abc.ABC, typing.Generic[Payload]):
|
|
20
|
-
@abc.abstractmethod
|
|
21
|
-
async def get(self, user_id: int) -> Option[StateData[Payload]]: ...
|
|
22
|
-
|
|
23
|
-
@abc.abstractmethod
|
|
24
|
-
async def delete(self, user_id: int) -> None: ...
|
|
25
|
-
|
|
26
|
-
@abc.abstractmethod
|
|
27
|
-
async def set(self, user_id: int, key: str | enum.Enum, payload: Payload) -> None: ...
|
|
28
|
-
|
|
29
|
-
def State(self, key: str | StateMeta | enum.Enum = StateMeta.ANY, /) -> State[Payload]: # noqa: N802
|
|
30
|
-
"""Can be used as a shortcut to get a state rule dependant on current storage."""
|
|
31
|
-
|
|
32
|
-
return State(storage=self, key=key)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
__all__ = ("ABCStateStorage", "StateData")
|
|
1
|
+
import abc
|
|
2
|
+
import enum
|
|
3
|
+
import typing
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from fntypes import Option
|
|
7
|
+
|
|
8
|
+
from telegrinder.bot.rules.state import State, StateMeta
|
|
9
|
+
|
|
10
|
+
Payload = typing.TypeVar("Payload")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True, slots=True)
|
|
14
|
+
class StateData(typing.Generic[Payload]):
|
|
15
|
+
key: str | enum.Enum
|
|
16
|
+
payload: Payload
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ABCStateStorage(abc.ABC, typing.Generic[Payload]):
|
|
20
|
+
@abc.abstractmethod
|
|
21
|
+
async def get(self, user_id: int) -> Option[StateData[Payload]]: ...
|
|
22
|
+
|
|
23
|
+
@abc.abstractmethod
|
|
24
|
+
async def delete(self, user_id: int) -> None: ...
|
|
25
|
+
|
|
26
|
+
@abc.abstractmethod
|
|
27
|
+
async def set(self, user_id: int, key: str | enum.Enum, payload: Payload) -> None: ...
|
|
28
|
+
|
|
29
|
+
def State(self, key: str | StateMeta | enum.Enum = StateMeta.ANY, /) -> State[Payload]: # noqa: N802
|
|
30
|
+
"""Can be used as a shortcut to get a state rule dependant on current storage."""
|
|
31
|
+
|
|
32
|
+
return State(storage=self, key=key)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
__all__ = ("ABCStateStorage", "StateData")
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
|
-
from fntypes.option import Option
|
|
4
|
-
|
|
5
|
-
from telegrinder.tools.functional import from_optional
|
|
6
|
-
from telegrinder.tools.state_storage.abc import ABCStateStorage, StateData
|
|
7
|
-
|
|
8
|
-
Payload: typing.TypeAlias = dict[str, typing.Any]
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class MemoryStateStorage(ABCStateStorage[Payload]):
|
|
12
|
-
def __init__(self) -> None:
|
|
13
|
-
self.storage: dict[int, StateData[Payload]] = {}
|
|
14
|
-
|
|
15
|
-
async def get(self, user_id: int) -> Option[StateData[Payload]]:
|
|
16
|
-
return from_optional(self.storage.get(user_id))
|
|
17
|
-
|
|
18
|
-
async def set(self, user_id: int, key: str, payload: Payload) -> None:
|
|
19
|
-
self.storage[user_id] = StateData(key, payload)
|
|
20
|
-
|
|
21
|
-
async def delete(self, user_id: int) -> None:
|
|
22
|
-
self.storage.pop(user_id)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
__all__ = ("MemoryStateStorage",)
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from fntypes.option import Option
|
|
4
|
+
|
|
5
|
+
from telegrinder.tools.functional import from_optional
|
|
6
|
+
from telegrinder.tools.state_storage.abc import ABCStateStorage, StateData
|
|
7
|
+
|
|
8
|
+
Payload: typing.TypeAlias = dict[str, typing.Any]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MemoryStateStorage(ABCStateStorage[Payload]):
|
|
12
|
+
def __init__(self) -> None:
|
|
13
|
+
self.storage: dict[int, StateData[Payload]] = {}
|
|
14
|
+
|
|
15
|
+
async def get(self, user_id: int) -> Option[StateData[Payload]]:
|
|
16
|
+
return from_optional(self.storage.get(user_id))
|
|
17
|
+
|
|
18
|
+
async def set(self, user_id: int, key: str, payload: Payload) -> None:
|
|
19
|
+
self.storage[user_id] = StateData(key, payload)
|
|
20
|
+
|
|
21
|
+
async def delete(self, user_id: int) -> None:
|
|
22
|
+
self.storage.pop(user_id)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__all__ = ("MemoryStateStorage",)
|