telegrinder 0.3.0.post1__tar.gz → 0.3.1__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.

Files changed (166) hide show
  1. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/PKG-INFO +1 -1
  2. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/pyproject.toml +1 -1
  3. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/cute_types/callback_query.py +2 -14
  4. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/cute_types/chat_join_request.py +1 -1
  5. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/cute_types/chat_member_updated.py +1 -1
  6. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/cute_types/inline_query.py +1 -6
  7. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/cute_types/message.py +1 -21
  8. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/cute_types/update.py +1 -1
  9. telegrinder-0.3.1/telegrinder/bot/dispatch/abc.py +77 -0
  10. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/dispatch.py +8 -8
  11. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/handler/func.py +8 -10
  12. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/process.py +1 -1
  13. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/view/base.py +31 -20
  14. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/view/raw.py +20 -16
  15. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/waiter_machine/actions.py +3 -0
  16. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +15 -18
  17. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +21 -13
  18. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/waiter_machine/hasher/message.py +15 -16
  19. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/waiter_machine/hasher/state.py +6 -6
  20. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/waiter_machine/machine.py +24 -30
  21. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/waiter_machine/short_state.py +10 -4
  22. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/abc.py +42 -7
  23. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/adapter/raw_update.py +1 -3
  24. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/callback_data.py +7 -7
  25. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/chat_join.py +5 -5
  26. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/command.py +1 -1
  27. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/enum_text.py +4 -1
  28. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/fuzzy.py +1 -1
  29. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/inline.py +6 -7
  30. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/integer.py +1 -1
  31. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/is_from.py +20 -20
  32. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/markup.py +6 -3
  33. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/mention.py +1 -1
  34. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/message.py +2 -2
  35. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/message_entities.py +2 -2
  36. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/node.py +1 -1
  37. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/regex.py +1 -1
  38. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/start.py +2 -2
  39. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/text.py +6 -4
  40. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/update.py +1 -1
  41. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/scenario/checkbox.py +9 -1
  42. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/msgspec_utils.py +11 -3
  43. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/attachment.py +6 -6
  44. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/base.py +17 -11
  45. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/callback_query.py +1 -1
  46. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/command.py +1 -1
  47. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/composer.py +5 -2
  48. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/container.py +1 -1
  49. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/event.py +1 -1
  50. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/message.py +1 -1
  51. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/polymorphic.py +6 -3
  52. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/rule.py +1 -1
  53. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/source.py +5 -7
  54. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/text.py +2 -2
  55. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/tools/generator.py +1 -2
  56. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/update.py +3 -3
  57. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/rules.py +2 -0
  58. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/buttons.py +4 -4
  59. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/error_handler/abc.py +7 -7
  60. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/error_handler/error_handler.py +58 -47
  61. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/formatting/html.py +0 -2
  62. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/functional.py +3 -0
  63. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/global_context/telegrinder_ctx.py +2 -0
  64. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/i18n/__init__.py +1 -1
  65. telegrinder-0.3.0.post1/telegrinder/tools/i18n/base.py → telegrinder-0.3.1/telegrinder/tools/i18n/abc.py +0 -0
  66. telegrinder-0.3.1/telegrinder/tools/i18n/middleware/__init__.py +3 -0
  67. telegrinder-0.3.0.post1/telegrinder/tools/i18n/middleware/base.py → telegrinder-0.3.1/telegrinder/tools/i18n/middleware/abc.py +3 -2
  68. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/i18n/simple.py +11 -12
  69. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/keyboard.py +9 -9
  70. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/magic.py +8 -4
  71. telegrinder-0.3.0.post1/telegrinder/bot/dispatch/abc.py +0 -35
  72. telegrinder-0.3.0.post1/telegrinder/tools/i18n/middleware/__init__.py +0 -3
  73. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/LICENSE +0 -0
  74. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/readme.md +0 -0
  75. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/__init__.py +1 -1
  76. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/api/__init__.py +0 -0
  77. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/api/api.py +0 -0
  78. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/api/error.py +0 -0
  79. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/api/response.py +0 -0
  80. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/api/token.py +0 -0
  81. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/__init__.py +0 -0
  82. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/bot.py +0 -0
  83. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/cute_types/__init__.py +0 -0
  84. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/cute_types/base.py +0 -0
  85. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/cute_types/utils.py +0 -0
  86. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/__init__.py +0 -0
  87. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/context.py +0 -0
  88. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/handler/__init__.py +0 -0
  89. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/handler/abc.py +0 -0
  90. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/handler/audio_reply.py +0 -0
  91. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/handler/base.py +0 -0
  92. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/handler/document_reply.py +0 -0
  93. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/handler/media_group_reply.py +0 -0
  94. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/handler/message_reply.py +0 -0
  95. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/handler/photo_reply.py +0 -0
  96. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/handler/sticker_reply.py +0 -0
  97. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/handler/video_reply.py +0 -0
  98. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/middleware/__init__.py +0 -0
  99. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/middleware/abc.py +0 -0
  100. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/return_manager/__init__.py +0 -0
  101. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/return_manager/abc.py +0 -0
  102. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/return_manager/callback_query.py +0 -0
  103. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/return_manager/inline_query.py +0 -0
  104. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/return_manager/message.py +0 -0
  105. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/view/__init__.py +0 -0
  106. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/view/abc.py +0 -0
  107. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/view/box.py +0 -0
  108. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/view/callback_query.py +0 -0
  109. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/view/chat_join_request.py +0 -0
  110. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/view/chat_member.py +0 -0
  111. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/view/inline_query.py +0 -0
  112. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/view/message.py +0 -0
  113. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/waiter_machine/__init__.py +0 -0
  114. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +0 -0
  115. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/dispatch/waiter_machine/middleware.py +0 -0
  116. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/polling/__init__.py +0 -0
  117. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/polling/abc.py +0 -0
  118. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/polling/polling.py +0 -0
  119. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/__init__.py +0 -0
  120. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/adapter/__init__.py +0 -0
  121. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/adapter/abc.py +0 -0
  122. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/adapter/errors.py +0 -0
  123. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/adapter/event.py +0 -0
  124. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/adapter/node.py +0 -0
  125. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/func.py +0 -0
  126. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/rule_enum.py +0 -0
  127. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/rules/state.py +0 -0
  128. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/scenario/__init__.py +0 -0
  129. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/scenario/abc.py +0 -0
  130. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/bot/scenario/choice.py +0 -0
  131. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/client/__init__.py +0 -0
  132. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/client/abc.py +0 -0
  133. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/client/aiohttp.py +0 -0
  134. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/model.py +0 -0
  135. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/modules.py +0 -0
  136. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/msgspec_json.py +0 -0
  137. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/__init__.py +0 -0
  138. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/me.py +0 -0
  139. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/scope.py +0 -0
  140. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/node/tools/__init__.py +0 -0
  141. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/py.typed +0 -0
  142. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/__init__.py +0 -0
  143. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/error_handler/__init__.py +0 -0
  144. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/error_handler/error.py +0 -0
  145. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/formatting/__init__.py +0 -0
  146. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/formatting/links.py +0 -0
  147. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/formatting/spec_html_formats.py +0 -0
  148. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/global_context/__init__.py +0 -0
  149. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/global_context/abc.py +0 -0
  150. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/global_context/global_context.py +0 -0
  151. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/kb_set/__init__.py +0 -0
  152. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/kb_set/base.py +0 -0
  153. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/kb_set/yaml.py +0 -0
  154. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/limited_dict.py +0 -0
  155. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/loop_wrapper/__init__.py +0 -0
  156. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/loop_wrapper/abc.py +0 -0
  157. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/loop_wrapper/loop_wrapper.py +0 -0
  158. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/parse_mode.py +0 -0
  159. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/state_storage/__init__.py +0 -0
  160. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/state_storage/abc.py +0 -0
  161. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/tools/state_storage/memory.py +0 -0
  162. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/types/__init__.py +0 -0
  163. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/types/enums.py +0 -0
  164. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/types/methods.py +0 -0
  165. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/types/objects.py +0 -0
  166. {telegrinder-0.3.0.post1 → telegrinder-0.3.1}/telegrinder/verification_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: telegrinder
