telegrinder 0.1.dev158__py3-none-any.whl → 0.1.dev160__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (128) hide show
  1. telegrinder/__init__.py +4 -2
  2. telegrinder/api/__init__.py +0 -0
  3. telegrinder/api/abc.py +6 -4
  4. telegrinder/api/api.py +25 -11
  5. telegrinder/api/error.py +0 -0
  6. telegrinder/api/response.py +0 -0
  7. telegrinder/bot/__init__.py +0 -0
  8. telegrinder/bot/bot.py +0 -0
  9. telegrinder/bot/cute_types/__init__.py +0 -0
  10. telegrinder/bot/cute_types/base.py +100 -9
  11. telegrinder/bot/cute_types/callback_query.py +426 -37
  12. telegrinder/bot/cute_types/inline_query.py +44 -17
  13. telegrinder/bot/cute_types/message.py +2885 -117
  14. telegrinder/bot/cute_types/update.py +14 -7
  15. telegrinder/bot/cute_types/utils.py +542 -0
  16. telegrinder/bot/dispatch/__init__.py +0 -0
  17. telegrinder/bot/dispatch/abc.py +0 -0
  18. telegrinder/bot/dispatch/composition.py +0 -0
  19. telegrinder/bot/dispatch/context.py +0 -0
  20. telegrinder/bot/dispatch/dispatch.py +0 -0
  21. telegrinder/bot/dispatch/handler/__init__.py +0 -0
  22. telegrinder/bot/dispatch/handler/abc.py +0 -0
  23. telegrinder/bot/dispatch/handler/func.py +1 -1
  24. telegrinder/bot/dispatch/handler/message_reply.py +0 -0
  25. telegrinder/bot/dispatch/middleware/__init__.py +0 -0
  26. telegrinder/bot/dispatch/middleware/abc.py +0 -0
  27. telegrinder/bot/dispatch/process.py +0 -0
  28. telegrinder/bot/dispatch/return_manager/__init__.py +0 -0
  29. telegrinder/bot/dispatch/return_manager/abc.py +0 -0
  30. telegrinder/bot/dispatch/return_manager/callback_query.py +0 -0
  31. telegrinder/bot/dispatch/return_manager/inline_query.py +0 -0
  32. telegrinder/bot/dispatch/return_manager/message.py +0 -0
  33. telegrinder/bot/dispatch/view/__init__.py +0 -0
  34. telegrinder/bot/dispatch/view/abc.py +40 -29
  35. telegrinder/bot/dispatch/view/box.py +0 -0
  36. telegrinder/bot/dispatch/view/callback_query.py +0 -0
  37. telegrinder/bot/dispatch/view/inline_query.py +0 -0
  38. telegrinder/bot/dispatch/view/message.py +0 -0
  39. telegrinder/bot/dispatch/waiter_machine/__init__.py +0 -0
  40. telegrinder/bot/dispatch/waiter_machine/machine.py +0 -0
  41. telegrinder/bot/dispatch/waiter_machine/middleware.py +0 -0
  42. telegrinder/bot/dispatch/waiter_machine/short_state.py +0 -0
  43. telegrinder/bot/polling/__init__.py +0 -0
  44. telegrinder/bot/polling/abc.py +0 -0
  45. telegrinder/bot/polling/polling.py +7 -11
  46. telegrinder/bot/rules/__init__.py +0 -0
  47. telegrinder/bot/rules/abc.py +1 -1
  48. telegrinder/bot/rules/adapter/__init__.py +0 -0
  49. telegrinder/bot/rules/adapter/abc.py +0 -0
  50. telegrinder/bot/rules/adapter/errors.py +0 -0
  51. telegrinder/bot/rules/adapter/event.py +12 -6
  52. telegrinder/bot/rules/adapter/raw_update.py +0 -0
  53. telegrinder/bot/rules/callback_data.py +3 -11
  54. telegrinder/bot/rules/command.py +0 -0
  55. telegrinder/bot/rules/enum_text.py +0 -0
  56. telegrinder/bot/rules/func.py +0 -0
  57. telegrinder/bot/rules/fuzzy.py +0 -0
  58. telegrinder/bot/rules/inline.py +2 -1
  59. telegrinder/bot/rules/integer.py +0 -0
  60. telegrinder/bot/rules/is_from.py +0 -0
  61. telegrinder/bot/rules/markup.py +3 -1
  62. telegrinder/bot/rules/mention.py +0 -0
  63. telegrinder/bot/rules/message_entities.py +3 -1
  64. telegrinder/bot/rules/regex.py +1 -1
  65. telegrinder/bot/rules/rule_enum.py +0 -0
  66. telegrinder/bot/rules/start.py +0 -0
  67. telegrinder/bot/rules/text.py +0 -0
  68. telegrinder/bot/scenario/__init__.py +0 -0
  69. telegrinder/bot/scenario/abc.py +0 -0
  70. telegrinder/bot/scenario/checkbox.py +0 -0
  71. telegrinder/bot/scenario/choice.py +0 -0
  72. telegrinder/client/__init__.py +2 -2
  73. telegrinder/client/abc.py +35 -12
  74. telegrinder/client/aiohttp.py +35 -22
  75. telegrinder/model.py +70 -23
  76. telegrinder/modules.py +22 -12
  77. telegrinder/msgspec_json.py +0 -0
  78. telegrinder/msgspec_utils.py +30 -10
  79. telegrinder/node/__init__.py +0 -0
  80. telegrinder/node/attachment.py +0 -0
  81. telegrinder/node/base.py +0 -0
  82. telegrinder/node/composer.py +0 -0
  83. telegrinder/node/container.py +0 -0
  84. telegrinder/node/message.py +0 -0
  85. telegrinder/node/rule.py +0 -0
  86. telegrinder/node/source.py +0 -0
  87. telegrinder/node/text.py +0 -0
  88. telegrinder/node/tools/__init__.py +0 -0
  89. telegrinder/node/tools/generator.py +0 -0
  90. telegrinder/node/update.py +0 -0
  91. telegrinder/rules.py +0 -0
  92. telegrinder/tools/__init__.py +2 -30
  93. telegrinder/tools/buttons.py +19 -5
  94. telegrinder/tools/error_handler/__init__.py +2 -0
  95. telegrinder/tools/error_handler/abc.py +5 -1
  96. telegrinder/tools/error_handler/error.py +10 -0
  97. telegrinder/tools/error_handler/error_handler.py +100 -81
  98. telegrinder/tools/formatting/__init__.py +0 -0
  99. telegrinder/tools/formatting/html.py +0 -0
  100. telegrinder/tools/formatting/links.py +0 -0
  101. telegrinder/tools/formatting/spec_html_formats.py +0 -0
  102. telegrinder/tools/global_context/__init__.py +0 -0
  103. telegrinder/tools/global_context/abc.py +0 -0
  104. telegrinder/tools/global_context/global_context.py +65 -67
  105. telegrinder/tools/global_context/telegrinder_ctx.py +0 -0
  106. telegrinder/tools/i18n/__init__.py +0 -0
  107. telegrinder/tools/i18n/base.py +0 -0
  108. telegrinder/tools/i18n/middleware/__init__.py +0 -0
  109. telegrinder/tools/i18n/middleware/base.py +0 -0
  110. telegrinder/tools/i18n/simple.py +0 -0
  111. telegrinder/tools/kb_set/__init__.py +0 -0
  112. telegrinder/tools/kb_set/base.py +0 -0
  113. telegrinder/tools/kb_set/yaml.py +3 -3
  114. telegrinder/tools/keyboard.py +17 -26
  115. telegrinder/tools/loop_wrapper/__init__.py +0 -0
  116. telegrinder/tools/loop_wrapper/abc.py +0 -0
  117. telegrinder/tools/loop_wrapper/loop_wrapper.py +0 -0
  118. telegrinder/tools/magic.py +1 -1
  119. telegrinder/tools/parse_mode.py +0 -0
  120. telegrinder/types/__init__.py +0 -0
  121. telegrinder/types/enums.py +13 -9
  122. telegrinder/types/methods.py +783 -673
  123. telegrinder/types/objects.py +317 -163
  124. {telegrinder-0.1.dev158.dist-info → telegrinder-0.1.dev160.dist-info}/LICENSE +0 -0
  125. {telegrinder-0.1.dev158.dist-info → telegrinder-0.1.dev160.dist-info}/METADATA +9 -7
  126. {telegrinder-0.1.dev158.dist-info → telegrinder-0.1.dev160.dist-info}/RECORD +42 -41
  127. {telegrinder-0.1.dev158.dist-info → telegrinder-0.1.dev160.dist-info}/WHEEL +1 -1
  128. telegrinder/tools/inline_query.py +0 -684
