Pytdbot 0.10.0.dev5__py3-none-any.whl → 0.10.0.dev6__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.
pytdbot/__init__.py CHANGED
@@ -13,7 +13,7 @@ __all__ = [
13
13
  "Client",
14
14
  ]
15
15
 
16
- __version__ = "0.10.0.dev5"
16
+ __version__ = "0.10.0.dev6"
17
17
  __copyright__ = "Copyright (c) 2022-2026 Pytdbot, AYMENJD"
18
18
  __license__ = "MIT License"
19
19
 
@@ -1,4 +1,4 @@
1
- __all__ = ("StopHandlers", "AuthorizationError")
1
+ __all__ = ("StopHandlers", "AuthorizationError", "WebAppDataError")
2
2
 
3
3
 
4
4
  class StopHandlers(Exception):
@@ -10,22 +10,30 @@ class StopHandlers(Exception):
10
10
  class AuthorizationError(Exception):
11
11
  r"""An exception for authorization errors"""
12
12
 
13
+ def __init__(self, message: str, code: int = 0) -> None:
14
+ self.code = code
15
+ super().__init__(message)
16
+
17
+
18
+ class WebAppDataError(Exception):
19
+ r"""Base exception for webapp data errors"""
20
+
13
21
  pass
14
22
 
15
23
 
16
- class WebAppDataInvalid(Exception):
24
+ class WebAppDataInvalid(WebAppDataError):
17
25
  r"""An exception for invalid webapp data"""
18
26
 
19
27
  pass
20
28
 
21
29
 
22
- class WebAppDataOutdated(Exception):
30
+ class WebAppDataOutdated(WebAppDataError):
23
31
  r"""An exception for outdated webapp data"""
24
32
 
25
33
  pass
26
34
 
27
35
 
28
- class WebAppDataMismatch(Exception):
36
+ class WebAppDataMismatch(WebAppDataError):
29
37
  r"""An exception for mismatched webapp data"""
30
38
 
31
39
  pass
@@ -11,6 +11,8 @@ from .td_updates import Updates
11
11
 
12
12
  logger = logging.getLogger(__name__)
13
13
 
14
+ HandlerDecorator = Callable[[Callable], Callable]
15
+
14
16
 
15
17
  class Decorators(Updates):
16
18
  """Decorators class."""
@@ -21,7 +23,7 @@ class Decorators(Updates):
21
23
  position: int | None = None,
22
24
  inner_object: bool = False,
23
25
  timeout: float | None = None,
24
- ) -> None:
26
+ ) -> HandlerDecorator:
25
27
  r"""A decorator to initialize an event object before running other handlers
26
28
 
27
29
  Parameters:
@@ -85,7 +87,7 @@ class Decorators(Updates):
85
87
  position: int | None = None,
86
88
  inner_object: bool = False,
87
89
  timeout: float | None = None,
88
- ) -> None:
90
+ ) -> HandlerDecorator:
89
91
  r"""A decorator to finalize an event object after running all handlers
90
92
 
91
93
  Parameters:
@@ -147,7 +149,7 @@ class Decorators(Updates):
147
149
  filters: pytdbot.filters.Filter | None = None,
148
150
  position: int | None = None,
149
151
  timeout: float | None = None,
150
- ) -> None:
152
+ ) -> HandlerDecorator:
151
153
  r"""A decorator to handle ``updateNewMessage`` but with ``Message`` object.
152
154
 
153
155
  Parameters:
@@ -207,7 +209,7 @@ class Decorators(Updates):
207
209
  filters: pytdbot.filters.Filter | None = None,
208
210
  position: int | None = None,
209
211
  timeout: float | None = None,
210
- ) -> None:
212
+ ) -> HandlerDecorator:
211
213
  r"""A scheduled event has been triggered
212
214
 
213
215
  Parameters:
@@ -10,6 +10,16 @@ from ..filters import Filter
10
10
  class Handler:
11
11
  r"""A handler class."""
12
12
 