3
- Version: 0.3.0.post1
3
+ Version: 0.3.1
4
4
  Summary: Modern visionary telegram bot framework.
5
5
  Home-page: https://github.com/timoniq/telegrinder
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "telegrinder"
3
- version = "0.3.0.post1"
3
+ version = "0.3.1"
4
4
  description = "Modern visionary telegram bot framework."
5
5
  authors = ["timoniq <tesseradecades@mail.ru>"]
6
6
  maintainers = ["luwqz1 <howluwqz1@gmail.com>"]
@@ -9,19 +9,7 @@ from telegrinder.bot.cute_types.base import BaseCute, compose_method_params, sho
9
9
  from telegrinder.bot.cute_types.message import MediaType, MessageCute, ReplyMarkup, execute_method_edit
10
10
  from telegrinder.model import get_params
11
11
  from telegrinder.msgspec_utils import Option, decoder
12
- from telegrinder.types.objects import (
13
- CallbackQuery,
14
- Chat,
15
- InaccessibleMessage,
16
- InlineKeyboardMarkup,
17
- InputFile,
18
- InputMedia,
19
- LinkPreviewOptions,
20
- MessageEntity,
21
- MessageId,
22
- ReplyParameters,
23
- User,
24
- )
12
+ from telegrinder.types.objects import *
25
13
 
26
14
 
