From 2fb8ef6c74488af54dd90ec81364ab969512ecf1 Mon Sep 17 00:00:00 2001 From: david-shiko Date: Fri, 7 Mar 2025 04:31:36 +0300 Subject: [PATCH] Add `name` and `full_name` properties to the `SharedUser` class just as in the `telegram.User` class. --- telegram/_shared.py | 22 +++++++++++++++++++++- tests/test_shared.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/telegram/_shared.py b/telegram/_shared.py index 9c0d3684ec2..77055624631 100644 --- a/telegram/_shared.py +++ b/telegram/_shared.py @@ -18,7 +18,7 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains two objects used for request chats/users service messages.""" from collections.abc import Sequence -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, Optional, Union from telegram._files.photosize import PhotoSize from telegram._telegramobject import TelegramObject @@ -244,6 +244,26 @@ def __init__( self._freeze() + @property + def name(self) -> Union[str, None]: + """:obj:`str`: Convenience property. If available, returns the user's :attr:`username` + prefixed with "@". If :attr:`username` is not available, returns :attr:`full_name`. + """ + if self.username: + return f"@{self.username}" + return self.full_name + + @property + def full_name(self) -> Union[str, None]: + """:obj:`str`: Convenience property. The user's :attr:`first_name`, followed by (if + available) :attr:`last_name`, otherwise None. + """ + if self.first_name and self.last_name: + return f"{self.first_name} {self.last_name}" + if self.first_name or self.last_name: + return f"{self.first_name or self.last_name}" + return None + @classmethod def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "SharedUser": """See :meth:`telegram.TelegramObject.de_json`.""" diff --git a/tests/test_shared.py b/tests/test_shared.py index 239e8600092..61478b7a8aa 100644 --- a/tests/test_shared.py +++ b/tests/test_shared.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Lesser Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. +from unittest.mock import patch + import pytest from telegram import ChatShared, PhotoSize, SharedUser, UsersShared @@ -228,3 +230,32 @@ def test_equality(self, chat_shared): assert a != d assert hash(a) != hash(d) + + def test_name(self, shared_user, ): + with shared_user._unfrozen(): + assert shared_user.name == "@user" + with patch.object(shared_user, 'username', None): + assert shared_user.name == "first last" + with patch.multiple( + shared_user, + last_name=None, + first_name=None, + ): + assert shared_user.full_name is None + + def test_full_name(self, shared_user): + with shared_user._unfrozen(): + # Test `and` (both exists) + assert shared_user.full_name == "first last" + # Test `or` (one of them exists) + with patch.object(shared_user, 'first_name', None): + assert shared_user.full_name == "last" + with patch.object(shared_user, 'last_name', None): + assert shared_user.full_name == "first" + # Test None (None of them exists) + with patch.multiple( + shared_user, + last_name=None, + first_name=None, + ): + assert shared_user.full_name is None