telegrinder/model.py CHANGED
@@ -1,10 +1,14 @@
1
+ import dataclasses
2
+ import enum
3
+ import secrets
1
4
  import typing
5
+ from datetime import datetime
2
6
  from types import NoneType
3
7
 
4
8
  import msgspec
5
9
  from fntypes.co import Nothing, Result, Some
6
10
 
7
- from .msgspec_utils import decoder, encoder
11
+ from .msgspec_utils import decoder, encoder, get_origin
8
12
 
9
13
  T = typing.TypeVar("T")
10
14
 
@@ -41,31 +45,12 @@ def full_result(
41
45
  return result.map(lambda v: decoder.decode(v, type=full_t)) # type: ignore
42
46
 
43
47
 
44
- def convert(d: typing.Any, serialize: bool = True) -> typing.Any:
45
- if isinstance(d, Model):
46
- converted_dct = convert(d.to_dict(), serialize=False)
47
- return encoder.encode(converted_dct) if serialize is True else converted_dct
48
-
49
- if isinstance(d, dict):
50
- return {
51
- k: convert(v, serialize=serialize)
52
- for k, v in d.items()
53
- if type(v) not in (NoneType, Nothing)
54
- }
55
-
56
- if isinstance(d, list):
57
- converted_lst = [convert(x, serialize=False) for x in d]
58
- return encoder.encode(converted_lst) if serialize is True else converted_lst
59
-
60
- return d
61
-
62
-
63
48
  def get_params(params: dict[str, typing.Any]) -> dict[str, typing.Any]:
64
49
  return {
65
- k: v.unwrap() if v and isinstance(v, Some) else v
50
+ k: v.unwrap() if isinstance(v, Some) else v
66
51
  for k, v in (
67
- *params.items(),
68
52
  *params.pop("other", {}).items(),
53
+ *params.items(),
69
54
  )
70
55
  if k != "self" and type(v) not in (NoneType, Nothing)
71
56
  }
@@ -87,9 +72,71 @@ class Model(msgspec.Struct, **MODEL_CONFIG):
87
72
  }