27
15
  class CallbackQueryCute(BaseCute[CallbackQuery], CallbackQuery, kw_only=True):
@@ -81,7 +69,7 @@ class CallbackQueryCute(BaseCute[CallbackQuery], CallbackQuery, kw_only=True):
81
69
  if "cached_callback_data" in self.__dict__:
82
70
  return self.__dict__["cached_callback_data"]
83
71
  data = Nothing()
84
- with suppress(msgspec.ValidationError):
72
+ with suppress(msgspec.ValidationError, msgspec.DecodeError):
85
73
  data = Some(decoder.decode(self.data.unwrap()))
86
74
  self.__dict__["cached_callback_data"] = data
87
75
  return data
@@ -5,7 +5,7 @@ from fntypes.result import Result
5
5
  from telegrinder.api import API, APIError
6
6
  from telegrinder.bot.cute_types.base import BaseCute, shortcut
7
7
  from telegrinder.bot.cute_types.chat_member_updated import ChatMemberShortcuts, chat_member_interaction
8
- from telegrinder.types.objects import ChatJoinRequest, User
8
+ from telegrinder.types.objects import *
9
9
 
10
10
 
11
11
  class ChatJoinRequestCute(BaseCute[ChatJoinRequest], ChatJoinRequest, ChatMemberShortcuts, kw_only=True):
@@ -6,7 +6,7 @@ from fntypes.result import Result
6
6
  from telegrinder.api import API, APIError
7
7
  from telegrinder.bot.cute_types.base import BaseCute, compose_method_params, shortcut
8
8
  from telegrinder.model import get_params
9
- from telegrinder.types.objects import ChatMemberUpdated, ChatPermissions, User
9
+ from telegrinder.types.objects import *
10
10
 
11
11
 