13
+ __slots__ = (
14
+ "func",
15
+ "update_type",
16
+ "filter",
17
+ "position",
18
+ "inner_object",
19
+ "timeout",
20
+ "is_from_plugin",
21
+ )
22
+
13
23
  def __init__(
14
24
  self,
15
25
  func: Callable,
pytdbot/utils/escape.py CHANGED
@@ -18,8 +18,8 @@ def escape_html(text: str, quote: bool = True) -> str:
18
18
  return _html_escape(text, quote=quote)
19
19
 
20
20
 
21
- special_chars_v1 = r"_\*`\["
22
- special_chars_v2 = r"\_*[]()~`>#+-=|{}.!"
21
+ special_chars_v1_set = set(r"_\*`\[")
22
+ special_chars_v2_set = set(r"\_*[]()~`>#+-=|{}.!")
23
23
 
24
24
 
25
25
  def escape_markdown(text: str, version: int = 2) -> str:
@@ -40,9 +40,9 @@ def escape_markdown(text: str, version: int = 2) -> str:
40
40
  """
41
41
 
42
42
  if version == 1:
43
- chars = special_chars_v1
43
+ chars = special_chars_v1_set
44
44
  elif version == 2:
45
- chars = special_chars_v2
45
+ chars = special_chars_v2_set
46
46
  else:
47
47
  raise ValueError("Invalid version. Must be 1 or 2.")
48
48
 
@@ -1,3 +1,5 @@
1
+ from typing import Any
2
+
1
3
  try:
2
4
  import orjson as json
3
5
  except ImportError:
@@ -29,12 +31,12 @@ else:
29
31
  return d if not encode else d.encode("utf-8")
30
32
 
31
33
 
32
- def json_loads(obj):
34
+ def json_loads(obj: Any) -> Any:
33
35
  return json.loads(obj)
34
36
 
35
37
 
36
38
  class CallbackData:
37
- def __init__(self, action, data=None):
39
+ def __init__(self, action: str, data: Any = None) -> None:
38
40
  self.action = action
39
41
  self.data = data
40
42
 
@@ -45,20 +47,20 @@ empty_callback_data = CallbackData("")
45
47
  def load_callback_data(data: bytes) -> CallbackData:
46
48
  r"""loads already created callback data by :func:`~pytdbot.utils.callback_data`. Returns empty CallbackData on error"""
47
49
 
48
- if not (data[0] == 0x5B and data[-1] == 0x5D):
50
+ if not data or not (data[0] == 0x5B and data[-1] == 0x5D):
49
51
  return empty_callback_data
50
52
 
51
53
  try:
52
54
  d = json_loads(data)
53
55
  if not isinstance(d, list) or len(d) != 2:
54
56
  return empty_callback_data
55
- except Exception:
57
+ except (ValueError, TypeError):
56
58
  return empty_callback_data
57
59
  else:
58
60
  return CallbackData(*d)
59
61
 
60
62
 
61
- def callback_data(action, data=None) -> bytes:
63
+ def callback_data(action: Any, data: Any = None) -> bytes:
62
64
  r"""Create callback data for inline buttons
63
65
 
64
66
  Parameters:
@@ -1,14 +1,17 @@
1
1
  import json
2
2
  from base64 import b64encode
3
+ from typing import Any
3
4
 
4
5
  from .. import types, utils
5
6
 
7
+ _type_cache: dict[str, type] = {}
6
8
 
7
- def obj_to_json(obj, **kwargs):
9
+
10
+ def obj_to_json(obj: Any, **kwargs: Any) -> str:
8
11
  return json.dumps(obj_to_dict(obj), **kwargs)
9
12
 
10
13
 
11
- def obj_to_dict(obj):
14
+ def obj_to_dict(obj: Any) -> Any:
12
15
  if hasattr(obj, "to_dict"):
13
16
  return obj_to_dict(obj.to_dict())
14
17
  elif isinstance(obj, list):
@@ -21,10 +24,16 @@ def obj_to_dict(obj):
21
24
  return obj
22
25
 
23
26
 
24
- def dict_to_obj(dict_obj, client=None):
27
+ def dict_to_obj(dict_obj: Any, client: Any = None) -> Any:
25
28
  if isinstance(dict_obj, dict):
26
29
  if "@type" in dict_obj:
27
- obj = getattr(types, utils.to_camel_case(dict_obj["@type"])).from_dict(
30
+ td_type = dict_obj["@type"]
31
+ obj_type = _type_cache.get(td_type)
32
+ if obj_type is None:
33
+ obj_type = getattr(types, utils.to_camel_case(td_type))
34
+ _type_cache[td_type] = obj_type
35
+
36
+ obj = obj_type.from_dict(
28
37
  {key: dict_to_obj(value, client) for key, value in dict_obj.items()}
29
38
  )
30
39
  if client:
pytdbot/utils/strings.py CHANGED
@@ -9,23 +9,23 @@ def to_camel_case(input_str: str, delimiter: str = ".", is_class: bool = True) -
9
9
  return ""
10
10
 
11
11
  parts = input_str.split(delimiter)
12
- camel_case_str = ""
13
12
 
14
- for i, part in enumerate(parts):
15
- if i > 0:
16
- camel_case_str += part[0].upper() + part[1:]
17
- else:
18
- camel_case_str += part
13
+ result = [parts[0]]
14
+ for part in parts[1:]:
15
+ result.append(part[0].upper())
16
+ result.append(part[1:])
19
17
 
20
- if camel_case_str:
21
- camel_case_str = (
22
- camel_case_str[0].upper() if is_class else camel_case_str[0].lower()
23
- ) + camel_case_str[1:]
18
+ joined = "".join(result)
24
19
 
25
- return camel_case_str
20
+ if not joined:
21
+ return ""
22
+
23
+ if is_class:
24
+ return joined[0].upper() + joined[1:]
25
+ return joined[0].lower() + joined[1:]
26
26
 
27
27
 
28
- def create_extra_id(bytes_size: int = 9):
28
+ def create_extra_id(bytes_size: int = 9) -> str:
29
29
  return binascii.hexlify(os.urandom(bytes_size)).decode()
30
30
 
31
31
 
@@ -48,5 +48,5 @@ def get_retry_after_time(error_message: str) -> int:
48
48
 
49
49
  try:
50
50
  return int(error_message.removeprefix(RETRY_AFTER_PREFEX))
51
- except Exception:
51
+ except (ValueError, AttributeError):
52
52
  return 0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Pytdbot
3
- Version: 0.10.0.dev5
3
+ Version: 0.10.0.dev6
4
4
  Summary: Easy-to-use asynchronous TDLib wrapper for Python.
5
5
  Author-email: AYMEN A <let.me.code.safe@gmail.com>
6
6
  License-Expression: MIT
@@ -1,11 +1,11 @@
1
- pytdbot/__init__.py,sha256=PTdb68DV7VmMQHsCyPEbSxhsWqs7dQIXdWxdwBK5TtI,424
1
+ pytdbot/__init__.py,sha256=fAOXY9Ym3mogUkdcHUqriTb9-7a0Dqak2bS7-YzDFbU,424
2
2
  pytdbot/client.py,sha256=c57DSHi2oH5Fx9HurQue5V2L3AANrFrliuV48FtDi6E,45940
3
3
  pytdbot/client_manager.py,sha256=jWWosyRY57XAL8u2UmsE9ftpLHhJG8moJxeSIvVjgFs,6515
4
4
  pytdbot/filters.py,sha256=V6b09AGNVrw4ipgRMFYD9jJKAcNo9_WIJ-bSaGwSyf4,1549
5
- pytdbot/exception/__init__.py,sha256=K58aYatmsHdbnYuDThr9akCrCrN-_TiWbfrXpCGVSCI,540
5
+ pytdbot/exception/__init__.py,sha256=KCO1OF5xjKz2k9nUMzSGUITva-Y1Mb4N54kE-MEtnsg,783
6
6
  pytdbot/handlers/__init__.py,sha256=ap6He04bk1v9BnYxhY6-_wrD7gBk39U9wrhJagxyOOw,101
7
- pytdbot/handlers/decorators.py,sha256=3_WSbnX586dTyfZtVZVb2Dd1dFs1fFrlUtsTPRcLE4Q,9048
8
- pytdbot/handlers/handler.py,sha256=jbQatcL27iskCvmuR-dWR-VNMKYz3MinPA6PSxcT3Yw,1124
7
+ pytdbot/handlers/decorators.py,sha256=qZFeYbPMh07aLUtLfNnlenvz8x4Z33L48ASWC8mqEKQ,9147
8
+ pytdbot/handlers/handler.py,sha256=XILBjMhpwvPcVUssv2XP_tsoMlo9qjgqTvNHrftnOZI,1295
9
9
  pytdbot/handlers/td_updates.py,sha256=tlu9BKefvrOk09954iZsnxxEKh1Oio_N7xyC8oKkchw,385216
10
10
  pytdbot/methods/__init__.py,sha256=naVHl8-m9DU43Z_QUFYQOPes6NDz86JLWjb2l0q59ws,53
11
11
  pytdbot/methods/methods.py,sha256=lDXNkx3XFxmCtM8lqWU5bIZkcmU15OT8Oz3XbQCANCo,65398
@@ -26,14 +26,14 @@ pytdbot/types/tdserver/schedule.py,sha256=_4DyCk4EG_b54g85DDRKUyq_S0ptcCGhdM26OB
26
26
  pytdbot/types/tdserver/stats.py,sha256=WKpn0bWHU-TgtUrPU1c9nJi6B-NhrJEtA0ZmLBqJ-Ow,1879
27
27
  pytdbot/utils/__init__.py,sha256=ttnEmS35a_DiHCGFtExscZZB-KB4xWWv5o413PGtiDM,1404
28
28
  pytdbot/utils/albums.py,sha256=xl8wzTju2Rim1uH0LjlsW1NxkKrstsZCD3oCWu-O_gE,513
29
- pytdbot/utils/escape.py,sha256=Ya2Ho7WtH3gjNIWuiSbRJdwAOhqS_X5KtWnU0_ZqSf8,1191
30
- pytdbot/utils/json_utils.py,sha256=VKHgHIFCiJASfE7Fp9IVAv6i7B59QL6cBug6m2aXhlQ,2121
31
- pytdbot/utils/obj_encoder.py,sha256=VmFdYtGloV3wOQx-srdrg4HY8cIYiGmFik0VmYFZB4w,1158
32
- pytdbot/utils/strings.py,sha256=0jVBjlM0bKV5iCZy5ZipBTCPvdaqMxhlp1dxnu5W2dY,1256
29
+ pytdbot/utils/escape.py,sha256=D5ZL3xBAMZDvAb_GLYk-nbk_H7RbnRcBsKt2NOOoC0o,1217
30
+ pytdbot/utils/json_utils.py,sha256=YLZt5Jc5w-ZFaW5QHTwH-qdvtFUXOcWwp1-cMghCcNM,2217
31
+ pytdbot/utils/obj_encoder.py,sha256=NeZxXQlj4cUMvfa1kFT1516xz4sgKOHexYbGVJSQAbM,1460
32
+ pytdbot/utils/strings.py,sha256=NjTArf4zkOV3j2kerJfbA47lmuwZ20Xh_ppZ-pETQ0c,1203
33
33
  pytdbot/utils/text_format.py,sha256=g-PvtYr0dvltCa120IcEMff6LnBeI_F_6m7anYtEFaE,9762
34
34
  pytdbot/utils/webapps.py,sha256=qD8j3wpgAn2KgxEZMoh7k8FEom8JNiPN3rKweAS2lGw,2428
35
- pytdbot-0.10.0.dev5.dist-info/licenses/LICENSE,sha256=Y77J1RSAYfRz6kBjIWq81eWgLFQ_Su_b1l5rWthsHCM,1078
36
- pytdbot-0.10.0.dev5.dist-info/METADATA,sha256=hdDDkNKNpQDPBNfAgcgYUv6f6NPfoS4nykY5UOcTywQ,11026
37
- pytdbot-0.10.0.dev5.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
38
- pytdbot-0.10.0.dev5.dist-info/top_level.txt,sha256=EkLKG-BZysNAC-td3TJQQAomlT6YsvKWwei1Pzk6Oqg,8
39
- pytdbot-0.10.0.dev5.dist-info/RECORD,,
35
+ pytdbot-0.10.0.dev6.dist-info/licenses/LICENSE,sha256=Y77J1RSAYfRz6kBjIWq81eWgLFQ_Su_b1l5rWthsHCM,1078
36
+ pytdbot-0.10.0.dev6.dist-info/METADATA,sha256=r1Rg4h4SjTkxWVL9M_-7msCEuu-RmRJVDCBM3SLN6dA,11026
37
+ pytdbot-0.10.0.dev6.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
38
+ pytdbot-0.10.0.dev6.dist-info/top_level.txt,sha256=EkLKG-BZysNAC-td3TJQQAomlT6YsvKWwei1Pzk6Oqg,8
39
+ pytdbot-0.10.0.dev6.dist-info/RECORD,,