Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Usetimedelta to represent time periods in classes#4750

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
aelkheir wants to merge14 commits intomaster
base:master
Choose a base branch
Loading
fromfeature/4575-timedelta-classes
Open
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
14 commits
Select commitHold shift + click to select a range
40d354a
Setup helper functions and a common test fixture.
aelkheirApr 8, 2025
5cd6507
Accept timedeltas in params of `ChatFullInfo`.
aelkheirApr 8, 2025
a3b340b
Add chango fragment for PR #4750
aelkheirApr 9, 2025
d60b9fe
Refactor `test_chatfullinfo.py` a bit.
aelkheirApr 9, 2025
d4d62ce
Oops, so many white spaces.
aelkheirApr 9, 2025
3084d3b
Finish up `ChatFullInfo` plus some helper tweaks.
aelkheirApr 11, 2025
8d48756
Modify ``docs/substitutions/global.rst``.
aelkheirApr 11, 2025
8ef4ca9
Accept timedeltas in ``duration`` param of media classes.
aelkheirApr 12, 2025
28af9f7
Undeprecate passing `ints` to classes' arguments.
aelkheirMay 15, 2025
319dd6c
Accept timedeltas in params of `InlineQueryResult.*` classes.
aelkheirMay 16, 2025
d8dbe15
Accept timedeltas in other time period params.
aelkheirMay 17, 2025
caa831b
Modify test_official to handle time periods as timedelta automatically.
aelkheirMay 17, 2025
881a9f6
Accept timedeltas in Bot.get_updates.timeout.
aelkheirMay 17, 2025
466e0b0
Elaborate chango fragment for PR.
aelkheirMay 17, 2025
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
35 changes: 35 additions & 0 deletionschanges/unreleased/4750.jJBu7iAgZa96hdqcpHK96W.toml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
features ="Use `timedelta` to represent time periods in classes"
deprecations ="""In this release, we're migrating attributes that represent durations/time periods from :ob:`int` type to Python's native :class:`datetime.timedelta`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
deprecations ="""In this release, we're migrating attributes that represent durations/time periods from :ob:`int` type to Python's native :class:`datetime.timedelta`.
deprecations ="""In this release, we're migrating attributes that represent durations/time periods from :obj:`int` type to Python's native :class:`datetime.timedelta`.

Enable the ``PTB_TIMEDELTA`` environment variable to adopt :obj:`timedelta` now. Support for :obj:`int` values is deprecated and will be removed in a future major version.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
Enable the ``PTB_TIMEDELTA`` environment variable to adopt :obj:`timedelta` now. Support for :obj:`int` values is deprecated and will be removed in a future major version.
Set the ``PTB_TIMEDELTA=1`` environment variable to adopt :obj:`timedelta` now. Support for :obj:`int` values is deprecated and will be removed in a future major version.

it's not clear to me what happens when you set the env variable, are timedelta objects returned? If that's the case, the release note should mention that.

Affected Attributes:
- :attr:`telegram.ChatFullInfo.slow_mode_delay` and :attr:`telegram.ChatFullInfo.message_auto_delete_time`
- :attr:`telegram.Animation.duration`
- :attr:`telegram.Audio.duration`
- :attr:`telegram.Video.duration` and :attr:`telegram.Video.start_timestamp`
- :attr:`telegram.VideoNote.duration`
- :attr:`telegram.Voice.duration`
- :attr:`telegram.PaidMediaPreview.duration`
- :attr:`telegram.VideoChatEnded.duration`
- :attr:`telegram.InputMediaVideo.duration`
- :attr:`telegram.InputMediaAnimation.duration`
- :attr:`telegram.InputMediaAudio.duration`
- :attr:`telegram.InputPaidMediaVideo.duration`
- :attr:`telegram.InlineQueryResultGif.gif_duration`
- :attr:`telegram.InlineQueryResultMpeg4Gif.mpeg4_duration`
- :attr:`telegram.InlineQueryResultVideo.video_duration`
- :attr:`telegram.InlineQueryResultAudio.audio_duration`
- :attr:`telegram.InlineQueryResultVoice.voice_duration`
- :attr:`telegram.InlineQueryResultLocation.live_period`
- :attr:`telegram.Poll.open_period`
- :attr:`telegram.Location.live_period`
- :attr:`telegram.MessageAutoDeleteTimerChanged.message_auto_delete_time`
- :attr:`telegram.ChatInviteLink.subscription_period`
- :attr:`telegram.InputLocationMessageContent.live_period`
"""
internal ="Modify test_official to handle time periods as timedelta automatically."
[[pull_requests]]
uid ="4750"
author_uid ="aelkheir"
closes_threads = ["4575"]
2 changes: 2 additions & 0 deletionsdocs/substitutions/global.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -101,3 +101,5 @@
.. |org-verify| replace:: `on behalf of the organization <https://telegram.org/verify#third-party-verification>`__