12
12
  async def chat_member_interaction(
@@ -5,12 +5,7 @@ from fntypes.result import Result
5
5
  from telegrinder.api import API, APIError
6
6
  from telegrinder.bot.cute_types.base import BaseCute, compose_method_params, shortcut
7
7
  from telegrinder.model import get_params
8
- from telegrinder.types import (
9
- InlineQuery,
10
- InlineQueryResult,
11
- InlineQueryResultsButton,
12
- User,
13
- )
8
+ from telegrinder.types.objects import *
14
9
 
15
10
 
16
11
  class InlineQueryCute(BaseCute[InlineQuery], InlineQuery, kw_only=True):
@@ -15,27 +15,7 @@ from telegrinder.bot.cute_types.utils import (
15
15
  )
16
16
  from telegrinder.model import get_params
17
17
  from telegrinder.msgspec_utils import Nothing, Option
18
- from telegrinder.types.objects import (
19
- ChatAction,
20
- DiceEmoji,
21
- ForceReply,
22
- InaccessibleMessage,
23
- InlineKeyboardMarkup,
24
- InputFile,
25
- InputMedia,
26
- InputPollOption,
27
- LabeledPrice,
28
- LinkPreviewOptions,
29
- Message,
30
- MessageEntity,
31
- MessageId,
32
- ReactionEmoji,
33
- ReactionType,
34
- ReplyKeyboardMarkup,
35
- ReplyKeyboardRemove,
36
- ReplyParameters,
37
- User,
38
- )
18
+ from telegrinder.types import *
39
19
 
40
20
  if typing.TYPE_CHECKING:
41
21
  from datetime import datetime
@@ -11,7 +11,7 @@ from telegrinder.bot.cute_types.chat_member_updated import ChatMemberUpdatedCute
11
11
  from telegrinder.bot.cute_types.inline_query import InlineQueryCute
12
12
  from telegrinder.bot.cute_types.message import MessageCute
13
13
  from telegrinder.msgspec_utils import Option
14
- from telegrinder.types.objects import Model, Update
14
+ from telegrinder.types.objects import *
15
15
 
16
16
  EventModel = typing.TypeVar("EventModel", bound=Model)
17
17
 
@@ -0,0 +1,77 @@
1
+ import importlib.util as importlib_util
2
+ import os
3
+ import pathlib
4
+ import sys
5
+ import typing
6
+ from abc import ABC, abstractmethod
7
+
8
+ from fntypes.option import Option
9
+
10
+ from telegrinder.api.api import API
11
+ from telegrinder.tools.global_context.abc import ABCGlobalContext
12
+ from telegrinder.types.objects import Update
13
+
14
+ T = typing.TypeVar("T")
15
+
16
+
17
+ class PathExistsError(BaseException):
18
+ pass
19
+
20
+
21
+ class ABCDispatch(ABC):
22
+ @property
23
+ @abstractmethod
24
+ def global_context(self) -> ABCGlobalContext:
25
+ pass
26
+
27
+ @abstractmethod
28
+ async def feed(self, event: Update, api: API) -> bool:
29
+ pass
30
+
31
+ @abstractmethod
32
+ def load(self, external: typing.Self) -> None:
33
+ pass
34
+
35
+ @abstractmethod
36
+ def get_view(self, of_type: type[T]) -> Option[T]:
37
+ pass
38
+
39
+ def load_many(self, *externals: typing.Self) -> None:
40
+ for external in externals:
41
+ self.load(external)
42
+
43
+ def load_from_dir(self, directory: str | pathlib.Path) -> bool:
44
+ """Loads dispatchers from a directory containing Python modules where global variables
45
+ are declared with instances of dispatch.
46
+ Returns True if dispatchers were found, otherwise False."""
47
+
48
+ directory = pathlib.Path(directory)
49
+
50
+ if not directory.exists():
51
+ raise PathExistsError(f"Path {str(directory)!r} does not exists.")
52
+
53
+ dps: list[typing.Self] = []
54
+ for root, _, files in os.walk(directory):
55
+ for f in files:
56
+ if f.endswith(".py") and f != "__init__.py":
57
+ module_path = os.path.join(root, f)
58
+ module_name = os.path.splitext(os.path.relpath(module_path, directory))[0]
59
+ module_name = module_name.replace(os.sep, ".")
60
+
61
+ spec = importlib_util.spec_from_file_location(module_name, module_path)
62
+ if spec is None or spec.loader is None:
63
+ continue
64
+
65
+ module = importlib_util.module_from_spec(spec)
66
+ sys.modules[module_name] = module
67
+ spec.loader.exec_module(module)
68
+
69
+ for obj in module.__dict__.values():
70
+ if isinstance(obj, self.__class__):
71
+ dps.append(obj)
72
+
73
+ self.load_many(*dps)
74
+ return bool(dps)
75
+
76
+
77
+ __all__ = ("ABCDispatch",)
@@ -1,6 +1,6 @@
1
1
  import dataclasses
2
- import typing
3
2
 
3
+ import typing_extensions as typing
4
4
  from fntypes import Nothing, Option, Some
5
5
  from vbml.patcher import Patcher
6
6
 
@@ -27,7 +27,7 @@ from telegrinder.types.objects import Update
27
27
  if typing.TYPE_CHECKING:
28
28
  from telegrinder.bot.rules.abc import ABCRule
29
29
 
30
- T = typing.TypeVar("T")
30
+ T = typing.TypeVar("T", default=typing.Any)
31
31
  Handler = typing.Callable[typing.Concatenate[T, ...], typing.Coroutine[typing.Any, typing.Any, typing.Any]]
32
32
  Event = typing.TypeVar("Event", bound=BaseCute)
33
33
 
@@ -52,7 +52,7 @@ class Dispatch(
52
52
  )
53
53
 
54
54
  def __repr__(self) -> str:
55
- return "Dispatch(%s)" % ", ".join(f"{k}={v!r}" for k, v in self.__dict__.items())
55
+ return "Dispatch(%s)" % ", ".join(f"{k}={v!r}" for k, v in self.get_views().items())
56
56
 
57
57
  @property
58
58
  def global_context(self) -> TelegrinderContext:
@@ -97,7 +97,7 @@ class Dispatch(
97
97
  ) -> typing.Callable[[Handler[T]], FuncHandler[UpdateCute, Handler[T], ErrorHandler]]: ...
98
98
 
99
99
  @typing.overload
100
- def handle( # type: ignore
100
+ def handle(
101
101
  self,
102
102
  *rules: "ABCRule",
103
103
  error_handler: ErrorHandlerT,
@@ -105,7 +105,7 @@ class Dispatch(
105
105
  ) -> typing.Callable[[Handler[T]], FuncHandler[UpdateCute, Handler[T], ErrorHandlerT]]: ...
106
106
 
107
107
  @typing.overload
108
- def handle( # type: ignore
108
+ def handle(
109
109
  self,
110
110
  *rules: "ABCRule",
111
111
  update_type: UpdateType,
@@ -142,15 +142,15 @@ class Dispatch(
142
142
  is_blocking: bool = True,
143
143
  ) -> typing.Callable[[Handler[T]], FuncHandler[UpdateCute, Handler[T], ErrorHandler]]: ...
144
144
 
145
- def handle( # type: ignore
145
+ def handle(
146
146
  self,
147
147
  *rules: "ABCRule",
148
148
  update_type: UpdateType | None = None,
149
149
  dataclass: type[typing.Any] = DEFAULT_DATACLASS,
150
150
  error_handler: ErrorHandlerT | None = None,
151
151
  is_blocking: bool = True,
152
- ):
153
- def wrapper(func: typing.Callable):
152
+ ) -> typing.Callable[..., typing.Any]:
153
+ def wrapper(func):
154
154
  handler = FuncHandler(
155
155
  func,
156
156
  list(rules),
@@ -21,10 +21,7 @@ from .abc import ABCHandler
21
21
  if typing.TYPE_CHECKING:
22
22
  from telegrinder.bot.rules import ABCRule
23
23
 
24
- F = typing.TypeVar(
25
- "F",
26
- bound=typing.Callable[typing.Concatenate[typing.Any, ...], typing.Awaitable[typing.Any]],
27
- )
24
+ F = typing.TypeVar("F", bound=typing.Callable[..., typing.Awaitable[typing.Any]])
28
25
  Event = typing.TypeVar("Event", bound=Model)
29
26
  ErrorHandlerT = typing.TypeVar("ErrorHandlerT", bound=ABCErrorHandler, default=ErrorHandler)
30
27
 
@@ -65,9 +62,15 @@ class FuncHandler(ABCHandler[Event], typing.Generic[Event, F, ErrorHandlerT]):
65
62
  temp_ctx = ctx.copy()
66
63
  temp_ctx |= self.preset_context
67
64
 
65
+ update = event
66
+
67
+ for rule in self.rules:
68
+ if not await check_rule(api, rule, update, temp_ctx):
69
+ logger.debug("Rule {!r} failed!", rule)
70
+ return False
71
+
68
72
  nodes = self.required_nodes
69
73
  node_col = None
70
- update = event
71
74
 
72
75
  if nodes:
73
76
  result = await compose_nodes(nodes, ctx, data={Update: event, API: api})
@@ -83,11 +86,6 @@ class FuncHandler(ABCHandler[Event], typing.Generic[Event, F, ErrorHandlerT]):
83
86
  if node is ctx[EVENT_NODE_KEY] and name in temp_ctx:
84
87
  ctx[EVENT_NODE_KEY] = temp_ctx.pop(name)
85
88
 
86
- for rule in self.rules:
87
- if not await check_rule(api, rule, update, temp_ctx):
88
- logger.debug("Rule {!r} failed!", rule)
89
- return False
90
-
91
89
  logger.debug("All checks passed for handler.")
92
90
 
93
91
  temp_ctx["node_col"] = node_col
@@ -10,7 +10,7 @@ from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
10
10
  from telegrinder.model import Model
11
11
  from telegrinder.modules import logger
12
12
  from telegrinder.node.composer import CONTEXT_STORE_NODES_KEY, NodeScope, compose_nodes
13
- from telegrinder.tools.i18n.base import I18nEnum
13
+ from telegrinder.tools.i18n.abc import I18nEnum
14
14
  from telegrinder.types.objects import Update
15
15
 
16
16
  if typing.TYPE_CHECKING:
@@ -18,14 +18,22 @@ from telegrinder.msgspec_utils import Option
18
18
  from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
19
19
  from telegrinder.types.objects import Update
20
20
 
21
+ if typing.TYPE_CHECKING:
22
+ from telegrinder.node.base import Node
23
+
24
+ T = typing.TypeVar("T", contravariant=True, bound="BaseCute | Node")
21
25
  Event = typing.TypeVar("Event", bound=BaseCute)
22
26
  ErrorHandlerT = typing.TypeVar("ErrorHandlerT", bound=ABCErrorHandler)
23
27
  MiddlewareT = typing.TypeVar("MiddlewareT", bound=ABCMiddleware)
24
28
 
25
- FuncType: typing.TypeAlias = typing.Callable[
26
- typing.Concatenate[Event, ...],
27
- typing.Coroutine[typing.Any, typing.Any, typing.Any],
28
- ]
29
+
30
+ class Func(typing.Protocol[T]):
31
+ __name__: str
32
+
33
+ async def __call__(self, event_or_node: T, /, *args: typing.Any, **kwargs: typing.Any) -> typing.Any: ...
34
+
35
+
36
+ FuncType: typing.TypeAlias = Func[Event] | Func[T]
29
37
 
30
38
 
31
39
  def get_event_model_class(view: "BaseView[Event]") -> Option[type[Event]]:
@@ -66,8 +74,8 @@ class BaseView(ABCView, typing.Generic[Event]):
66
74
  cls,
67
75
  *rules: ABCRule,
68
76
  ) -> typing.Callable[
69
- [FuncType[Event]],
70
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
77
+ [FuncType[Event, T]],
78
+ FuncHandler[Event, FuncType[Event, T], ErrorHandler[Event]],
71
79
  ]: ...
72
80
 
73
81
  @typing.overload
@@ -77,7 +85,7 @@ class BaseView(ABCView, typing.Generic[Event]):
77
85
  *rules: ABCRule,
78
86
  error_handler: ErrorHandlerT,
79
87
  is_blocking: bool = True,
80
- ) -> typing.Callable[[FuncType[Event]], FuncHandler[Event, FuncType[Event], ErrorHandlerT]]: ...
88
+ ) -> typing.Callable[[FuncType[Event, T]], FuncHandler[Event, FuncType[Event, T], ErrorHandlerT]]: ...
81
89
 
82
90
  @typing.overload
83
91
  @classmethod
@@ -87,18 +95,18 @@ class BaseView(ABCView, typing.Generic[Event]):
87
95
  error_handler: typing.Literal[None] = None,
88
96
  is_blocking: bool = True,
89
97
  ) -> typing.Callable[
90
- [FuncType[Event]],
91
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
98
+ [FuncType[Event, T]],
99
+ FuncHandler[Event, FuncType[Event, T], ErrorHandler[Event]],
92
100
  ]: ...
93
101
 
94
102
  @classmethod
95
- def to_handler( # type: ignore
103
+ def to_handler(
96
104
  cls,
97
105
  *rules: ABCRule,
98
106
  error_handler: ABCErrorHandler | None = None,
99
107
  is_blocking: bool = True,
100
- ):
101
- def wrapper(func: FuncType[Event]):
108
+ ) -> typing.Callable[..., typing.Any]:
109
+ def wrapper(func):
102
110
  return FuncHandler(
103
111
  func,
104
112
  list(rules),
@@ -114,8 +122,8 @@ class BaseView(ABCView, typing.Generic[Event]):
114
122
  self,
115
123
  *rules: ABCRule,
116
124
  ) -> typing.Callable[
117
- [FuncType[Event]],
118
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
125
+ [FuncType[Event, T]],
126
+ FuncHandler[Event, FuncType[Event, T], ErrorHandler[Event]],
119
127
  ]: ...
120
128
 
121
129
  @typing.overload
@@ -124,7 +132,7 @@ class BaseView(ABCView, typing.Generic[Event]):
124
132
  *rules: ABCRule,
125
133
  error_handler: ErrorHandlerT,
126
134
  is_blocking: bool = True,
127
- ) -> typing.Callable[[FuncType[Event]], FuncHandler[Event, FuncType[Event], ErrorHandlerT]]: ...
135
+ ) -> typing.Callable[[FuncType[Event, T]], FuncHandler[Event, FuncType[Event, T], ErrorHandlerT]]: ...
128
136
 
