telegrinder 0.4.2__py3-none-any.whl → 0.5.0__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 +37 -55
- telegrinder/__meta__.py +1 -0
- telegrinder/api/__init__.py +6 -4
- telegrinder/api/api.py +100 -26
- telegrinder/api/error.py +42 -8
- telegrinder/api/response.py +4 -1
- telegrinder/api/token.py +2 -2
- telegrinder/bot/__init__.py +9 -25
- telegrinder/bot/bot.py +31 -25
- telegrinder/bot/cute_types/__init__.py +0 -0
- telegrinder/bot/cute_types/base.py +103 -61
- telegrinder/bot/cute_types/callback_query.py +447 -400
- telegrinder/bot/cute_types/chat_join_request.py +59 -62
- telegrinder/bot/cute_types/chat_member_updated.py +154 -157
- telegrinder/bot/cute_types/inline_query.py +41 -44
- telegrinder/bot/cute_types/message.py +2621 -2590
- telegrinder/bot/cute_types/pre_checkout_query.py +38 -42
- telegrinder/bot/cute_types/update.py +1 -8
- telegrinder/bot/cute_types/utils.py +1 -1
- telegrinder/bot/dispatch/__init__.py +10 -15
- telegrinder/bot/dispatch/abc.py +12 -11
- telegrinder/bot/dispatch/action.py +104 -0
- telegrinder/bot/dispatch/context.py +32 -26
- telegrinder/bot/dispatch/dispatch.py +61 -134
- telegrinder/bot/dispatch/handler/__init__.py +2 -0
- telegrinder/bot/dispatch/handler/abc.py +10 -8
- telegrinder/bot/dispatch/handler/audio_reply.py +2 -3
- telegrinder/bot/dispatch/handler/base.py +10 -33
- telegrinder/bot/dispatch/handler/document_reply.py +2 -3
- telegrinder/bot/dispatch/handler/func.py +55 -87
- telegrinder/bot/dispatch/handler/media_group_reply.py +2 -3
- telegrinder/bot/dispatch/handler/message_reply.py +2 -3
- telegrinder/bot/dispatch/handler/photo_reply.py +2 -3
- telegrinder/bot/dispatch/handler/sticker_reply.py +2 -3
- telegrinder/bot/dispatch/handler/video_reply.py +2 -3
- telegrinder/bot/dispatch/middleware/__init__.py +0 -0
- telegrinder/bot/dispatch/middleware/abc.py +79 -55
- telegrinder/bot/dispatch/middleware/global_middleware.py +18 -33
- telegrinder/bot/dispatch/process.py +84 -105
- telegrinder/bot/dispatch/return_manager/__init__.py +0 -0
- telegrinder/bot/dispatch/return_manager/abc.py +102 -65
- telegrinder/bot/dispatch/return_manager/callback_query.py +4 -5
- telegrinder/bot/dispatch/return_manager/inline_query.py +3 -4
- telegrinder/bot/dispatch/return_manager/message.py +8 -10
- telegrinder/bot/dispatch/return_manager/pre_checkout_query.py +4 -5
- telegrinder/bot/dispatch/view/__init__.py +4 -4
- telegrinder/bot/dispatch/view/abc.py +6 -16
- telegrinder/bot/dispatch/view/base.py +54 -178
- telegrinder/bot/dispatch/view/box.py +19 -18
- telegrinder/bot/dispatch/view/callback_query.py +4 -8
- telegrinder/bot/dispatch/view/chat_join_request.py +5 -6
- telegrinder/bot/dispatch/view/chat_member.py +5 -25
- telegrinder/bot/dispatch/view/error.py +9 -0
- telegrinder/bot/dispatch/view/inline_query.py +4 -8
- telegrinder/bot/dispatch/view/message.py +5 -25
- telegrinder/bot/dispatch/view/pre_checkout_query.py +4 -8
- telegrinder/bot/dispatch/view/raw.py +3 -109
- telegrinder/bot/dispatch/waiter_machine/__init__.py +2 -5
- telegrinder/bot/dispatch/waiter_machine/actions.py +6 -4
- telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +1 -3
- telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +1 -1
- telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +11 -7
- telegrinder/bot/dispatch/waiter_machine/hasher/message.py +0 -0
- telegrinder/bot/dispatch/waiter_machine/machine.py +43 -60
- telegrinder/bot/dispatch/waiter_machine/middleware.py +19 -23
- telegrinder/bot/dispatch/waiter_machine/short_state.py +6 -5
- telegrinder/bot/polling/__init__.py +0 -0
- telegrinder/bot/polling/abc.py +0 -0
- telegrinder/bot/polling/polling.py +209 -88
- telegrinder/bot/rules/__init__.py +3 -16
- telegrinder/bot/rules/abc.py +42 -122
- telegrinder/bot/rules/callback_data.py +29 -49
- telegrinder/bot/rules/chat_join.py +5 -23
- telegrinder/bot/rules/command.py +8 -4
- telegrinder/bot/rules/enum_text.py +3 -4
- telegrinder/bot/rules/func.py +7 -14
- telegrinder/bot/rules/fuzzy.py +3 -4
- telegrinder/bot/rules/inline.py +8 -20
- telegrinder/bot/rules/integer.py +2 -3
- telegrinder/bot/rules/is_from.py +12 -11
- telegrinder/bot/rules/logic.py +11 -5
- telegrinder/bot/rules/markup.py +22 -14
- telegrinder/bot/rules/mention.py +8 -7
- telegrinder/bot/rules/message_entities.py +8 -4
- telegrinder/bot/rules/node.py +23 -12
- telegrinder/bot/rules/payload.py +5 -4
- telegrinder/bot/rules/payment_invoice.py +6 -21
- telegrinder/bot/rules/regex.py +2 -4
- telegrinder/bot/rules/rule_enum.py +8 -7
- telegrinder/bot/rules/start.py +5 -6
- telegrinder/bot/rules/state.py +1 -1
- telegrinder/bot/rules/text.py +4 -15
- telegrinder/bot/rules/update.py +3 -4
- telegrinder/bot/scenario/__init__.py +0 -0
- telegrinder/bot/scenario/abc.py +6 -5
- telegrinder/bot/scenario/checkbox.py +1 -1
- telegrinder/bot/scenario/choice.py +30 -39
- telegrinder/client/__init__.py +3 -5
- telegrinder/client/abc.py +11 -6
- telegrinder/client/aiohttp.py +141 -27
- telegrinder/client/form_data.py +1 -1
- telegrinder/model.py +61 -89
- telegrinder/modules.py +325 -102
- telegrinder/msgspec_utils/__init__.py +40 -0
- telegrinder/msgspec_utils/abc.py +18 -0
- telegrinder/msgspec_utils/custom_types/__init__.py +6 -0
- telegrinder/msgspec_utils/custom_types/datetime.py +24 -0
- telegrinder/msgspec_utils/custom_types/enum_meta.py +43 -0
- telegrinder/msgspec_utils/custom_types/literal.py +25 -0
- telegrinder/msgspec_utils/custom_types/option.py +17 -0
- telegrinder/msgspec_utils/decoder.py +389 -0
- telegrinder/msgspec_utils/encoder.py +206 -0
- telegrinder/{msgspec_json.py → msgspec_utils/json.py} +6 -5
- telegrinder/msgspec_utils/tools.py +75 -0
- telegrinder/node/__init__.py +24 -7
- telegrinder/node/attachment.py +1 -0
- telegrinder/node/base.py +154 -72
- telegrinder/node/callback_query.py +5 -5
- telegrinder/node/collection.py +39 -0
- telegrinder/node/command.py +1 -2
- telegrinder/node/composer.py +121 -72
- telegrinder/node/container.py +11 -8
- telegrinder/node/context.py +48 -0
- telegrinder/node/either.py +27 -40
- telegrinder/node/error.py +41 -0
- telegrinder/node/event.py +37 -11
- telegrinder/node/exceptions.py +7 -0
- telegrinder/node/file.py +0 -0
- telegrinder/node/i18n.py +108 -0
- telegrinder/node/me.py +3 -2
- telegrinder/node/payload.py +1 -1
- telegrinder/node/polymorphic.py +63 -28
- telegrinder/node/reply_message.py +12 -0
- telegrinder/node/rule.py +6 -13
- telegrinder/node/scope.py +14 -5
- telegrinder/node/session.py +53 -0
- telegrinder/node/source.py +41 -9
- telegrinder/node/text.py +1 -2
- telegrinder/node/tools/__init__.py +0 -0
- telegrinder/node/tools/generator.py +3 -5
- telegrinder/node/utility.py +16 -0
- telegrinder/py.typed +0 -0
- telegrinder/rules.py +0 -0
- telegrinder/tools/__init__.py +48 -88
- telegrinder/tools/aio.py +103 -0
- telegrinder/tools/callback_data_serialization/__init__.py +5 -0
- telegrinder/tools/{callback_data_serilization → callback_data_serialization}/abc.py +0 -0
- telegrinder/tools/{callback_data_serilization → callback_data_serialization}/json_ser.py +2 -3
- telegrinder/tools/{callback_data_serilization → callback_data_serialization}/msgpack_ser.py +45 -27
- telegrinder/tools/final.py +21 -0
- telegrinder/tools/formatting/__init__.py +2 -18
- telegrinder/tools/formatting/deep_links/__init__.py +39 -0
- telegrinder/tools/formatting/{deep_links.py → deep_links/links.py} +12 -85
- telegrinder/tools/formatting/deep_links/parsing.py +90 -0
- telegrinder/tools/formatting/deep_links/validators.py +8 -0
- telegrinder/tools/formatting/html_formatter.py +18 -45
- telegrinder/tools/fullname.py +83 -0
- telegrinder/tools/global_context/__init__.py +4 -3
- telegrinder/tools/global_context/abc.py +17 -14
- telegrinder/tools/global_context/builtin_context.py +39 -0
- telegrinder/tools/global_context/global_context.py +138 -39
- telegrinder/tools/input_file_directory.py +0 -0
- telegrinder/tools/keyboard/__init__.py +39 -0
- telegrinder/tools/keyboard/abc.py +159 -0
- telegrinder/tools/keyboard/base.py +77 -0
- telegrinder/tools/keyboard/buttons/__init__.py +14 -0
- telegrinder/tools/keyboard/buttons/base.py +18 -0
- telegrinder/tools/{buttons.py → keyboard/buttons/buttons.py} +71 -23
- telegrinder/tools/keyboard/buttons/static_buttons.py +56 -0
- telegrinder/tools/keyboard/buttons/tools.py +18 -0
- telegrinder/tools/keyboard/data.py +20 -0
- telegrinder/tools/keyboard/keyboard.py +131 -0
- telegrinder/tools/keyboard/static_keyboard.py +83 -0
- telegrinder/tools/lifespan.py +87 -51
- telegrinder/tools/limited_dict.py +4 -1
- telegrinder/tools/loop_wrapper.py +332 -0
- telegrinder/tools/magic/__init__.py +32 -0
- telegrinder/tools/magic/annotations.py +165 -0
- telegrinder/tools/magic/dictionary.py +20 -0
- telegrinder/tools/magic/function.py +246 -0
- telegrinder/tools/magic/shortcut.py +111 -0
- telegrinder/tools/parse_mode.py +9 -3
- telegrinder/tools/singleton/__init__.py +4 -0
- telegrinder/tools/singleton/abc.py +14 -0
- telegrinder/tools/singleton/singleton.py +18 -0
- telegrinder/tools/state_storage/__init__.py +0 -0
- telegrinder/tools/state_storage/abc.py +6 -1
- telegrinder/tools/state_storage/memory.py +1 -1
- telegrinder/tools/strings.py +0 -0
- telegrinder/types/__init__.py +307 -268
- telegrinder/types/enums.py +64 -37
- telegrinder/types/input_file.py +3 -3
- telegrinder/types/methods.py +5699 -5055
- telegrinder/types/methods_utils.py +62 -0
- telegrinder/types/objects.py +7846 -7058
- telegrinder/verification_utils.py +3 -1
- telegrinder-0.5.0.dist-info/METADATA +162 -0
- telegrinder-0.5.0.dist-info/RECORD +200 -0
- {telegrinder-0.4.2.dist-info → telegrinder-0.5.0.dist-info}/licenses/LICENSE +2 -2
- telegrinder/bot/dispatch/waiter_machine/hasher/state.py +0 -20
- telegrinder/bot/rules/id.py +0 -24
- telegrinder/bot/rules/message.py +0 -15
- telegrinder/client/sonic.py +0 -212
- telegrinder/msgspec_utils.py +0 -478
- telegrinder/tools/adapter/__init__.py +0 -19
- telegrinder/tools/adapter/abc.py +0 -49
- telegrinder/tools/adapter/dataclass.py +0 -56
- telegrinder/tools/adapter/errors.py +0 -5
- telegrinder/tools/adapter/event.py +0 -61
- telegrinder/tools/adapter/node.py +0 -46
- telegrinder/tools/adapter/raw_event.py +0 -27
- telegrinder/tools/adapter/raw_update.py +0 -30
- telegrinder/tools/callback_data_serilization/__init__.py +0 -5
- telegrinder/tools/error_handler/__init__.py +0 -10
- telegrinder/tools/error_handler/abc.py +0 -30
- telegrinder/tools/error_handler/error.py +0 -9
- telegrinder/tools/error_handler/error_handler.py +0 -179
- telegrinder/tools/formatting/spec_html_formats.py +0 -75
- telegrinder/tools/functional.py +0 -8
- telegrinder/tools/global_context/telegrinder_ctx.py +0 -27
- telegrinder/tools/i18n/__init__.py +0 -12
- telegrinder/tools/i18n/abc.py +0 -32
- telegrinder/tools/i18n/middleware/__init__.py +0 -3
- telegrinder/tools/i18n/middleware/abc.py +0 -22
- telegrinder/tools/i18n/simple.py +0 -43
- telegrinder/tools/keyboard.py +0 -132
- telegrinder/tools/loop_wrapper/__init__.py +0 -4
- telegrinder/tools/loop_wrapper/abc.py +0 -20
- telegrinder/tools/loop_wrapper/loop_wrapper.py +0 -169
- telegrinder/tools/magic.py +0 -344
- telegrinder-0.4.2.dist-info/METADATA +0 -151
- telegrinder-0.4.2.dist-info/RECORD +0 -182
- {telegrinder-0.4.2.dist-info → telegrinder-0.5.0.dist-info}/WHEEL +0 -0
telegrinder/modules.py
CHANGED
|
@@ -3,22 +3,39 @@ import typing
|
|
|
3
3
|
|
|
4
4
|
from choicelib import choice_in_order
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
from telegrinder.msgspec_utils import json
|
|
7
|
+
|
|
8
|
+
if typing.TYPE_CHECKING:
|
|
9
|
+
from logging import Handler as LoggingBasicHandler
|
|
10
|
+
|
|
11
|
+
from loguru import AsyncHandlerConfig as LoguruAsyncHandlerConfig # type: ignore
|
|
12
|
+
from loguru import BasicHandlerConfig as LoguruBasicHandlerConfig # type: ignore
|
|
13
|
+
from loguru import FileHandlerConfig as LoguruFileHandlerConfig # type: ignore
|
|
14
|
+
from loguru import HandlerConfig as LoguruHandlerConfig # type: ignore
|
|
15
|
+
else:
|
|
16
|
+
LoguruAsyncHandlerConfig = LoguruBasicHandlerConfig = LoguruFileHandlerConfig = dict
|
|
17
|
+
|
|
18
|
+
type _LoggerHandler = LoggingBasicHandler | LoguruHandlerConfig
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _remove_handlers(logger: typing.Any, /) -> None:
|
|
22
|
+
for hdlr in logger.handlers[:]:
|
|
23
|
+
logger.removeHandler(hdlr)
|
|
7
24
|
|
|
8
25
|
|
|
9
26
|
@typing.runtime_checkable
|
|
10
27
|
class LoggerModule(typing.Protocol):
|
|
11
|
-
def debug(self, __msg:
|
|
28
|
+
def debug(self, __msg: typing.Any, *args: typing.Any, **kwargs: typing.Any) -> None: ...
|
|
12
29
|
|
|
13
|
-
def info(self, __msg:
|
|
30
|
+
def info(self, __msg: typing.Any, *args: typing.Any, **kwargs: typing.Any) -> None: ...
|
|
14
31
|
|
|
15
|
-
def warning(self, __msg:
|
|
32
|
+
def warning(self, __msg: typing.Any, *args: typing.Any, **kwargs: typing.Any) -> None: ...
|
|
16
33
|
|
|
17
|
-
def error(self, __msg:
|
|
34
|
+
def error(self, __msg: typing.Any, *args: typing.Any, **kwargs: typing.Any) -> None: ...
|
|
18
35
|
|
|
19
|
-
def critical(self, __msg:
|
|
36
|
+
def critical(self, __msg: typing.Any, *args: typing.Any, **kwargs: typing.Any) -> None: ...
|
|
20
37
|
|
|
21
|
-
def exception(self, __msg:
|
|
38
|
+
def exception(self, __msg: typing.Any, *args: typing.Any, **kwargs: typing.Any) -> None: ...
|
|
22
39
|
|
|
23
40
|
if typing.TYPE_CHECKING:
|
|
24
41
|
|
|
@@ -35,11 +52,14 @@ class LoggerModule(typing.Protocol):
|
|
|
35
52
|
/,
|
|
36
53
|
) -> None: ...
|
|
37
54
|
|
|
55
|
+
def set_new_handler(self, new_handler: _LoggerHandler, /) -> None: ...
|
|
56
|
+
|
|
38
57
|
|
|
39
58
|
logger: LoggerModule
|
|
40
59
|
logging_level = os.getenv("LOGGER_LEVEL", default="DEBUG").upper()
|
|
41
|
-
logging_module = choice_in_order(["loguru"], default="logging", do_import=False)
|
|
42
|
-
asyncio_module = choice_in_order(["uvloop"], default="asyncio", do_import=False)
|
|
60
|
+
logging_module = choice_in_order(["structlog", "loguru"], default="logging", do_import=False)
|
|
61
|
+
asyncio_module = choice_in_order(["uvloop", "winloop"], default="asyncio", do_import=False)
|
|
62
|
+
|
|
43
63
|
|
|
44
64
|
if logging_module == "loguru":
|
|
45
65
|
import os
|
|
@@ -63,6 +83,166 @@ if logging_module == "loguru":
|
|
|
63
83
|
level=logging_level,
|
|
64
84
|
)
|
|
65
85
|
|
|
86
|
+
elif logging_module == "structlog":
|
|
87
|
+
import logging
|
|
88
|
+
import re
|
|
89
|
+
import sys
|
|
90
|
+
import typing
|
|
91
|
+
from contextlib import suppress
|
|
92
|
+
|
|
93
|
+
import colorama
|
|
94
|
+
import structlog # type: ignore
|
|
95
|
+
|
|
96
|
+
LEVELS_COLORS = dict(
|
|
97
|
+
debug=colorama.Fore.LIGHTBLUE_EX,
|
|
98
|
+
info=colorama.Fore.LIGHTGREEN_EX,
|
|
99
|
+
warning=colorama.Fore.LIGHTYELLOW_EX,
|
|
100
|
+
error=colorama.Fore.LIGHTRED_EX,
|
|
101
|
+
critical=colorama.Fore.LIGHTRED_EX,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
class SLF4JStyleFormatter:
|
|
105
|
+
TOKENS = frozenset(("{}", "{!s}", "{!r}", "{!a}"))
|
|
106
|
+
TOKENS_PATTERN = re.compile(r"({!r}|{})")
|
|
107
|
+
|
|
108
|
+
def __init__(self, *, remove_positional_args: bool = True) -> None:
|
|
109
|
+
self.remove_positional_args = remove_positional_args
|
|
110
|
+
|
|
111
|
+
def __call__(
|
|
112
|
+
self,
|
|
113
|
+
logger: typing.Any,
|
|
114
|
+
method_name: str,
|
|
115
|
+
event_dict: dict[str, typing.Any],
|
|
116
|
+
) -> dict[str, typing.Any]:
|
|
117
|
+
args = event_dict.get("positional_args")
|
|
118
|
+
if not args:
|
|
119
|
+
return event_dict
|
|
120
|
+
|
|
121
|
+
event = event_dict.get("event", "")
|
|
122
|
+
if not isinstance(event, str):
|
|
123
|
+
return event_dict
|
|
124
|
+
|
|
125
|
+
log_level = event_dict.get("level", "debug")
|
|
126
|
+
with suppress(TypeError, ValueError, IndexError):
|
|
127
|
+
if "{}" in event or "{!r}" in event:
|
|
128
|
+
event_dict["event"] = self._safe_format_braces(event, args, log_level)
|
|
129
|
+
elif len(args) == 1 and isinstance(args[0], dict):
|
|
130
|
+
formatted = event % args[0]
|
|
131
|
+
event_dict["event"] = self._highlight_values(
|
|
132
|
+
formatted, args[0].values(), log_level, percent_style=True
|
|
133
|
+
)
|
|
134
|
+
else:
|
|
135
|
+
formatted = event % args
|
|
136
|
+
event_dict["event"] = self._highlight_values(formatted, args, log_level, percent_style=True)
|
|
137
|
+
|
|
138
|
+
if self.remove_positional_args and "positional_args" in event_dict:
|
|
139
|
+
del event_dict["positional_args"]
|
|
140
|
+
|
|
141
|
+
return event_dict
|
|
142
|
+
|
|
143
|
+
def _colorize(self, value: typing.Any, log_level: str) -> str:
|
|
144
|
+
return f"{LEVELS_COLORS[log_level]}{value}{colorama.Fore.RESET}"
|
|
145
|
+
|
|
146
|
+
def _safe_format_braces(
|
|
147
|
+
self,
|
|
148
|
+
message: str,
|
|
149
|
+
args: tuple[typing.Any, ...],
|
|
150
|
+
log_level: str,
|
|
151
|
+
) -> str:
|
|
152
|
+
tokens = self.TOKENS_PATTERN.split(message)
|
|
153
|
+
result = []
|
|
154
|
+
arg_index = 0
|
|
155
|
+
|
|
156
|
+
for token in tokens:
|
|
157
|
+
if token in self.TOKENS and arg_index < len(args):
|
|
158
|
+
result.append(
|
|
159
|
+
self._colorize(
|
|
160
|
+
str(args[arg_index]) if token != "{!r}" else repr(args[arg_index]),
|
|
161
|
+
log_level,
|
|
162
|
+
),
|
|
163
|
+
)
|
|
164
|
+
arg_index += 1
|
|
165
|
+
else:
|
|
166
|
+
result.append(token)
|
|
167
|
+
|
|
168
|
+
return "".join(result)
|
|
169
|
+
|
|
170
|
+
def _highlight_values(
|
|
171
|
+
self,
|
|
172
|
+
full_message: str,
|
|
173
|
+
values: typing.Iterable[typing.Any],
|
|
174
|
+
log_level: str,
|
|
175
|
+
percent_style: bool = False,
|
|
176
|
+
) -> str:
|
|
177
|
+
for v in values:
|
|
178
|
+
with suppress(Exception):
|
|
179
|
+
raw = repr(v) if percent_style and ("%r" in full_message) else str(v)
|
|
180
|
+
pattern = re.compile(rf"(?<!%)\b{re.escape(raw)}\b")
|
|
181
|
+
full_message = pattern.sub(
|
|
182
|
+
lambda m: self._colorize(m.group(0), log_level), full_message, count=1
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
return full_message
|
|
186
|
+
|
|
187
|
+
class LogLevelColumnFormatter:
|
|
188
|
+
def __call__(self, key: str, value: typing.Any) -> str:
|
|
189
|
+
color = LEVELS_COLORS[value]
|
|
190
|
+
return f"[{color}{value:^12}{colorama.Fore.RESET}]"
|
|
191
|
+
|
|
192
|
+
class Filter(logging.Filter):
|
|
193
|
+
def filter(self, record: logging.LogRecord) -> bool:
|
|
194
|
+
level_color = LEVELS_COLORS[record.levelname.lower()]
|
|
195
|
+
location = (
|
|
196
|
+
f"{colorama.Fore.LIGHTCYAN_EX}{record.module}{colorama.Fore.RESET}:"
|
|
197
|
+
f"{level_color}{record.funcName}{colorama.Fore.RESET}:"
|
|
198
|
+
f"{colorama.Fore.LIGHTMAGENTA_EX}{record.lineno}{colorama.Fore.RESET} "
|
|
199
|
+
)
|
|
200
|
+
record.location = location
|
|
201
|
+
return True
|
|
202
|
+
|
|
203
|
+
def configure_logging() -> None:
|
|
204
|
+
console_renderer = structlog.dev.ConsoleRenderer(colors=True)
|
|
205
|
+
|
|
206
|
+
for column in console_renderer._columns:
|
|
207
|
+
if column.key == "level":
|
|
208
|
+
column.formatter = LogLevelColumnFormatter()
|
|
209
|
+
break
|
|
210
|
+
|
|
211
|
+
structlog.configure( # type: ignore
|
|
212
|
+
processors=[
|
|
213
|
+
structlog.stdlib.filter_by_level,
|
|
214
|
+
structlog.stdlib.add_log_level,
|
|
215
|
+
SLF4JStyleFormatter(), # type: ignore
|
|
216
|
+
structlog.processors.StackInfoRenderer(),
|
|
217
|
+
structlog.processors.format_exc_info,
|
|
218
|
+
structlog.processors.UnicodeDecoder(),
|
|
219
|
+
console_renderer,
|
|
220
|
+
],
|
|
221
|
+
context_class=dict,
|
|
222
|
+
logger_factory=structlog.stdlib.LoggerFactory(),
|
|
223
|
+
wrapper_class=structlog.stdlib.BoundLogger,
|
|
224
|
+
cache_logger_on_first_use=True,
|
|
225
|
+
)
|
|
226
|
+
fmt = (
|
|
227
|
+
f"[{colorama.Fore.LIGHTBLUE_EX}{{name}}{colorama.Style.RESET_ALL}] "
|
|
228
|
+
f"{colorama.Fore.LIGHTWHITE_EX}{{location}}{colorama.Style.RESET_ALL}"
|
|
229
|
+
f"[{colorama.Fore.LIGHTBLACK_EX}{{asctime}}{colorama.Style.RESET_ALL}] "
|
|
230
|
+
f"{colorama.Fore.LIGHTWHITE_EX}~{colorama.Style.RESET_ALL} {{message}}"
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
telegrinder_logger = logging.getLogger("telegrinder")
|
|
234
|
+
telegrinder_logger.setLevel(logging_level)
|
|
235
|
+
|
|
236
|
+
handler = logging.StreamHandler(sys.stderr)
|
|
237
|
+
handler.addFilter(Filter())
|
|
238
|
+
formatter = logging.Formatter(fmt, datefmt="%Y-%m-%d %H:%M:%S", style="{")
|
|
239
|
+
handler.setFormatter(formatter)
|
|
240
|
+
_remove_handlers(telegrinder_logger)
|
|
241
|
+
telegrinder_logger.addHandler(handler)
|
|
242
|
+
|
|
243
|
+
configure_logging()
|
|
244
|
+
logger = structlog.get_logger("telegrinder") # type: ignore
|
|
245
|
+
|
|
66
246
|
elif logging_module == "logging":
|
|
67
247
|
"""
|
|
68
248
|
This is a workaround for lazy formatting with {} in logging.
|
|
@@ -76,99 +256,109 @@ elif logging_module == "logging":
|
|
|
76
256
|
|
|
77
257
|
import colorama
|
|
78
258
|
|
|
79
|
-
colorama.just_fix_windows_console()
|
|
259
|
+
colorama.just_fix_windows_console()
|
|
260
|
+
colorama.init()
|
|
80
261
|
|
|
81
|
-
|
|
82
|
-
"<
|
|
83
|
-
" <
|
|
84
|
-
"{module}</level_module><
|
|
85
|
-
"{funcName}</
|
|
86
|
-
"
|
|
87
|
-
|
|
262
|
+
LOG_FORMAT = (
|
|
263
|
+
"<light_white>{name: <4} |</light_white> <level>{levelname: <8}</level>"
|
|
264
|
+
" <light_white>|</light_white> <light_green>{asctime}</light_green> <light_white>"
|
|
265
|
+
"|</light_white> <level_module>{module}</level_module><light_white>:</light_white>"
|
|
266
|
+
"<func_name>{funcName}</func_name><light_white>:</light_white><lineno>{lineno}</lineno>"
|
|
267
|
+
" <light_white>></light_white> <message>{message}</message>"
|
|
268
|
+
)
|
|
269
|
+
COLORS = dict(
|
|
270
|
+
reset=colorama.Style.RESET_ALL,
|
|
271
|
+
red=colorama.Fore.RED,
|
|
272
|
+
green=colorama.Fore.GREEN,
|
|
273
|
+
blue=colorama.Fore.BLUE,
|
|
274
|
+
white=colorama.Fore.WHITE,
|
|
275
|
+
yellow=colorama.Fore.YELLOW,
|
|
276
|
+
magenta=colorama.Fore.MAGENTA,
|
|
277
|
+
cyan=colorama.Fore.CYAN,
|
|
278
|
+
light_red=colorama.Fore.LIGHTRED_EX,
|
|
279
|
+
light_green=colorama.Fore.LIGHTGREEN_EX,
|
|
280
|
+
light_blue=colorama.Fore.LIGHTBLUE_EX,
|
|
281
|
+
light_white=colorama.Fore.LIGHTWHITE_EX,
|
|
282
|
+
light_yellow=colorama.Fore.LIGHTYELLOW_EX,
|
|
283
|
+
light_magenta=colorama.Fore.LIGHTMAGENTA_EX,
|
|
284
|
+
light_cyan=colorama.Fore.LIGHTCYAN_EX,
|
|
285
|
+
)
|
|
286
|
+
LEVEL_FORMAT_SETTINGS = dict(
|
|
287
|
+
DEBUG=dict(
|
|
288
|
+
level="light_blue",
|
|
289
|
+
level_module="blue",
|
|
290
|
+
func_name="blue",
|
|
291
|
+
lineno="light_yellow",
|
|
292
|
+
message="light_blue",
|
|
293
|
+
),
|
|
294
|
+
INFO=dict(
|
|
295
|
+
level="cyan",
|
|
296
|
+
level_module="light_cyan",
|
|
297
|
+
func_name="light_cyan",
|
|
298
|
+
lineno="light_yellow",
|
|
299
|
+
message="light_green",
|
|
300
|
+
),
|
|
301
|
+
WARNING=dict(
|
|
302
|
+
level="light_yellow",
|
|
303
|
+
level_module="light_magenta",
|
|
304
|
+
func_name="light_magenta",
|
|
305
|
+
lineno="light_blue",
|
|
306
|
+
message="light_yellow",
|
|
307
|
+
),
|
|
308
|
+
ERROR=dict(
|
|
309
|
+
level="red",
|
|
310
|
+
level_module="light_yellow",
|
|
311
|
+
func_name="light_yellow",
|
|
312
|
+
lineno="light_blue",
|
|
313
|
+
message="light_red",
|
|
314
|
+
),
|
|
315
|
+
CRITICAL=dict(
|
|
316
|
+
level="magenta",
|
|
317
|
+
level_module="light_red",
|
|
318
|
+
func_name="light_red",
|
|
319
|
+
lineno="light_yellow",
|
|
320
|
+
message="light_magenta",
|
|
321
|
+
),
|
|
88
322
|
)
|
|
89
|
-
|
|
90
|
-
"
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"yellow": colorama.Fore.LIGHTYELLOW_EX,
|
|
95
|
-
"magenta": colorama.Fore.LIGHTMAGENTA_EX,
|
|
96
|
-
"cyan": colorama.Fore.LIGHTCYAN_EX,
|
|
97
|
-
"reset": colorama.Style.RESET_ALL,
|
|
98
|
-
}
|
|
99
|
-
LEVEL_SETTINGS = {
|
|
100
|
-
"INFO": {
|
|
101
|
-
"level": "green",
|
|
102
|
-
"level_module": "blue",
|
|
103
|
-
"level_func": "cyan",
|
|
104
|
-
"level_lineno": "white",
|
|
105
|
-
"level_message": "green",
|
|
106
|
-
},
|
|
107
|
-
"DEBUG": {
|
|
108
|
-
"level": "blue",
|
|
109
|
-
"level_module": "yellow",
|
|
110
|
-
"level_func": "green",
|
|
111
|
-
"level_lineno": "cyan",
|
|
112
|
-
"level_message": "blue",
|
|
113
|
-
},
|
|
114
|
-
"WARNING": {
|
|
115
|
-
"level": "yellow",
|
|
116
|
-
"level_module": "red",
|
|
117
|
-
"level_func": "green",
|
|
118
|
-
"level_lineno": "red",
|
|
119
|
-
"level_message": "yellow",
|
|
120
|
-
},
|
|
121
|
-
"ERROR": {
|
|
122
|
-
"level": "red",
|
|
123
|
-
"level_module": "magenta",
|
|
124
|
-
"level_func": "yellow",
|
|
125
|
-
"level_lineno": "green",
|
|
126
|
-
"level_message": "red",
|
|
127
|
-
},
|
|
128
|
-
"CRITICAL": {
|
|
129
|
-
"level": "cyan",
|
|
130
|
-
"level_module": "yellow",
|
|
131
|
-
"level_func": "yellow",
|
|
132
|
-
"level_lineno": "yellow",
|
|
133
|
-
"level_message": "cyan",
|
|
134
|
-
},
|
|
135
|
-
}
|
|
136
|
-
FORMAT = (
|
|
137
|
-
FORMAT.replace("<white>", COLORS["white"])
|
|
138
|
-
.replace("</white>", COLORS["reset"])
|
|
139
|
-
.replace("<green>", COLORS["green"])
|
|
140
|
-
.replace("</green>", COLORS["reset"])
|
|
323
|
+
LOG_FORMAT = (
|
|
324
|
+
LOG_FORMAT.replace("<light_white>", COLORS["light_white"])
|
|
325
|
+
.replace("</light_white>", COLORS["reset"])
|
|
326
|
+
.replace("<light_green>", COLORS["light_green"])
|
|
327
|
+
.replace("</light_green>", COLORS["reset"])
|
|
141
328
|
)
|
|
142
|
-
LEVEL_FORMATS
|
|
143
|
-
|
|
144
|
-
|
|
329
|
+
LEVEL_FORMATS = dict[str, str]()
|
|
330
|
+
|
|
331
|
+
for level, settings in LEVEL_FORMAT_SETTINGS.items():
|
|
332
|
+
fmt = LOG_FORMAT
|
|
333
|
+
|
|
145
334
|
for name, color in settings.items():
|
|
146
335
|
fmt = fmt.replace(f"<{name}>", COLORS[color]).replace(f"</{name}>", COLORS["reset"])
|
|
336
|
+
|
|
147
337
|
LEVEL_FORMATS[level] = fmt
|
|
148
338
|
|
|
149
339
|
class TelegrinderLoggingFormatter(logging.Formatter):
|
|
150
340
|
def format(self, record: logging.LogRecord) -> str:
|
|
151
341
|
if not record.funcName or record.funcName == "<module>":
|
|
152
342
|
record.funcName = "\b"
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if frame:
|
|
162
|
-
module =
|
|
163
|
-
|
|
343
|
+
|
|
344
|
+
frame = sys._getframe(1)
|
|
345
|
+
while frame:
|
|
346
|
+
if frame.f_code.co_filename == record.pathname and frame.f_lineno == record.lineno:
|
|
347
|
+
break
|
|
348
|
+
|
|
349
|
+
frame = frame.f_back
|
|
350
|
+
|
|
351
|
+
if frame is not None:
|
|
352
|
+
record.module = frame.f_globals.get("__name__", "<module>")
|
|
353
|
+
|
|
164
354
|
return logging.Formatter(
|
|
165
|
-
LEVEL_FORMATS.get(record.levelname),
|
|
355
|
+
fmt=LEVEL_FORMATS.get(record.levelname),
|
|
166
356
|
datefmt="%Y-%m-%d %H:%M:%S",
|
|
167
357
|
style="{",
|
|
168
358
|
).format(record)
|
|
169
359
|
|
|
170
360
|
class LogMessage:
|
|
171
|
-
def __init__(self, fmt:
|
|
361
|
+
def __init__(self, fmt: str, args: typing.Any, kwargs: typing.Any) -> None:
|
|
172
362
|
self.fmt = fmt
|
|
173
363
|
self.args = args
|
|
174
364
|
self.kwargs = kwargs
|
|
@@ -177,41 +367,44 @@ elif logging_module == "logging":
|
|
|
177
367
|
return self.fmt.format(*self.args, **self.kwargs)
|
|
178
368
|
|
|
179
369
|
class TelegrinderLoggingStyleAdapter(logging.LoggerAdapter):
|
|
370
|
+
logger: logging.Logger
|
|
371
|
+
|
|
180
372
|
def __init__(
|
|
181
373
|
self,
|
|
182
|
-
logger:
|
|
183
|
-
extra:
|
|
374
|
+
logger: logging.Logger,
|
|
375
|
+
**extra: typing.Any,
|
|
184
376
|
) -> None:
|
|
185
|
-
super().__init__(logger, extra
|
|
377
|
+
super().__init__(logger, extra=extra)
|
|
378
|
+
self.log_arg_names = frozenset(inspect.getfullargspec(self.logger._log).args[1:])
|
|
186
379
|
|
|
187
|
-
def log(self, level: int, msg:
|
|
380
|
+
def log(self, level: int, msg: typing.Any, *args: typing.Any, **kwargs: typing.Any) -> None:
|
|
188
381
|
if self.isEnabledFor(level):
|
|
189
|
-
kwargs.setdefault("stacklevel", 2)
|
|
190
382
|
msg, args, kwargs = self.proc(msg, args, kwargs)
|
|
191
383
|
self.logger._log(level, msg, args, **kwargs)
|
|
192
384
|
|
|
193
385
|
def proc(
|
|
194
386
|
self,
|
|
195
|
-
msg:
|
|
196
|
-
args: tuple[
|
|
197
|
-
kwargs: dict[str,
|
|
198
|
-
) -> tuple[
|
|
199
|
-
|
|
200
|
-
key: kwargs[key] for key in inspect.getfullargspec(self.logger._log).args[1:] if key in kwargs
|
|
201
|
-
}
|
|
387
|
+
msg: typing.Any,
|
|
388
|
+
args: tuple[typing.Any, ...],
|
|
389
|
+
kwargs: dict[str, typing.Any],
|
|
390
|
+
) -> tuple[typing.Any, tuple[typing.Any, ...], dict[str, typing.Any]]:
|
|
391
|
+
kwargs.setdefault("stacklevel", 2)
|
|
202
392
|
|
|
203
393
|
if isinstance(msg, str):
|
|
204
394
|
msg = LogMessage(msg, args, kwargs)
|
|
205
395
|
args = tuple()
|
|
206
|
-
|
|
396
|
+
|
|
397
|
+
return msg, args, {name: kwargs[name] for name in self.log_arg_names if name in kwargs}
|
|
207
398
|
|
|
208
399
|
handler = logging.StreamHandler(sys.stderr)
|
|
209
400
|
handler.setFormatter(TelegrinderLoggingFormatter())
|
|
210
401
|
logger = logging.getLogger("telegrinder") # type: ignore
|
|
402
|
+
_remove_handlers(logger)
|
|
211
403
|
logger.setLevel(logging_level) # type: ignore
|
|
212
404
|
logger.addHandler(handler) # type: ignore
|
|
213
405
|
logger = TelegrinderLoggingStyleAdapter(logger) # type: ignore
|
|
214
406
|
|
|
407
|
+
|
|
215
408
|
if asyncio_module == "uvloop":
|
|
216
409
|
import asyncio
|
|
217
410
|
|
|
@@ -219,10 +412,17 @@ if asyncio_module == "uvloop":
|
|
|
219
412
|
|
|
220
413
|
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) # type: ignore
|
|
221
414
|
|
|
415
|
+
elif asyncio_module == "winloop":
|
|
416
|
+
import asyncio
|
|
417
|
+
|
|
418
|
+
import winloop # type: ignore
|
|
419
|
+
|
|
420
|
+
asyncio.set_event_loop_policy(winloop.EventLoopPolicy()) # type: ignore
|
|
222
421
|
|
|
223
|
-
|
|
422
|
+
|
|
423
|
+
def _set_logger_level(level: str, /) -> None:
|
|
224
424
|
level = level.upper()
|
|
225
|
-
if logging_module
|
|
425
|
+
if logging_module in ("logging", "structlog"):
|
|
226
426
|
import logging
|
|
227
427
|
|
|
228
428
|
logging.getLogger("telegrinder").setLevel(level)
|
|
@@ -233,7 +433,30 @@ def _set_logger_level(level, /):
|
|
|
233
433
|
loguru.logger._core.handlers[handler_id]._levelno = loguru.logger.level(level).no # type: ignore
|
|
234
434
|
|
|
235
435
|
|
|
236
|
-
|
|
436
|
+
def _set_logger_handler(new_handler: typing.Any, /) -> None:
|
|
437
|
+
if logging_module in ("logging", "structlog"):
|
|
438
|
+
import logging
|
|
439
|
+
|
|
440
|
+
telegrinder_logger = logging.getLogger("telegrinder")
|
|
441
|
+
_remove_handlers(telegrinder_logger)
|
|
442
|
+
telegrinder_logger.addHandler(new_handler)
|
|
443
|
+
elif logging_module == "loguru":
|
|
444
|
+
import loguru # type: ignore
|
|
445
|
+
|
|
446
|
+
global handler_id # type: ignore
|
|
447
|
+
loguru.logger.remove(handler_id) # type: ignore
|
|
448
|
+
handler_id = loguru.logger.configure(handlers=(new_handler,))[0] # type: ignore
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
setattr(logger, "set_level", staticmethod(_set_logger_level))
|
|
452
|
+
setattr(logger, "set_new_handler", staticmethod(_set_logger_handler))
|
|
237
453
|
|
|
238
454
|
|
|
239
|
-
__all__ = (
|
|
455
|
+
__all__ = (
|
|
456
|
+
"LoggerModule",
|
|
457
|
+
"LoguruAsyncHandlerConfig",
|
|
458
|
+
"LoguruBasicHandlerConfig",
|
|
459
|
+
"LoguruFileHandlerConfig",
|
|
460
|
+
"json",
|
|
461
|
+
"logger",
|
|
462
|
+
)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from telegrinder.msgspec_utils.abc import SupportsCast, is_supports_cast
|
|
2
|
+
from telegrinder.msgspec_utils.custom_types.datetime import datetime, timedelta
|
|
3
|
+
from telegrinder.msgspec_utils.custom_types.enum_meta import BaseEnumMeta
|
|
4
|
+
from telegrinder.msgspec_utils.custom_types.literal import Literal
|
|
5
|
+
from telegrinder.msgspec_utils.custom_types.option import Option
|
|
6
|
+
from telegrinder.msgspec_utils.decoder import Decoder, convert, decoder
|
|
7
|
+
from telegrinder.msgspec_utils.encoder import Encoder, encoder, to_builtins
|
|
8
|
+
from telegrinder.msgspec_utils.json import dumps, loads
|
|
9
|
+
from telegrinder.msgspec_utils.tools import (
|
|
10
|
+
get_class_annotations,
|
|
11
|
+
get_origin,
|
|
12
|
+
get_type_hints,
|
|
13
|
+
is_common_type,
|
|
14
|
+
struct_asdict,
|
|
15
|
+
type_check,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
__all__ = (
|
|
19
|
+
"BaseEnumMeta",
|
|
20
|
+
"Decoder",
|
|
21
|
+
"Encoder",
|
|
22
|
+
"Literal",
|
|
23
|
+
"Option",
|
|
24
|
+
"SupportsCast",
|
|
25
|
+
"convert",
|
|
26
|
+
"datetime",
|
|
27
|
+
"decoder",
|
|
28
|
+
"dumps",
|
|
29
|
+
"encoder",
|
|
30
|
+
"get_class_annotations",
|
|
31
|
+
"get_origin",
|
|
32
|
+
"get_type_hints",
|
|
33
|
+
"is_common_type",
|
|
34
|
+
"is_supports_cast",
|
|
35
|
+
"loads",
|
|
36
|
+
"struct_asdict",
|
|
37
|
+
"timedelta",
|
|
38
|
+
"to_builtins",
|
|
39
|
+
"type_check",
|
|
40
|
+
)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import abc
|
|
4
|
+
import typing
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def is_supports_cast(obj: typing.Any, /) -> typing.TypeGuard[SupportsCast]:
|
|
8
|
+
return isinstance(obj, SupportsCast)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@typing.runtime_checkable
|
|
12
|
+
class SupportsCast(typing.Protocol):
|
|
13
|
+
@classmethod
|
|
14
|
+
@abc.abstractmethod
|
|
15
|
+
def cast(cls, obj: typing.Any) -> typing.Self: ...
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
__all__ = ("SupportsCast", "is_supports_cast")
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
from telegrinder.msgspec_utils.custom_types.datetime import datetime, timedelta
|
|
2
|
+
from telegrinder.msgspec_utils.custom_types.enum_meta import BaseEnumMeta
|
|
3
|
+
from telegrinder.msgspec_utils.custom_types.literal import Literal
|
|
4
|
+
from telegrinder.msgspec_utils.custom_types.option import Option
|
|
5
|
+
|
|
6
|
+
__all__ = ("BaseEnumMeta", "Literal", "Option", "datetime", "timedelta")
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import datetime as dt
|
|
2
|
+
import typing
|
|
3
|
+
|
|
4
|
+
from telegrinder.msgspec_utils.abc import SupportsCast
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class datetime(dt.datetime, SupportsCast): # noqa: N801 # type: ignore
|
|
8
|
+
@classmethod
|
|
9
|
+
def cast(cls, obj: dt.datetime) -> typing.Self:
|
|
10
|
+
return cls.fromtimestamp(timestamp=obj.timestamp(), tz=obj.tzinfo)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class timedelta(dt.timedelta, SupportsCast): # noqa: N801 # type: ignore
|
|
14
|
+
@classmethod
|
|
15
|
+
def cast(cls, obj: dt.timedelta) -> typing.Self:
|
|
16
|
+
return cls(seconds=obj.total_seconds())
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
if typing.TYPE_CHECKING:
|
|
20
|
+
datetime: typing.TypeAlias = dt.datetime
|
|
21
|
+
timedelta: typing.TypeAlias = dt.timedelta
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
__all__ = ("datetime", "timedelta")
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
import typing
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BaseEnumMeta(enum.EnumMeta, type):
|
|
6
|
+
if typing.TYPE_CHECKING:
|
|
7
|
+
|
|
8
|
+
class BaseEnumMeta(enum.Enum): # noqa
|
|
9
|
+
NOT_SUPPORTED = enum.auto()
|
|
10
|
+
|
|
11
|
+
NOT_SUPPORTED: typing.Literal[BaseEnumMeta.NOT_SUPPORTED]
|
|
12
|
+
|
|
13
|
+
else:
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def _member_missing(cls, value):
|
|
17
|
+
from telegrinder.modules import logger
|
|
18
|
+
|
|
19
|
+
logger.warning(
|
|
20
|
+
"Unsupported value {!r} for enum of type {!r}. Probably teleginder needs to be "
|
|
21
|
+
"updated to support the latest version of Telegram Bot API.",
|
|
22
|
+
value,
|
|
23
|
+
cls,
|
|
24
|
+
)
|
|
25
|
+
return cls._member_map_["NOT_SUPPORTED"]
|
|
26
|
+
|
|
27
|
+
def __new__(
|
|
28
|
+
metacls,
|
|
29
|
+
cls,
|
|
30
|
+
bases,
|
|
31
|
+
classdict,
|
|
32
|
+
*,
|
|
33
|
+
boundary=None,
|
|
34
|
+
_simple=False,
|
|
35
|
+
**kwds,
|
|
36
|
+
):
|
|
37
|
+
classdict["NOT_SUPPORTED"] = "NOT_SUPPORTED" if any(x in bases for x in (str, enum.StrEnum)) else -1
|
|
38
|
+
classdict["_missing_"] = classmethod(BaseEnumMeta._member_missing)
|
|
39
|
+
new_type = super().__new__(metacls, cls, bases, classdict, boundary=boundary, _simple=_simple, **kwds)
|
|
40
|
+
return new_type
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
__all__ = ("BaseEnumMeta",)
|