88
73
 
89
74
 
75
+ @dataclasses.dataclass(kw_only=True)
76
+ class DataConverter:
77
+ files: dict[str, tuple[str, bytes]] = dataclasses.field(default_factory=lambda: {})
78
+
79
+ @property
80
+ def converters(self) -> dict[type[typing.Any], typing.Callable[..., typing.Any]]:
81
+ return {
82
+ get_origin(value.__annotations__["data"]): value
83
+ for key, value in vars(self.__class__).items()
84
+ if key.startswith("convert_") and callable(value)
85
+ }
86
+
87
+ @staticmethod
88
+ def convert_enum(data: enum.Enum, _: bool = True) -> typing.Any:
89
+ return data.value
90
+
91
+ @staticmethod
92
+ def convert_datetime(data: datetime, _: bool = True) -> int:
93
+ return int(data.timestamp())
94
+
95
+ def __call__(self, data: typing.Any, *, serialize: bool = True) -> typing.Any:
96
+ converter = self.get_converter(get_origin(type(data)))
97
+ if converter is not None:
98
+ if isinstance(converter, staticmethod):
99
+ return converter(data, serialize)
100
+ return converter(self, data, serialize)
101
+ return data
102
+
103
+ def get_converter(self, t: type[typing.Any]):
104
+ for type, converter in self.converters.items():
105
+ if issubclass(t, type):
106
+ return converter
107
+ return None
108
+
109
+ def convert_model(self, data: Model, serialize: bool = True) -> str | dict[str, typing.Any]:
110
+ converted_dct = self(data.to_dict(), serialize=False)
111
+ return encoder.encode(converted_dct) if serialize is True else converted_dct
112
+
113
+ def convert_dct(self, data: dict[str, typing.Any], serialize: bool = True) -> dict[str, typing.Any]:
114
+ return {
115
+ k: self(v, serialize=serialize)
116
+ for k, v in data.items()
117
+ if type(v) not in (NoneType, Nothing)
118
+ }
119
+
120
+ def convert_lst(self, data: list[typing.Any], serialize: bool = True) -> str | list[typing.Any]:
121
+ converted_lst = [self(x, serialize=False) for x in data]
122
+ return encoder.encode(converted_lst) if serialize is True else converted_lst
123
+
124
+ def convert_tpl(self, data: tuple[typing.Any, ...], _: bool = True) -> str | tuple[typing.Any, ...]:
125
+ if (
126
+ isinstance(data, tuple)
127
+ and len(data) == 2
128
+ and isinstance(data[0], str)
129
+ and isinstance(data[1], bytes)
130
+ ):
131
+ attach_name = secrets.token_urlsafe(16)
132
+ self.files[attach_name] = data
133
+ return "attach://{}".format(attach_name)
134
+ return data
135
+
136
+
90
137
  __all__ = (
138
+ "DataConverter",
91
139
  "Model",
92
- "convert",
93
140
  "full_result",
94
141
  "get_params",
95
142
  "MODEL_CONFIG",
telegrinder/modules.py CHANGED
@@ -5,30 +5,30 @@ from choicelib import choice_in_order
5
5
 
6
6
 
7
7
  class JSONModule(typing.Protocol):
8
- def loads(self, s: str) -> dict | list:
8
+ def loads(self, s: str | bytes) -> dict[str, typing.Any] | list[typing.Any]:
9
9
  ...
10
10
 
11
- def dumps(self, o: dict | list) -> str:
11
+ def dumps(self, o: dict[str, typing.Any] | list[typing.Any]) -> str:
12
12
  ...
13
13
 
14
14
 
15
15
  class LoggerModule(typing.Protocol):
16
- def debug(self, __msg: object, *args: object, **kwargs: object):
16
+ def debug(self, __msg: object, *args: object, **kwargs: object) -> None:
17
17
  ...
18
18
 
19
- def info(self, __msg: object, *args: object, **kwargs: object):
19
+ def info(self, __msg: object, *args: object, **kwargs: object) -> None:
20
20
  ...
21
21
 
22
- def warning(self, __msg: object, *args: object, **kwargs: object):
22
+ def warning(self, __msg: object, *args: object, **kwargs: object) -> None:
23
23
  ...
24
24
 
25
- def error(self, __msg: object, *args: object, **kwargs: object):
25
+ def error(self, __msg: object, *args: object, **kwargs: object) -> None:
26
26
  ...
27
27
 
28
- def critical(self, __msg: object, *args: object, **kwargs: object):
28
+ def critical(self, __msg: object, *args: object, **kwargs: object) -> None:
29
29
  ...
30
30
 
31
- def exception(self, __msg: object, *args: object, **kwargs: object):
31
+ def exception(self, __msg: object, *args: object, **kwargs: object) -> None:
32
32
  ...
33
33
 
34
34
  def set_level(
@@ -187,7 +187,7 @@ elif logging_module == "logging":
187
187
 
188
188
 
189
189
  class LogMessage:
190
- def __init__(self, fmt, args, kwargs):
190
+ def __init__(self, fmt: typing.Any, args: typing.Any, kwargs: typing.Any) -> None:
191
191
  self.fmt = fmt
192
192
  self.args = args
193
193
  self.kwargs = kwargs
@@ -195,17 +195,27 @@ elif logging_module == "logging":
195
195
  def __str__(self) -> str:
196
196
  return self.fmt.format(*self.args, **self.kwargs)
197
197
 
198
+
198
199
  class TelegrinderLoggingStyleAdapter(logging.LoggerAdapter):
199
- def __init__(self, logger, extra=None):
200
+ def __init__(
201
+ self,
202
+ logger: LoggerModule,
203
+ extra: dict[str, typing.Any] | None = None,
204
+ ) -> None:
200
205
  super().__init__(logger, extra or {})
201
206
 
202
- def log(self, level, msg, *args, **kwargs):
207
+ def log(self, level: int, msg: object, *args: object, **kwargs: object) -> None:
203
208
  if self.isEnabledFor(level):
204
209
  kwargs.setdefault("stacklevel", 2)
205
210
  msg, args, kwargs = self.proc(msg, args, kwargs)
206
211
  self.logger._log(level, msg, args, **kwargs)
207
212
 
208
- def proc(self, msg, args, kwargs):
213
+ def proc(
214
+ self,
215
+ msg: object,
216
+ args: tuple[object, ...],
217
+ kwargs: dict[str, object],
218
+ ) -> tuple[LogMessage | object, tuple[object, ...], dict[str, object]]:
209
219
  log_kwargs = {
210
220
  key: kwargs[key]
211
221
  for key in inspect.getfullargspec(self.logger._log).args[1:]
File without changes
@@ -1,4 +1,3 @@
1
- import types # noqa: TCH003
2
1
  import typing
3
2
 
4
3
  import fntypes.option
@@ -9,11 +8,17 @@ T = typing.TypeVar("T")
9
8
  Ts = typing.TypeVarTuple("Ts")
10
9
 
11
10
  if typing.TYPE_CHECKING:
11
+ import types
12
+ from datetime import datetime
13
+
12
14
  from fntypes.option import Option
13
15
  else:
16
+ from datetime import datetime as dt
14
17
 
15
18
  Value = typing.TypeVar("Value")
16
19
 
20
+ datetime = type("datetime", (dt,), {})
21
+
17
22
  class OptionMeta(type):
18
23
  def __instancecheck__(cls, __instance: typing.Any) -> bool:
19
24
  return isinstance(__instance, fntypes.option.Some | fntypes.option.Nothing)
@@ -22,8 +27,8 @@ else:
22
27
  class Option(typing.Generic[Value], metaclass=OptionMeta):
23
28
  pass
24
29
 
25
- DecHook: typing.TypeAlias = typing.Callable[[type[T], object], object]
26
- EncHook: typing.TypeAlias = typing.Callable[[T], object]
30
+ DecHook: typing.TypeAlias = typing.Callable[[type[T], typing.Any], object]
31
+ EncHook: typing.TypeAlias = typing.Callable[[T], typing.Any]
27
32
 
28
33
  Nothing: typing.Final[fntypes.option.Nothing] = fntypes.option.Nothing()
29
34
 
@@ -43,7 +48,11 @@ def msgspec_convert(obj: typing.Any, t: type[T]) -> Result[T, msgspec.Validation
43
48
  return Error(exc)
44
49
 
45
50
 
46
- def option_dec_hook(tp: type["Option[typing.Any]"], obj: typing.Any) -> typing.Any:
51
+ def datetime_dec_hook(tp: type[datetime], obj: int | float) -> datetime:
52
+ return tp.fromtimestamp(obj)
53
+
54
+
55
+ def option_dec_hook(tp: type[Option[typing.Any]], obj: typing.Any) -> Option[typing.Any]:
47
56
  if obj is None:
48
57
  return Nothing
49
58
  generic_args = typing.get_args(tp)
@@ -85,19 +94,26 @@ def variative_dec_hook(tp: type[Variative], obj: typing.Any) -> Variative:
85
94
  )
86
95
 
87
96
 
88
- def option_enc_hook(obj: "Option[typing.Any]") -> typing.Any | None:
97
+ def datetime_enc_hook(obj: datetime) -> int:
98
+ return int(obj.timestamp())
99
+
100
+
101
+ def option_enc_hook(obj: Option[typing.Any]) -> typing.Any | None:
89
102
  return obj.value if isinstance(obj, fntypes.option.Some) else None
90
103
 
91
104
 
92
- def variative_enc_hook(obj: Variative) -> typing.Any:
93
- return typing.cast(typing.Any, obj.v)
105
+ def variative_enc_hook(obj: Variative[typing.Any]) -> typing.Any:
106
+ return obj.v
94
107
 
95
108
 
96
109
  class Decoder:
97
110
  def __init__(self) -> None:
98
- self.dec_hooks: dict[type | types.UnionType, DecHook[typing.Any]] = {
111
+ self.dec_hooks: dict[
112
+ typing.Union[type[typing.Any], "types.UnionType"], DecHook[typing.Any]
113
+ ] = {
99
114
  Option: option_dec_hook,
100
115
  Variative: variative_dec_hook,
116
+ datetime: datetime_dec_hook,
101
117
  }
102
118
 
103
119
  def add_dec_hook(self, tp: type[T]):
@@ -156,6 +172,7 @@ class Encoder:
156
172
  fntypes.option.Some: option_enc_hook,
157
173
  fntypes.option.Nothing: option_enc_hook,
158
174
  Variative: variative_enc_hook,
175
+ datetime: datetime_enc_hook,
159
176
  }
160
177
 
161
178
  def add_dec_hook(self, tp: type[T]):
@@ -174,11 +191,11 @@ class Encoder:
174
191
  return self.enc_hooks[origin_type](obj)
175
192
 
176
193
  @typing.overload
177
- def encode(self, obj: typing.Any) -> str:
194
+ def encode(self, obj: typing.Any, *, as_str: typing.Literal[True] = True) -> str:
178
195
  ...
179
196
 
180
197
  @typing.overload
181
- def encode(self, obj: typing.Any, *, as_str: bool = False) -> bytes:
198
+ def encode(self, obj: typing.Any, *, as_str: typing.Literal[False] = False) -> bytes:
182
199
  ...
183
200
 
184
201
  def encode(self, obj: typing.Any, *, as_str: bool = True) -> str | bytes:
@@ -198,10 +215,13 @@ __all__ = (
198
215
  "get_origin",
199
216
  "repr_type",
200
217
  "msgspec_convert",
218
+ "datetime_dec_hook",
219
+ "datetime_enc_hook",
201
220
  "option_dec_hook",
202
221
  "option_enc_hook",
203
222
  "variative_dec_hook",
204
223
  "variative_enc_hook",
224
+ "datetime",
205
225
  "decoder",
206
226
  "encoder",
207
227
  )
File without changes
File without changes
telegrinder/node/base.py CHANGED
File without changes
File without changes
File without changes
File without changes
telegrinder/node/rule.py CHANGED
File without changes
File without changes
telegrinder/node/text.py CHANGED
File without changes
File without changes
File without changes
File without changes
telegrinder/rules.py CHANGED
File without changes
@@ -1,5 +1,5 @@
1
1
  from .buttons import BaseButton
2
- from .error_handler import ABCErrorHandler, Catcher, ErrorHandler
2
+ from .error_handler import ABCErrorHandler, Catcher, CatcherError, ErrorHandler
3
3
  from .formatting import (
4
4
  BaseSpecFormat,
5
5
  ChannelBoostLink,
@@ -54,33 +54,6 @@ from .i18n import (
54
54
  SimpleI18n,
55
55
  SimpleTranslator,
56
56
  )
57
- from .inline_query import (
58
- inline_query_article,
59
- inline_query_audio,
60
- inline_query_cached_audio,
61
- inline_query_cached_document,
62
- inline_query_cached_gif,
63
- inline_query_cached_mpeg4_gif,
64
- inline_query_cached_photo,
65
- inline_query_cached_sticker,
66
- inline_query_cached_video,
67
- inline_query_cached_voice,
68
- inline_query_contact,
69
- inline_query_document,
70
- inline_query_game,
71
- inline_query_gif,
72
- inline_query_location,
73
- inline_query_mpeg4_gif,
74
- inline_query_photo,
75
- inline_query_venue,
76
- inline_query_video,
77
- inline_query_voice,
78
- input_contact_message_content,
79
- input_invoice_message_content,
80
- input_location_message_content,
81
- input_text_message_content,
82
- input_venue_message_content,
83
- )
84
57
  from .kb_set import KeyboardSetBase, KeyboardSetYAML
85
58
  from .keyboard import (
86
59
  AnyMarkup,
@@ -89,7 +62,6 @@ from .keyboard import (
89
62
  InlineKeyboard,
90
63
  Keyboard,
91
64
  RowButtons,
92
- keyboard_remove,
93
65
  )
94
66
  from .loop_wrapper import ABCLoopWrapper, DelayedTask, LoopWrapper
95
67
  from .magic import magic_bundle, resolve_arg_names
@@ -107,6 +79,7 @@ __all__ = (
107
79
  "BaseSpecFormat",
108
80
  "Button",
109
81
  "Catcher",
82
+ "CatcherError",
110
83
  "ChannelBoostLink",
111
84
  "CtxVar",
112
85
  "DelayedTask",
@@ -150,7 +123,6 @@ __all__ = (
150
123
  "get_start_group_link",
151
124
  "invite_chat_link",
152
125
  "italic",
153
- "keyboard_remove",
154
126
  "link",
155
127
  "magic_bundle",
156
128
  "mention",
@@ -4,6 +4,15 @@ import typing
4
4
  import msgspec
5
5
 
6
6
  from telegrinder.model import encoder
7
+ from telegrinder.types import (
8
+ CallbackGame,
9
+ KeyboardButtonPollType,
10
+ KeyboardButtonRequestChat,
11
+ KeyboardButtonRequestUsers,
12
+ SwitchInlineQueryChosenChat,
13
+ WebAppInfo,
14
+ )
15
+ from telegrinder.types.objects import LoginUrl
7
16
 
8
17
  ButtonT = typing.TypeVar("ButtonT", bound="BaseButton")
9
18
 
@@ -43,8 +52,10 @@ class Button(BaseButton):
43
52
  _: dataclasses.KW_ONLY
44
53
  request_contact: bool = False
45
54
  request_location: bool = False
46
- request_poll: dict | None = None
47
- web_app: dict | None = None
55
+ request_chat: dict[str, typing.Any] | KeyboardButtonRequestChat | None = None
56
+ request_user: dict[str, typing.Any] | KeyboardButtonRequestUsers | None = None
57
+ request_poll: dict[str, typing.Any] | KeyboardButtonPollType | None = None
58
+ web_app: dict[str, typing.Any] | WebAppInfo | None = None
48
59
 
49
60
 
50
61
  @dataclasses.dataclass
@@ -52,7 +63,7 @@ class InlineButton(BaseButton):
52
63
  text: str
53
64
  _: dataclasses.KW_ONLY
54
65
  url: str | None = None
55
- login_url: dict | None = None
66
+ login_url: dict[str, typing.Any] | LoginUrl | None = None
56
67
  pay: bool | None = None
57
68
  callback_data: typing.Union[
58
69
  str,
@@ -60,10 +71,13 @@ class InlineButton(BaseButton):
60
71
  DataclassInstance,
61
72
  msgspec.Struct,
62
73
  ] | None = None
63
- callback_game: dict | None = None
74
+ callback_game: dict[str, typing.Any] | CallbackGame | None = None
64
75
  switch_inline_query: str | None = None
65
76
  switch_inline_query_current_chat: str | None = None
66
- web_app: dict | None = None
77
+ switch_inline_query_chosen_chat: dict[
78
+ str, typing.Any
79
+ ] | SwitchInlineQueryChosenChat | None = None
80
+ web_app: dict[str, typing.Any] | WebAppInfo | None = None
67
81
 
68
82
 
69
83
  __all__ = (
@@ -1,8 +1,10 @@
1
1
  from .abc import ABCErrorHandler
2
+ from .error import CatcherError
2
3
  from .error_handler import Catcher, ErrorHandler
3
4
 
4
5
  __all__ = (
5
6
  "ABCErrorHandler",
6
7
  "Catcher",
8
+ "CatcherError",
7
9
  "ErrorHandler",
8
10
  )
@@ -13,7 +13,11 @@ Handler = typing.Callable[typing.Concatenate[EventT, ...], typing.Awaitable[typi
13
13
 
14
14
  class ABCErrorHandler(ABC, typing.Generic[EventT]):
15
15
  @abstractmethod
16
- def catch(self) -> typing.Callable[[typing.Callable], typing.Callable]:
16
+ def register_catcher(
17
+ self,
18
+ *args: typing.Any,
19
+ **kwargs: typing.Any,
20
+ ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Callable[..., typing.Any]]:
17
21
  ...
18
22
 
19
23
  @abstractmethod
@@ -0,0 +1,10 @@
1
+ import typing
2
+
3
+
4
+ class CatcherError(TypeError):
5
+ def __init__(self, exc: typing.Any, error: str) -> None:
6
+ self.exc = exc
7
+ self.error = error
8
+
9
+
10
+ __all__ = ("CatcherError",)