129
137
  @typing.overload
130
138
  def __call__(
@@ -133,17 +141,17 @@ class BaseView(ABCView, typing.Generic[Event]):
133
141
  error_handler: typing.Literal[None] = None,
134
142
  is_blocking: bool = True,
135
143
  ) -> typing.Callable[
136
- [FuncType[Event]],
137
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
144
+ [FuncType[Event, T]],
145
+ FuncHandler[Event, FuncType[Event, T], ErrorHandler[Event]],
138
146
  ]: ...
139
147
 
140
- def __call__( # type: ignore
148
+ def __call__(
141
149
  self,
142
150
  *rules: ABCRule,
143
151
  error_handler: ABCErrorHandler | None = None,
144
152
  is_blocking: bool = True,
145
- ):
146
- def wrapper(func: FuncType[Event]):
153
+ ) -> typing.Callable[..., typing.Any]:
154
+ def wrapper(func):
147
155
  func_handler = FuncHandler(
148
156
  func,
149
157
  [*self.auto_rules, *rules],
@@ -198,3 +206,6 @@ class BaseStateView(ABCStateView[Event], BaseView[Event], ABC, typing.Generic[Ev
198
206
  @abstractmethod
199
207
  def get_state_key(self, event: Event) -> int | None:
200
208
  pass
209
+
210
+
211
+ __all__ = ("ABCStateView", "ABCView", "BaseStateView", "BaseView")
@@ -11,12 +11,13 @@ from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, Error
11
11
  from telegrinder.types.enums import UpdateType
12
12
  from telegrinder.types.objects import Update
13
13
 
14
- T = typing.TypeVar("T")
14
+ T = typing.TypeVar("T", contravariant=True)
15
15
 
16
- FuncType: typing.TypeAlias = typing.Callable[
17
- typing.Concatenate[T, ...],
18
- typing.Coroutine[typing.Any, typing.Any, typing.Any],
19
- ]
16
+
17
+ class Func(typing.Protocol[T]):
18
+ __name__: str
19
+
20
+ async def __call__(self, event_or_node: T, /, *args: typing.Any, **kwargs: typing.Any) -> typing.Any: ...
20
21
 
21
22
 
22
23
  class RawEventView(ABCEventRawView[UpdateCute], BaseView[UpdateCute]):
@@ -32,8 +33,8 @@ class RawEventView(ABCEventRawView[UpdateCute], BaseView[UpdateCute]):
32
33
  update_type: UpdateType,
33
34
  *rules: ABCRule,
34
35
  ) -> typing.Callable[
35
- [FuncType[UpdateCute]],
36
- FuncHandler[UpdateCute, FuncType[UpdateCute], ErrorHandler[UpdateCute]],
36
+ [Func[UpdateCute]],
37
+ FuncHandler[UpdateCute, Func[UpdateCute], ErrorHandler[UpdateCute]],
37
38
  ]: ...
38
39
 
39
40
  @typing.overload
@@ -42,7 +43,7 @@ class RawEventView(ABCEventRawView[UpdateCute], BaseView[UpdateCute]):
42
43
  update_type: UpdateType,
43
44
  *rules: ABCRule,
44
45
  dataclass: type[T],
45
- ) -> typing.Callable[[FuncType[T]], FuncHandler[UpdateCute, FuncType[T], ErrorHandler[T]]]: ...
46
+ ) -> typing.Callable[[Func[T]], FuncHandler[UpdateCute, Func[T], ErrorHandler[T]]]: ...
46
47
 
