diff --git a/changes/unreleased/5078.FoNwUYLbXQFRebTFhR6UPn.toml b/changes/unreleased/5078.FoNwUYLbXQFRebTFhR6UPn.toml index 1894feaba7f..d74a4e85a0e 100644 --- a/changes/unreleased/5078.FoNwUYLbXQFRebTFhR6UPn.toml +++ b/changes/unreleased/5078.FoNwUYLbXQFRebTFhR6UPn.toml @@ -3,6 +3,8 @@ Full Support for Bot API 9.3 .. warning:: + - Bot API 9.3 deprecates the field ``last_resale_star_count`` of ``UniqueGiftInfo`` in favor of the new fields ``last_resale_currency`` and ``last_resale_amount``. The field ``last_resale_star_count`` is still present in PTB for backward compatibility, but it will be removed in future releases. Please update your code accordingly. + - Bot API 9.3 deprecates the argument ``exclude_limited`` of ``Bot.get_business_account_gifts`` in favor of the new arguments ``exclude_limited_upgradable`` and ``exclude_limited_non_upgradable``. The argument ``exclude_limited`` is still present in PTB for backward compatibility, but it will be removed in future releases. Please update your code accordingly. - Bot API 9.3 introduces a now required argument ``gift_id`` to ``UniqueGift``. For backward compatibility, the argument is currently still marked as optional in the signature and it's presence is enforced through a runtime check. In future versions, this argument will be made required in the signature as well. @@ -21,4 +23,5 @@ pull_requests = [ { uid = "5089", author_uids = ["Bibo-Joshi"] }, { uid = "5092", author_uids = ["Bibo-Joshi"] }, { uid = "5095", author_uids = ["Bibo-Joshi"] }, + { uid = "5094", author_uids = ["Bibo-Joshi"] }, ] diff --git a/src/telegram/_uniquegift.py b/src/telegram/_uniquegift.py index 860bc1e57af..6ff3d145543 100644 --- a/src/telegram/_uniquegift.py +++ b/src/telegram/_uniquegift.py @@ -30,6 +30,12 @@ from telegram._utils.argumentparsing import de_json_optional, parse_sequence_arg from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp from telegram._utils.types import JSONDict +from telegram._utils.warnings import warn +from telegram._utils.warnings_transition import ( + build_deprecation_warning_message, + warn_about_deprecated_attr_in_property, +) +from telegram.warnings import PTBDeprecationWarning if TYPE_CHECKING: from telegram import Bot @@ -483,10 +489,14 @@ class UniqueGiftInfo(TelegramObject): gift (:class:`UniqueGift`): Information about the gift. origin (:obj:`str`): Origin of the gift. Currently, either :attr:`UPGRADE` for gifts upgraded from regular gifts, :attr:`TRANSFER` for gifts transferred from other users - or channels, or :attr:`RESALE` for gifts bought from other users. + or channels, :attr:`RESALE` for gifts bought from other users, + :attr:`GIFTED_UPGRADE` for upgrades purchased after the gift was sent, or :attr:`OFFER` + for gifts bought or sold through gift purchase offers .. versionchanged:: 22.3 The :attr:`RESALE` origin was added. + .. versionchanged:: NEXT.VERSION + Bot API 9.3 added the :attr:`GIFTED_UPGRADE` and :attr:`OFFER` origins. owned_gift_id (:obj:`str`, optional) Unique identifier of the received gift for the bot; only present for gifts received on behalf of business accounts. transfer_star_count (:obj:`int`, optional): Number of Telegram Stars that must be paid @@ -495,6 +505,18 @@ class UniqueGiftInfo(TelegramObject): paid for the gift. .. versionadded:: 22.3 + .. deprecated:: NEXT.VERSION + Bot API 9.3 deprecated this field. Use :attr:`last_resale_currency` and + :attr:`last_resale_amount` instead. + last_resale_currency (:obj:`str`, optional): For gifts bought from other users, the + currency in which the payment for the gift was done. Currently, one of ``XTR`` for + Telegram Stars or ``TON`` for toncoins. + + .. versionadded:: NEXT.VERSION + last_resale_amount (:obj:`int`, optional): For gifts bought from other users, the price + paid for the gift in either Telegram Stars or nanotoncoins. + + .. versionadded:: NEXT.VERSION next_transfer_date (:obj:`datetime.datetime`, optional): Date when the gift can be transferred. If it's in the past, then the gift can be transferred now. |datetime_localization| @@ -505,18 +527,27 @@ class UniqueGiftInfo(TelegramObject): gift (:class:`UniqueGift`): Information about the gift. origin (:obj:`str`): Origin of the gift. Currently, either :attr:`UPGRADE` for gifts upgraded from regular gifts, :attr:`TRANSFER` for gifts transferred from other users - or channels, or :attr:`RESALE` for gifts bought from other users. + or channels, :attr:`RESALE` for gifts bought from other users, + :attr:`GIFTED_UPGRADE` for upgrades purchased after the gift was sent, or :attr:`OFFER` + for gifts bought or sold through gift purchase offers .. versionchanged:: 22.3 The :attr:`RESALE` origin was added. + .. versionchanged:: NEXT.VERSION + Bot API 9.3 added the :attr:`GIFTED_UPGRADE` and :attr:`OFFER` origins. owned_gift_id (:obj:`str`) Optional. Unique identifier of the received gift for the bot; only present for gifts received on behalf of business accounts. transfer_star_count (:obj:`int`): Optional. Number of Telegram Stars that must be paid to transfer the gift; omitted if the bot cannot transfer the gift. - last_resale_star_count (:obj:`int`): Optional. For gifts bought from other users, the price - paid for the gift. + last_resale_currency (:obj:`str`): Optional. For gifts bought from other users, the + currency in which the payment for the gift was done. Currently, one of ``XTR`` for + Telegram Stars or ``TON`` for toncoins. - .. versionadded:: 22.3 + .. versionadded:: NEXT.VERSION + last_resale_amount (:obj:`int`): Optional. For gifts bought from other users, the price + paid for the gift in either Telegram Stars or nanotoncoins. + + .. versionadded:: NEXT.VERSION next_transfer_date (:obj:`datetime.datetime`): Optional. Date when the gift can be transferred. If it's in the past, then the gift can be transferred now. |datetime_localization| @@ -524,19 +555,31 @@ class UniqueGiftInfo(TelegramObject): .. versionadded:: 22.3 """ - UPGRADE: Final[str] = constants.UniqueGiftInfoOrigin.UPGRADE - """:const:`telegram.constants.UniqueGiftInfoOrigin.UPGRADE`""" - TRANSFER: Final[str] = constants.UniqueGiftInfoOrigin.TRANSFER - """:const:`telegram.constants.UniqueGiftInfoOrigin.TRANSFER`""" + GIFTED_UPGRADE: Final[str] = constants.UniqueGiftInfoOrigin.GIFTED_UPGRADE + """:const:`telegram.constants.UniqueGiftInfoOrigin.GIFTED_UPGRADE` + + .. versionadded:: NEXT.VERSION + """ + OFFER: Final[str] = constants.UniqueGiftInfoOrigin.OFFER + """:const:`telegram.constants.UniqueGiftInfoOrigin.OFFER` + + .. versionadded:: NEXT.VERSION + """ RESALE: Final[str] = constants.UniqueGiftInfoOrigin.RESALE """:const:`telegram.constants.UniqueGiftInfoOrigin.RESALE` .. versionadded:: 22.3 """ + TRANSFER: Final[str] = constants.UniqueGiftInfoOrigin.TRANSFER + """:const:`telegram.constants.UniqueGiftInfoOrigin.TRANSFER`""" + UPGRADE: Final[str] = constants.UniqueGiftInfoOrigin.UPGRADE + """:const:`telegram.constants.UniqueGiftInfoOrigin.UPGRADE`""" __slots__ = ( + "_last_resale_star_count", "gift", - "last_resale_star_count", + "last_resale_amount", + "last_resale_currency", "next_transfer_date", "origin", "owned_gift_id", @@ -549,11 +592,28 @@ def __init__( origin: str, owned_gift_id: str | None = None, transfer_star_count: int | None = None, + # tags: deprecated NEXT.VERSION; bot api 9.3 last_resale_star_count: int | None = None, next_transfer_date: dtm.datetime | None = None, + last_resale_currency: str | None = None, + last_resale_amount: int | None = None, *, api_kwargs: JSONDict | None = None, ): + if last_resale_star_count is not None: + warn( + PTBDeprecationWarning( + version="NEXT.VERSION", + message=build_deprecation_warning_message( + deprecated_name="last_resale_star_count", + new_name="last_resale_currency/amount", + bot_api_version="9.3", + object_type="parameter", + ), + ), + stacklevel=2, + ) + super().__init__(api_kwargs=api_kwargs) # Required self.gift: UniqueGift = gift @@ -561,13 +621,34 @@ def __init__( # Optional self.owned_gift_id: str | None = owned_gift_id self.transfer_star_count: int | None = transfer_star_count - self.last_resale_star_count: int | None = last_resale_star_count + self._last_resale_star_count: int | None = last_resale_star_count self.next_transfer_date: dtm.datetime | None = next_transfer_date + self.last_resale_currency: str | None = last_resale_currency + self.last_resale_amount: int | None = last_resale_amount self._id_attrs = (self.gift, self.origin) self._freeze() + # tags: deprecated NEXT.VERSION; bot api 9.3 + @property + def last_resale_star_count(self) -> int | None: + """:obj:`int`: Optional. For gifts bought from other users, the price + paid for the gift. + + .. versionadded:: 22.3 + .. deprecated:: NEXT.VERSION + Bot API 9.3 deprecated this field. Use :attr:`last_resale_currency` and + :attr:`last_resale_amount` instead. + """ + warn_about_deprecated_attr_in_property( + deprecated_attr_name="last_resale_star_count", + new_attr_name="last_resale_currency/amount", + bot_api_version="9.3", + ptb_version="NEXT.VERSION", + ) + return self._last_resale_star_count + @classmethod def de_json(cls, data: JSONDict, bot: "Bot | None" = None) -> "UniqueGiftInfo": """See :meth:`telegram.TelegramObject.de_json`.""" diff --git a/src/telegram/constants.py b/src/telegram/constants.py index 5d8dd790dea..08cc435a11b 100644 --- a/src/telegram/constants.py +++ b/src/telegram/constants.py @@ -3348,15 +3348,25 @@ class UniqueGiftInfoOrigin(StringEnum): __slots__ = () - UPGRADE = "upgrade" - """:obj:`str` gift upgraded""" - TRANSFER = "transfer" - """:obj:`str` gift transfered""" + GIFTED_UPGRADE = "gifted_upgrade" + """:obj:`str` upgrades purchased after the gift was sent + + .. versionadded:: NEXT.VERSION + """ + OFFER = "OFFER" + """:obj:`str` gift bought or sold through gift purchase offers + + .. versionadded:: NEXT.VERSION + """ RESALE = "resale" """:obj:`str` gift bought from other users .. versionadded:: 22.3 """ + TRANSFER = "transfer" + """:obj:`str` gift transfered""" + UPGRADE = "upgrade" + """:obj:`str` gift upgraded""" class UpdateType(StringEnum): diff --git a/tests/test_uniquegift.py b/tests/test_uniquegift.py index 73c753beb51..84e6816bfad 100644 --- a/tests/test_uniquegift.py +++ b/tests/test_uniquegift.py @@ -35,6 +35,7 @@ ) from telegram._utils.datetime import UTC, to_timestamp from telegram.constants import UniqueGiftInfoOrigin +from telegram.warnings import PTBDeprecationWarning from tests.auxil.slots import mro_slots @@ -524,6 +525,8 @@ def unique_gift_info(): owned_gift_id=UniqueGiftInfoTestBase.owned_gift_id, transfer_star_count=UniqueGiftInfoTestBase.transfer_star_count, last_resale_star_count=UniqueGiftInfoTestBase.last_resale_star_count, + last_resale_currency=UniqueGiftInfoTestBase.last_resale_currency, + last_resale_amount=UniqueGiftInfoTestBase.last_resale_amount, next_transfer_date=UniqueGiftInfoTestBase.next_transfer_date, ) @@ -554,6 +557,8 @@ class UniqueGiftInfoTestBase: owned_gift_id = "some_id" transfer_star_count = 10 last_resale_star_count = 5 + last_resale_currency = "XTR" + last_resale_amount = 1234 next_transfer_date = dtm.datetime.now(tz=UTC).replace(microsecond=0) @@ -572,6 +577,8 @@ def test_de_json(self, offline_bot): "owned_gift_id": self.owned_gift_id, "transfer_star_count": self.transfer_star_count, "last_resale_star_count": self.last_resale_star_count, + "last_resale_currency": self.last_resale_currency, + "last_resale_amount": self.last_resale_amount, "next_transfer_date": to_timestamp(self.next_transfer_date), } unique_gift_info = UniqueGiftInfo.de_json(json_dict, offline_bot) @@ -581,6 +588,8 @@ def test_de_json(self, offline_bot): assert unique_gift_info.owned_gift_id == self.owned_gift_id assert unique_gift_info.transfer_star_count == self.transfer_star_count assert unique_gift_info.last_resale_star_count == self.last_resale_star_count + assert unique_gift_info.last_resale_currency == self.last_resale_currency + assert unique_gift_info.last_resale_amount == self.last_resale_amount assert unique_gift_info.next_transfer_date == self.next_transfer_date def test_de_json_localization(self, tz_bot, offline_bot, raw_bot): @@ -590,6 +599,8 @@ def test_de_json_localization(self, tz_bot, offline_bot, raw_bot): "owned_gift_id": self.owned_gift_id, "transfer_star_count": self.transfer_star_count, "last_resale_star_count": self.last_resale_star_count, + "last_resale_currency": self.last_resale_currency, + "last_resale_amount": self.last_resale_amount, "next_transfer_date": to_timestamp(self.next_transfer_date), } @@ -613,7 +624,8 @@ def test_to_dict(self, unique_gift_info): assert json_dict["origin"] == self.origin assert json_dict["owned_gift_id"] == self.owned_gift_id assert json_dict["transfer_star_count"] == self.transfer_star_count - assert json_dict["last_resale_star_count"] == self.last_resale_star_count + assert json_dict["last_resale_currency"] == self.last_resale_currency + assert json_dict["last_resale_amount"] == self.last_resale_amount assert json_dict["next_transfer_date"] == to_timestamp(self.next_transfer_date) def test_enum_type_conversion(self, unique_gift_info): @@ -636,3 +648,21 @@ def test_equality(self, unique_gift_info): assert a != d assert hash(a) != hash(d) + + def test_last_resale_star_count_argument_deprecation(self): + with pytest.warns(PTBDeprecationWarning, match=r"9\.3.*last_resale_star_count") as record: + UniqueGiftInfo( + gift=self.gift, + origin=UniqueGiftInfo.TRANSFER, + last_resale_star_count=self.last_resale_star_count, + ) + + assert record[0].category == PTBDeprecationWarning + assert record[0].filename == __file__, "wrong stacklevel!" + + def test_last_resale_star_count_attribute_deprecation(self, unique_gift_info): + with pytest.warns(PTBDeprecationWarning, match=r"9\.3.*last_resale_star_count") as record: + assert unique_gift_info.last_resale_star_count == self.last_resale_star_count + + assert record[0].category == PTBDeprecationWarning + assert record[0].filename == __file__, "wrong stacklevel!"