Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changes/unreleased/5078.FoNwUYLbXQFRebTFhR6UPn.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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"] },
]
103 changes: 92 additions & 11 deletions src/telegram/_uniquegift.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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|
Expand All @@ -505,38 +527,59 @@ 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|

.. 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",
Expand All @@ -549,25 +592,63 @@ 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
self.origin: str = enum.get_member(constants.UniqueGiftInfoOrigin, origin, origin)
# 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`."""
Expand Down
18 changes: 14 additions & 4 deletions src/telegram/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
32 changes: 31 additions & 1 deletion tests/test_uniquegift.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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,
)

Expand Down Expand Up @@ -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)


Expand All @@ -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)
Expand All @@ -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):
Expand All @@ -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),
}

Expand All @@ -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):
Expand All @@ -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!"
Loading