47
48
  @typing.overload
48
49
  def __call__(
@@ -51,8 +52,8 @@ class RawEventView(ABCEventRawView[UpdateCute], BaseView[UpdateCute]):
51
52
  *rules: ABCRule,
52
53
  error_handler: ErrorHandlerT,
53
54
  ) -> typing.Callable[
54
- [FuncType[UpdateCute]],
55
- FuncHandler[UpdateCute, FuncType[UpdateCute], ErrorHandlerT],
55
+ [Func[UpdateCute]],
56
+ FuncHandler[UpdateCute, Func[UpdateCute], ErrorHandlerT],
56
57
  ]: ...
57
58
 
58
59
  @typing.overload
@@ -63,19 +64,19 @@ class RawEventView(ABCEventRawView[UpdateCute], BaseView[UpdateCute]):
63
64
  dataclass: type[T],
64
65
  error_handler: ErrorHandlerT,
65
66
  is_blocking: bool = True,
66
- ) -> typing.Callable[[FuncType[T]], FuncHandler[UpdateCute, FuncType[T], ErrorHandlerT]]: ...
67
+ ) -> typing.Callable[[Func[T]], FuncHandler[UpdateCute, Func[T], ErrorHandlerT]]: ...
67
68
 
68
69
  @typing.overload
