mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-12-22 06:25:12 +01:00
Align Behavior Of JobQueue.run_daily
With cron
(#3046)
This commit is contained in:
parent
5e24765bbc
commit
349baa0202
2 changed files with 43 additions and 3 deletions
|
@ -28,6 +28,7 @@ from apscheduler.job import Job as APSJob
|
|||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram.ext._extbot import ExtBot
|
||||
from telegram.ext._utils.types import JobCallback
|
||||
|
||||
|
@ -50,6 +51,7 @@ class JobQueue:
|
|||
"""
|
||||
|
||||
__slots__ = ("_application", "scheduler", "_executor")
|
||||
_CRON_MAPPING = ("sun", "mon", "tue", "wed", "thu", "fri", "sat")
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._application: "Optional[weakref.ReferenceType[Application]]" = None
|
||||
|
@ -419,7 +421,11 @@ class JobQueue:
|
|||
(:obj:`datetime.time.tzinfo`) is :obj:`None`, the default timezone of the bot will
|
||||
be used.
|
||||
days (Tuple[:obj:`int`], optional): Defines on which days of the week the job should
|
||||
run (where ``0-6`` correspond to monday - sunday). Defaults to ``EVERY_DAY``
|
||||
run (where ``0-6`` correspond to sunday - saturday). By default, the job will run
|
||||
every day.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
Changed day of the week mapping of 0-6 from monday-sunday to sunday-saturday.
|
||||
data (:obj:`object`, optional): Additional data needed for the callback function.
|
||||
Can be accessed through :attr:`Job.data` in the callback. Defaults to
|
||||
:obj:`None`.
|
||||
|
@ -447,6 +453,12 @@ class JobQueue:
|
|||
queue.
|
||||
|
||||
"""
|
||||
# TODO: After v20.0, we should remove the this warning.
|
||||
warn(
|
||||
"Prior to v20.0 the `days` parameter was not aligned to that of cron's weekday scheme."
|
||||
"We recommend double checking if the passed value is correct.",
|
||||
stacklevel=2,
|
||||
)
|
||||
if not job_kwargs:
|
||||
job_kwargs = {}
|
||||
|
||||
|
@ -458,7 +470,7 @@ class JobQueue:
|
|||
name=name,
|
||||
args=(self.application,),
|
||||
trigger="cron",
|
||||
day_of_week=",".join([str(d) for d in days]),
|
||||
day_of_week=",".join([self._CRON_MAPPING[d] for d in days]),
|
||||
hour=time.hour,
|
||||
minute=time.minute,
|
||||
second=time.second,
|
||||
|
|
|
@ -303,7 +303,11 @@ class TestJobQueue:
|
|||
scheduled_time = job_queue.jobs()[0].next_t.timestamp()
|
||||
assert scheduled_time == pytest.approx(expected_time)
|
||||
|
||||
async def test_run_daily(self, job_queue):
|
||||
async def test_run_daily(self, job_queue, recwarn):
|
||||
expected_warning = (
|
||||
"Prior to v20.0 the `days` parameter was not aligned to that of cron's weekday scheme."
|
||||
"We recommend double checking if the passed value is correct."
|
||||
)
|
||||
delta, now = 1, dtm.datetime.now(pytz.utc)
|
||||
time_of_day = (now + dtm.timedelta(seconds=delta)).time()
|
||||
expected_reschedule_time = (now + dtm.timedelta(seconds=delta, days=1)).timestamp()
|
||||
|
@ -313,6 +317,30 @@ class TestJobQueue:
|
|||
assert self.result == 1
|
||||
scheduled_time = job_queue.jobs()[0].next_t.timestamp()
|
||||
assert scheduled_time == pytest.approx(expected_reschedule_time)
|
||||
assert len(recwarn) == 1
|
||||
assert str(recwarn[0].message) == expected_warning
|
||||
assert recwarn[0].filename == __file__, "wrong stacklevel"
|
||||
|
||||
@pytest.mark.parametrize("weekday", (0, 1, 2, 3, 4, 5, 6))
|
||||
async def test_run_daily_days_of_week(self, job_queue, recwarn, weekday):
|
||||
expected_warning = (
|
||||
"Prior to v20.0 the `days` parameter was not aligned to that of cron's weekday scheme."
|
||||
"We recommend double checking if the passed value is correct."
|
||||
)
|
||||
delta, now = 1, dtm.datetime.now(pytz.utc)
|
||||
time_of_day = (now + dtm.timedelta(seconds=delta)).time()
|
||||
# offset in days until next weekday
|
||||
offset = (weekday + 6 - now.weekday()) % 7
|
||||
offset = offset if offset > 0 else 7
|
||||
expected_reschedule_time = (now + dtm.timedelta(seconds=delta, days=offset)).timestamp()
|
||||
|
||||
job_queue.run_daily(self.job_run_once, time_of_day, days=[weekday])
|
||||
await asyncio.sleep(delta + 0.1)
|
||||
scheduled_time = job_queue.jobs()[0].next_t.timestamp()
|
||||
assert scheduled_time == pytest.approx(expected_reschedule_time)
|
||||
assert len(recwarn) == 1
|
||||
assert str(recwarn[0].message) == expected_warning
|
||||
assert recwarn[0].filename == __file__, "wrong stacklevel"
|
||||
|
||||
async def test_run_monthly(self, job_queue, timezone):
|
||||
delta, now = 1, dtm.datetime.now(timezone)
|
||||
|
|
Loading…
Reference in a new issue