.. |time-period-input| replace:: :class:`datetime.timedelta` objects are accepted in addition to plain :obj:`int` values.

.. |time-period-int-deprecated| replace:: In a future major version this will be of type :obj:`datetime.timedelta`. You can opt-in early by setting the `PTB_TIMEDELTA` environment variable.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
.. |time-period-int-deprecated|replace:: In a future major version this will be of type:obj:`datetime.timedelta`. You can opt-in early by settingthe`PTB_TIMEDELTA` environment variable.
.. |time-period-int-deprecated|replace:: In a future major version this will be of type:obj:`datetime.timedelta`. You can opt-in early by setting `PTB_TIMEDELTA=1` as an environment variable.

5 changes: 4 additions & 1 deletionexamples/rawapibot.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,7 @@
"""
import asyncio
import contextlib
import datetime as dtm
import logging
from typing import NoReturn

Expand DownExpand Up@@ -47,7 +48,9 @@ async def main() -> NoReturn:
async def echo(bot: Bot, update_id: int) -> int:
"""Echo the message the user sent."""
# Request updates after the last update_id
updates = await bot.get_updates(offset=update_id, timeout=10, allowed_updates=Update.ALL_TYPES)
updates = await bot.get_updates(
offset=update_id, timeout=dtm.timedelta(seconds=10), allowed_updates=Update.ALL_TYPES
)
for update in updates:
next_update_id = update.update_id + 1

Expand Down
19 changes: 14 additions & 5 deletionstelegram/_bot.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4519,7 +4519,7 @@ async def get_updates(
self,
offset:Optional[int]=None,
limit:Optional[int]=None,
timeout:Optional[int]=None,
timeout:Optional[TimePeriod]=None,
allowed_updates:Optional[Sequence[str]]=None,
*,
read_timeout:ODVInput[float]=DEFAULT_NONE,
Expand DownExpand Up@@ -4554,9 +4554,12 @@ async def get_updates(
between :tg-const:`telegram.constants.PollingLimit.MIN_LIMIT`-
:tg-const:`telegram.constants.PollingLimit.MAX_LIMIT` are accepted.
Defaults to ``100``.
timeout (:obj:`int`, optional): Timeout in seconds for long polling. Defaults to ``0``,
i.e. usual short polling. Should be positive, short polling should be used for
testing purposes only.
timeout (:obj:`int` | :class:`datetime.timedelta`, optional): Timeout in seconds for
long polling. Defaults to ``0``, i.e. usual short polling. Should be positive,
short polling should be used for testing purposes only.
.. versionchanged:: NEXT.VERSION
|time-period-input|
allowed_updates (Sequence[:obj:`str`]), optional): A sequence the types of
updates you want your bot to receive. For example, specify ["message",
"edited_channel_post", "callback_query"] to only receive updates of these types.
Expand DownExpand Up@@ -4591,6 +4594,12 @@ async def get_updates(
else:
arg_read_timeout=self._request[0].read_timeoutor0

read_timeout= (
(arg_read_timeout+timeout.total_seconds())
ifisinstance(timeout,dtm.timedelta)
else (arg_read_timeout+timeoutifisinstance(timeout,int)elsearg_read_timeout)
)
Comment on lines +4597 to +4601
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
read_timeout= (
(arg_read_timeout+timeout.total_seconds())
ifisinstance(timeout,dtm.timedelta)
else (arg_read_timeout+timeoutifisinstance(timeout,int)elsearg_read_timeout)
)
read_timeout= (
(arg_read_timeout+timeout.total_seconds())
ifisinstance(timeout,dtm.timedelta)
else (arg_read_timeout+timeoutiftimeoutelsearg_read_timeout)
)

ah I don't think I've ever seen nested ternary if statements in python haha. Regarding the change, we should check for truthiness oftimeout like before, because your case didn't cover if timeout was a float.


# Ideally we'd use an aggressive read timeout for the polling. However,
# * Short polling should return within 2 seconds.
# * Long polling poses a different problem: the connection might have been dropped while
Expand All@@ -4601,7 +4610,7 @@ async def get_updates(
awaitself._post(
"getUpdates",
data,
read_timeout=arg_read_timeout+timeoutiftimeoutelsearg_read_timeout,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
Expand Down
94 changes: 75 additions & 19 deletionstelegram/_chatfullinfo.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,7 +20,7 @@
"""This module contains an object that represents a Telegram ChatFullInfo."""
import datetime as dtm
from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, Optional, Union

from telegram._birthdate import Birthdate
from telegram._chat import Chat, _ChatBase
Expand All@@ -29,9 +29,18 @@
from telegram._files.chatphoto import ChatPhoto
from telegram._gifts import AcceptedGiftTypes
from telegram._reaction import ReactionType
from telegram._utils.argumentparsing import de_json_optional, de_list_optional, parse_sequence_arg
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.types import JSONDict
from telegram._utils.argumentparsing import (
de_json_optional,
de_list_optional,
parse_period_arg,
parse_sequence_arg,
)
from telegram._utils.datetime import (
extract_tzinfo_from_defaults,
from_timestamp,
get_timedelta_value,
)
from telegram._utils.types import JSONDict, TimePeriod
from telegram._utils.warnings import warn
from telegram._utils.warnings_transition import (
build_deprecation_warning_message,
Expand DownExpand Up@@ -166,17 +175,23 @@ class ChatFullInfo(_ChatBase):
(by sending date).
permissions (:class:`telegram.ChatPermissions`): Optional. Default chat member permissions,
for groups and supergroups.
slow_mode_delay (:obj:`int`, optional): For supergroups, the minimum allowed delay between
consecutive messages sent by each unprivileged user.
slow_mode_delay (:obj:`int` | :class:`datetime.timedelta`, optional): For supergroups,
the minimum allowed delay between consecutive messages sent by each unprivileged user.

.. versionchanged:: NEXT.VERSION
|time-period-input|
unrestrict_boost_count (:obj:`int`, optional): For supergroups, the minimum number of
boosts that a non-administrator user needs to add in order to ignore slow mode and chat
permissions.

.. versionadded:: 21.0
message_auto_delete_time (:obj:`int`, optional): The time after which all messages sent to
the chat will be automatically deleted; in seconds.
message_auto_delete_time (:obj:`int` | :class:`datetime.timedelta`, optional): The time
after which all messages sent tothe chat will be automatically deleted; in seconds.

.. versionadded:: 13.4

.. versionchanged:: NEXT.VERSION
|time-period-input|
has_aggressive_anti_spam_enabled (:obj:`bool`, optional): :obj:`True`, if aggressive
anti-spam checks are enabled in the supergroup. The field is only available to chat
administrators.
Expand DownExpand Up@@ -331,17 +346,23 @@ class ChatFullInfo(_ChatBase):
(by sending date).
permissions (:class:`telegram.ChatPermissions`): Optional. Default chat member permissions,
for groups and supergroups.
slow_mode_delay (:obj:`int`): Optional. For supergroups, the minimum allowed delay between
consecutive messages sent by each unprivileged user.
slow_mode_delay (:obj:`int` | :class:`datetime.timedelta`): Optional. For supergroups,
the minimum allowed delay between consecutive messages sent by each unprivileged user.

.. deprecated:: NEXT.VERSION
|time-period-int-deprecated|
unrestrict_boost_count (:obj:`int`): Optional. For supergroups, the minimum number of
boosts that a non-administrator user needs to add in order to ignore slow mode and chat
permissions.

.. versionadded:: 21.0
message_auto_delete_time (:obj:`int`): Optional. The time after which all messages sent to
the chat will be automatically deleted; in seconds.
message_auto_delete_time (:obj:`int` | :class:`datetime.timedelta`): Optional. The time
after which all messages sent tothe chat will be automatically deleted; in seconds.

.. versionadded:: 13.4

.. deprecated:: NEXT.VERSION
|time-period-int-deprecated|
has_aggressive_anti_spam_enabled (:obj:`bool`): Optional. :obj:`True`, if aggressive
anti-spam checks are enabled in the supergroup. The field is only available to chat
administrators.
Expand DownExpand Up@@ -383,6 +404,8 @@ class ChatFullInfo(_ChatBase):

__slots__ = (
"_can_send_gift",
"_message_auto_delete_time",
"_slow_mode_delay",
"accent_color_id",
"accepted_gift_types",
"active_usernames",
Expand DownExpand Up@@ -411,14 +434,12 @@ class ChatFullInfo(_ChatBase):
"linked_chat_id",
"location",
"max_reaction_count",
"message_auto_delete_time",
"permissions",
"personal_chat",
"photo",
"pinned_message",
"profile_accent_color_id",
"profile_background_custom_emoji_id",
"slow_mode_delay",
"sticker_set_name",
"unrestrict_boost_count",
)
Expand DownExpand Up@@ -456,9 +477,9 @@ def __init__(
invite_link: Optional[str] = None,
pinned_message: Optional["Message"] = None,
permissions: Optional[ChatPermissions] = None,
slow_mode_delay: Optional[int] = None,
slow_mode_delay: Optional[TimePeriod] = None,
unrestrict_boost_count: Optional[int] = None,
message_auto_delete_time: Optional[int] = None,
message_auto_delete_time: Optional[TimePeriod] = None,
has_aggressive_anti_spam_enabled: Optional[bool] = None,
has_hidden_members: Optional[bool] = None,
has_protected_content: Optional[bool] = None,
Expand DownExpand Up@@ -513,9 +534,9 @@ def __init__(
self.invite_link: Optional[str] = invite_link
self.pinned_message: Optional[Message] = pinned_message
self.permissions: Optional[ChatPermissions] = permissions
self.slow_mode_delay: Optional[int] = slow_mode_delay
self.message_auto_delete_time: Optional[int] = (
int(message_auto_delete_time) if message_auto_delete_time is not None else None
self._slow_mode_delay: Optional[dtm.timedelta] =parse_period_arg(slow_mode_delay)
self._message_auto_delete_time: Optional[dtm.timedelta] =parse_period_arg(
message_auto_delete_time
)
self.has_protected_content: Optional[bool] = has_protected_content
self.has_visible_history: Optional[bool] = has_visible_history
Expand DownExpand Up@@ -576,6 +597,20 @@ def can_send_gift(self) -> Optional[bool]:
)
return self._can_send_gift

@property
def slow_mode_delay(self) -> Optional[Union[int, dtm.timedelta]]:
value = get_timedelta_value(self._slow_mode_delay)
if isinstance(value, float) and value.is_integer():
value = int(value)
return value # type: ignore[return-value]

@property
def message_auto_delete_time(self) -> Optional[Union[int, dtm.timedelta]]:
value = get_timedelta_value(self._message_auto_delete_time)
if isinstance(value, float) and value.is_integer():
value = int(value)
return value # type: ignore[return-value]

@classmethod
def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "ChatFullInfo":
"""See :meth:`telegram.TelegramObject.de_json`."""
Expand All@@ -600,6 +635,13 @@ def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "ChatFullInfo":
Message,
)

data["slow_mode_delay"] = (
dtm.timedelta(seconds=s) if (s := data.get("slow_mode_delay")) else None
)
data["message_auto_delete_time"] = (
dtm.timedelta(seconds=s) if (s := data.get("message_auto_delete_time")) else None
)

data["pinned_message"] = de_json_optional(data.get("pinned_message"), Message, bot)
data["permissions"] = de_json_optional(data.get("permissions"), ChatPermissions, bot)
data["location"] = de_json_optional(data.get("location"), ChatLocation, bot)
Expand All@@ -617,3 +659,17 @@ def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "ChatFullInfo":
)

return super().de_json(data=data, bot=bot)

def to_dict(self, recursive: bool = True) -> JSONDict:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ah can't this be modified intelegramobject.py only?

"""See :meth:`telegram.TelegramObject.to_dict`."""
out = super().to_dict(recursive)

keys = ("slow_mode_delay", "message_auto_delete_time")
for key in keys:
if (value := getattr(self, "_" + key)) is not None:
seconds = value.total_seconds()
out[key] = int(seconds) if seconds.is_integer() else seconds
elif not recursive:
out[key] = value

return out
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp