8000 Move Dunder Methods to the Top of Class Bodies (#3883) · guillemap/python-telegram-bot@5b0f169 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5b0f169

Browse files
Move Dunder Methods to the Top of Class Bodies (python-telegram-bot#3883)
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
1 parent 9c7298c commit 5b0f169

File tree

10 files changed

+487
-487
lines changed

10 files changed

+487
-487
lines changed

telegram/_bot.py

Lines changed: 134 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,54 @@ def __init__(
309309

310310
self._freeze()
311311

312+
async def __aenter__(self: BT) -> BT:
313+
try:
314+
await self.initialize()
315+
return self
316+
except Exception as exc:
317+
await self.shutdown()
318+
raise exc
319+
320+
async def __aexit__(
321+
self,
322+
exc_type: Optional[Type[BaseException]],
323+
exc_val: Optional[BaseException],
324+
exc_tb: Optional[TracebackType],
325+
) -> None:
326+
# Make sure not to return `True` so that exceptions are not suppressed
327+
# https://docs.python.org/3/reference/datamodel.html?#object.__aexit__
328+
await self.shutdown()
329+
330+
def __reduce__(self) -> NoReturn:
331+
"""Customizes how :func:`copy.deepcopy` processes objects of this type. Bots can not
332+
be pickled and this method will always raise an exception.
333+
334+
.. versionadded:: 20.0
335+
336+
Raises:
337+
:exc:`pickle.PicklingError`
338+
"""
339+
raise pickle.PicklingError("Bot objects cannot be pickled!")
340+
341+
def __deepcopy__(self, memodict: Dict[int, object]) -> NoReturn:
342+
"""Customizes how :func:`copy.deepcopy` processes objects of this type. Bots can not
343+
be deepcopied and this method will always raise an exception.
344+
345+
.. versionadded:: 20.0
346+
347+
Raises:
348+
:exc:`TypeError`
349+
"""
350+
raise TypeError("Bot objects cannot be deepcopied!")
351+
352+
def __eq__(self, other: object) -> bool:
353+
if isinstance(other, self.__class__):
354+
return self.bot == other.bot
355+
return False
356+
357+
def __hash__(self) -> int:
358+
return hash((self.__class__, self.bot))
359+
312360
def __repr__(self) -> str:
313361
"""Give a string representation of the bot in the form ``Bot[token=...]``.
314362
@@ -365,36 +413,101 @@ def private_key(self) -> Optional[Any]:
365413
"""
366414
return self._private_key
367415

368-
@classmethod
369-
def _warn(
370-
cls, message: str, category: Type[Warning] = PTBUserWarning, stacklevel: int = 0
371-
) -> None:
372-
"""Convenience method to issue a warning. This method is here mostly to make it easier
373-
for ExtBot to add 1 level to all warning calls.
416+
@property
417+
def request(self) -> BaseRequest:
418+
"""The :class:`~telegram.request.BaseRequest` object used by this bot.
419+
420+
Warning:
421+
Requests to the Bot API are made by the various methods of this class. This attribute
422+
should *not* be used manually.
374423
"""
375-
warn(message=message, category=category, stacklevel=stacklevel + 1)
424+
return self._request[1]
376425

377-
def __reduce__(self) -> NoReturn:
378-
"""Customizes how :func:`copy.deepcopy` processes objects of this type. Bots can not
379-
be pickled and this method will always raise an exception.
426+
@property
427+
def bot(self) -> User:
428+
""":class:`telegram.User`: User instance for the bot as returned by :meth:`get_me`.
380429
381-
.. versionadded:: 20.0
430+
Warning:
431+
This value is the cached return value of :meth:`get_me`. If the bots profile is
432+
changed during runtime, this value won't reflect the changes until :meth:`get_me` is
433+
called again.
382434
383-
Raises:
384-
:exc:`pickle.PicklingError`
435+
.. seealso:: :meth:`initialize`
385436
"""
386-
raise pickle.PicklingError("Bot objects cannot be pickled!")
437+
if self._bot_user is None:
438+
raise RuntimeError(
439+
f"{self.__class__.__name__} is not properly initialized. Call "
440+
f"`{self.__class__.__name__}.initialize` before accessing this property."
441+
)
442+
return self._bot_user
387443

388-
def __deepcopy__(self, memodict: Dict[int, object]) -> NoReturn:
389-
"""Customizes how :func:`copy.deepcopy` processes objects of this type. Bots can not
390-
be deepcopied and this method will always raise an exception.
444+
@property
445+
def id(self) -> int:
446+
""":obj:`int`: Unique identifier for this bot. Shortcut for the corresponding attribute of
447+
:attr:`bot`.
448+
"""
449+
return self.bot.id
391450

392-
.. versionadded:: 20.0
451+
@property
452+
def first_name(self) -> str:
453+
""":obj:`str`: Bot's first name. Shortcut for the corresponding attribute of
454+
:attr:`bot`.
455+
"""
456+
return self.bot.first_name
393457

394-
Raises:
395-
:exc:`TypeError`
458+
@property
459+
def last_name(self) -> str:
460+
""":obj:`str`: Optional. Bot's last name. Shortcut for the corresponding attribute of
461+
:attr:`bot`.
396462
"""
397-
raise TypeError("Bot objects cannot be deepcopied!")
463+
return self.bot.last_name # type: ignore
464+
465+
@property
466+
def username(self) -> str:
467+
""":obj:`str`: Bot's username. Shortcut for the corresponding attribute of
468+
:attr:`bot`.
469+
"""
470+
return self.bot.username # type: ignore
471+
472+
@property
473+
def link(self) -> str:
474+
""":obj:`str`: Convenience property. Returns the t.me link of the bot."""
475+
return f"https://t.me/{self.username}"
476+
477+
@property
478+
def can_join_groups(self) -> bool:
479+
""":obj:`bool`: Bot's :attr:`telegram.User.can_join_groups` attribute. Shortcut for the
480+
corresponding attribute of :attr:`bot`.
481+
"""
482+
return self.bot.can_join_groups # type: ignore
483+
484+
@property
485+
def can_read_all_group_messages(self) -> bool:
486+
""":obj:`bool`: Bot's :attr:`telegram.User.can_read_all_group_messages` attribute.
487+
Shortcut for the corresponding attribute of :attr:`bot`.
488+
"""
489+
return self.bot.can_read_all_group_messages # type: ignore
490+
491+
@property
492+
def supports_inline_queries(self) -> bool:
493+
""":obj:`bool`: Bot's :attr:`telegram.User.supports_inline_queries` attribute.
494+
Shortcut for the corresponding attribute of :attr:`bot`.
495+
"""
496+
return self.bot.supports_inline_queries # type: ignore
497+
498+
@property
499+
def name(self) -> str:
500+
""":obj:`str`: Bot's @username. Shortcut for the corresponding attribute of :attr:`bot`."""
501+
return f"@{self.username}"
502+
503+
@classmethod
504+
def _warn(
505+
cls, message: str, category: Type[Warning] = PTBUserWarning, stacklevel: int = 0
506+
) -> None:
507+
"""Convenience method to issue a warning. This method is here mostly to make it easier
508+
for ExtBot to add 1 level to all warning calls.
509+
"""
510+
warn(message=message, category=category, stacklevel=stacklevel + 1)
398511

399512
# TODO: After https://youtrack.jetbrains.com/issue/PY-50952 is fixed, we can revisit this and
400513
# consider adding Paramspec from typing_extensions to properly fix this. Currently a workaround
@@ -633,111 +746,6 @@ async def shutdown(self) -> None:
633746
await asyncio.gather(self._request[0].shutdown(), self._request[1].shutdown())
634747
self._initialized = False
635748

636-
async def __aenter__(self: BT) -> BT:
637-
try:
638-
await self.initialize()
639-
return self
640-
except Exception as exc:
641-
await self.shutdown()
642-
raise exc
643-
644-
async def __aexit__(
645-
self,
646-
exc_type: Optional[Type[BaseException]],
647-
exc_val: Optional[BaseException],
648-
exc_tb: Optional[TracebackType],
649-
) -> None:
650-
# Make sure not to return `True` so that exceptions are not suppressed
651-
# https://docs.python.org/3/reference/datamodel.html?#object.__aexit__
652-
await self.shutdown()
653-
654-
@property
655-
def request(self) -> BaseRequest:
656-
"""The :class:`~telegram.request.BaseRequest` object used by this bot.
657-
658-
Warning:
659-
Requests to the Bot API are made by the various methods of this class. This attribute
660-
should *not* be used manually.
661-
"""
662-
return self._request[1]
663-
664-
@property
665-
def bot(self) -> User:
666-
""":class:`telegram.User`: User instance for the bot as returned by :meth:`get_me`.
667-
668-
Warning:
669-
This value is the cached return value of :meth:`get_me`. If the bots profile is
670-
changed during runtime, this value won't reflect the changes until :meth:`get_me` is
671-
called again.
672-
673-
.. seealso:: :meth:`initialize`
674-
"""
675-
if self._bot_user is None:
676-
raise RuntimeError(
677-
f"{self.__class__.__name__} is not properly initialized. Call "
678-
f"`{self.__class__.__name__}.initialize` before accessing this property."
679-
)
680-
return self._bot_user
681-
682-
@property
683-
def id(self) -> int:
684-
""":obj:`int`: Unique identifier for this bot. Shortcut for the corresponding attribute of
685-
:attr:`bot`.
686-
"""
687-
return self.bot.id
688-
689-
@property
690-
def first_name(self) -> str:
691-
""":obj:`str`: Bot's first name. Shortcut for the corresponding attribute of
692-
:attr:`bot`.
693-
"""
694-
return self.bot.first_name
695-
696-
@property
697-
def last_name(self) -> str:
698-
""":obj:`str`: Optional. Bot's last name. Shortcut for the corresponding attribute of
699-
:attr:`bot`.
700-
"""
701-
return self.bot.last_name # type: ignore
702-
703-
@property
704-
def username(self) -> str:
705-
""":obj:`str`: Bot's username. Shortcut for the corresponding attribute of
706-
:attr:`bot`.
707-
"""
708-
return self.bot.username # type: ignore
709-
710-
@property
711-
def link(self) -> str:
712-
""":obj:`str`: Convenience property. Returns the t.me link of the bot."""
713-
return f"https://t.me/{self.username}"
714-
715-
@property
716-
def can_join_groups(self) -> bool:
717-
""":obj:`bool`: Bot's :attr:`telegram.User.can_join_groups` attribute. Shortcut for the
718-
corresponding attribute of :attr:`bot`.
719-
"""
720-
return self.bot.can_join_groups # type: ignore
721-
722-
@property
723-
def can_read_all_group_messages(self) -> bool:
724-
""":obj:`bool`: Bot's :attr:`telegram.User.can_read_all_group_messages` attribute.
725-
Shortcut for the corresponding attribute of :attr:`bot`.
726-
"""
727-
return self.bot.can_read_all_group_messages # type: ignore
728-
729-
@property
730-
def supports_inline_queries(self) -> bool:
731-
""":obj:`bool`: Bot's :attr:`telegram.User.supports_inline_queries` attribute.
732-
Shortcut for the corresponding attribute of :attr:`bot`.
733-
"""
734-
return self.bot.supports_inline_queries # type: ignore
735-
736-
@property
737-
def name(self) -> str:
738-
""":obj:`str`: Bot's @username. Shortcut for the corresponding attribute of :attr:`bot`."""
739-
return f"@{self.username}"
740-
741749
@_log
742750
async def get_me(
743751
self,
@@ -7855,14 +7863,6 @@ def to_dict(self, recursive: bool = True) -> JSONDict: # skipcq: PYL-W0613
78557863

78567864
return data
78577865

7858-
def __eq__(self, other: object) -> bool:
7859-
if isinstance(other, self.__class__):
7860-
return self.bot == other.bot
7861-
return False
7862-
7863-
def __hash__(self) -> int:
7864-
return hash((self.__class__, self.bot))
7865-
78667866
# camelCase aliases
78677867
getMe = get_me
78687868
"""Alias for :meth:`get_me`"""

0 commit comments

Comments
 (0)
0