69
70
  def __call__(
70
71
  self,
71
72
  update_type: UpdateType,
72
73
  *rules: ABCRule,
73
- dataclass: typing.Literal[None] = None,
74
- error_handler: typing.Literal[None] = None,
74
+ dataclass: None = None,
75
+ error_handler: None = None,
75
76
  is_blocking: bool = True,
76
77
  ) -> typing.Callable[
77
- [FuncType[UpdateCute]],
78
- FuncHandler[UpdateCute, FuncType[UpdateCute], ErrorHandler[UpdateCute]],
78
+ [Func[UpdateCute]],
79
+ FuncHandler[UpdateCute, Func[UpdateCute], ErrorHandler[UpdateCute]],
79
80
  ]: ...
80
81
 
81
82
  def __call__( # type: ignore
@@ -86,7 +87,7 @@ class RawEventView(ABCEventRawView[UpdateCute], BaseView[UpdateCute]):
86
87
  error_handler: ABCErrorHandler | None = None,
87
88
  is_blocking: bool = True,
88
89
  ):
89
- def wrapper(func: FuncType[typing.Any]):
90
+ def wrapper(func):
90
91
  func_handler = FuncHandler(
91
92
  func,
92
93
  rules=[*self.auto_rules, *rules],
@@ -112,3 +113,6 @@ class RawEventView(ABCEventRawView[UpdateCute], BaseView[UpdateCute]):
112
113
  self.handlers,
113
114
  self.return_manager,
114
115
  )
116
+
117
+
118
+ __all__ = ("RawEventView",)
@@ -8,3 +8,6 @@ from .short_state import EventModel, ShortState
8
8
  class WaiterActions(typing.TypedDict, typing.Generic[EventModel]):
9
9
  on_miss: typing.NotRequired[ABCHandler[EventModel]]
10
10
  on_drop: typing.NotRequired[typing.Callable[[ShortState[EventModel]], None]]
11
+
12
+
13
+ __all__ = ("WaiterActions",)
@@ -1,9 +1,8 @@
1
- from fntypes import Some
1
+ from fntypes.option import Some
2
2
 
3
3
  from telegrinder.bot.cute_types import CallbackQueryCute as CallbackQuery
4
4
  from telegrinder.bot.dispatch.view import CallbackQueryView
5
-
6
- from .hasher import Hasher
5
+ from telegrinder.bot.dispatch.waiter_machine.hasher.hasher import Hasher
7
6
 
8
7
 
9
8
  def from_chat_hash(chat_id: int) -> int:
@@ -14,13 +13,6 @@ def get_chat_from_event(event: CallbackQuery) -> int | None:
14
13
  return event.chat.and_then(lambda chat: Some(chat.id)).unwrap_or_none()
15
14
 
16
15
 
17
- CALLBACK_QUERY_FROM_CHAT = Hasher(
18
- view=CallbackQueryView,
19
- get_hash_from_data=from_chat_hash,
20
- get_data_from_event=get_chat_from_event,
21
- )
22
-
23
-
24
16
  def for_message_hash(message_id: int) -> int:
25
17
  return message_id
26
18
 
@@ -29,13 +21,6 @@ def get_message_for_event(event: CallbackQuery) -> int | None:
29
21
  return event.message_id.unwrap_or_none()
30
22
 
31
23
 
32
- CALLBACK_QUERY_FOR_MESSAGE = Hasher(
33
- view=CallbackQueryView,
34
- get_hash_from_data=for_message_hash,
35
- get_data_from_event=get_message_for_event,
36
- )
37
-
38
-
39
24
  def for_message_in_chat(chat_and_message: tuple[int, int]) -> str:
40
25
  return f"{chat_and_message[0]}_{chat_and_message[1]}"
41
26
 
@@ -46,8 +31,20 @@ def get_chat_and_message_for_event(event: CallbackQuery) -> tuple[int, int] | No
46
31
  return event.chat.unwrap().id, event.message_id.unwrap()
47
32
 
48
33
 
34
+ CALLBACK_QUERY_FROM_CHAT = Hasher(
35
+ view_class=CallbackQueryView,
36
+ get_hash_from_data=from_chat_hash,
37
+ get_data_from_event=get_chat_from_event,
38
+ )
39
+
40
+ CALLBACK_QUERY_FOR_MESSAGE = Hasher(
41
+ view_class=CallbackQueryView,
42
+ get_hash_from_data=for_message_hash,
43
+ get_data_from_event=get_message_for_event,
44
+ )
45
+
49
46
  CALLBACK_QUERY_IN_CHAT_FOR_MESSAGE = Hasher(
50
- view=CallbackQueryView,
47
+ view_class=CallbackQueryView,
51
48
  get_hash_from_data=for_message_in_chat,
52
49
  get_data_from_event=get_chat_and_message_for_event,
53
50
  )
@@ -1,30 +1,44 @@
1
1
  import typing
2
+ from functools import cached_property
2
3
 
3
- from fntypes import Option
4
+ from fntypes.option import Option
4
5
 
5
6
  from telegrinder.bot.cute_types import BaseCute
6
7
  from telegrinder.bot.dispatch.view.base import BaseView
7
8
  from telegrinder.tools.functional import from_optional
8
9
 
10
+ T = typing.TypeVar("T")
9
11
  Event = typing.TypeVar("Event", bound=BaseCute)
10
12
  Data = typing.TypeVar("Data")
11
13
 
12
- ECHO = lambda x: x
14
+
15
+ def _echo(__x: T) -> T:
16
+ return __x
17
+
18
+
19
+ ECHO = _echo
13
20
 
14
21
 
15
22
  class Hasher(typing.Generic[Event, Data]):
16
23
  def __init__(
17
24
  self,
18
- view: type[BaseView[Event]],
25
+ view_class: type[BaseView[Event]],
19
26
  get_hash_from_data: typing.Callable[[Data], typing.Hashable | None] | None = None,
20
27
  get_data_from_event: typing.Callable[[Event], Data | None] | None = None,
21
- ):
22
- self.view = view
28
+ ) -> None:
29
+ self.view_class = view_class
23
30
  self._get_hash_from_data = get_hash_from_data
24
31
  self._get_data_from_event = get_data_from_event
25
32
 
26
- def get_name(self) -> str:
27
- return f"{self.view.__class__.__name__}_{id(self)}"
33
+ def __hash__(self) -> int:
34
+ return hash(self.name)
35
+
36
+ def __repr__(self) -> str:
37
+ return f"<Hasher {self.name}>"
38
+
39
+ @cached_property
40
+ def name(self) -> str:
41
+ return f"{self.view_class.__name__}_{id(self)}"
28
42
 
29
43
  def get_hash_from_data(self, data: Data) -> Option[typing.Hashable]:
30
44
  if self._get_hash_from_data is None:
@@ -39,11 +53,5 @@ class Hasher(typing.Generic[Event, Data]):
39
53
  def get_hash_from_data_from_event(self, event: Event) -> Option[typing.Hashable]:
40
54
  return self.get_data_from_event(event).and_then(self.get_hash_from_data) # type: ignore
41
55
 
42
- def __hash__(self) -> int:
43
- return hash(self.get_name())
44
-
45
- def __repr__(self) -> str:
46
- return f"<Hasher {self.get_name()}>"
47
-
48
56
 
49
57
  __all__ = ("Hasher",)