mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-12-28 07:20:17 +01:00
Add JobQueue.scheduler_configuration
and Corresponding Warnings (#3913)
This commit is contained in:
parent
af130ef5e7
commit
f67e8c0804
2 changed files with 64 additions and 10 deletions
|
@ -76,6 +76,17 @@ class JobQueue(Generic[CCT]):
|
|||
Attributes:
|
||||
scheduler (:class:`apscheduler.schedulers.asyncio.AsyncIOScheduler`): The scheduler.
|
||||
|
||||
Warning:
|
||||
This scheduler is configured by :meth:`set_application`. Additional configuration
|
||||
settings can be made by users. However, calling
|
||||
:meth:`~apscheduler.schedulers.base.BaseScheduler.configure` will delete any
|
||||
previous configuration settings. Therefore, please make sure to pass the values
|
||||
returned by :attr:`scheduler_configuration` to the method call in addition to your
|
||||
custom values.
|
||||
Alternatively, you can also use methods like
|
||||
:meth:`~apscheduler.schedulers.base.BaseScheduler.add_jobstore` to avoid using
|
||||
:meth:`~apscheduler.schedulers.base.BaseScheduler.configure` altogether.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
Uses :class:`~apscheduler.schedulers.asyncio.AsyncIOScheduler` instead of
|
||||
:class:`~apscheduler.schedulers.background.BackgroundScheduler`
|
||||
|
@ -94,9 +105,7 @@ class JobQueue(Generic[CCT]):
|
|||
|
||||
self._application: Optional[weakref.ReferenceType[Application]] = None
|
||||
self._executor = AsyncIOExecutor()
|
||||
self.scheduler: AsyncIOScheduler = AsyncIOScheduler(
|
||||
timezone=pytz.utc, executors={"default": self._executor}
|
||||
)
|
||||
self.scheduler: AsyncIOScheduler = AsyncIOScheduler(**self.scheduler_configuration)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""Give a string representation of the JobQueue in the form ``JobQueue[application=...]``.
|
||||
|
@ -119,6 +128,43 @@ class JobQueue(Generic[CCT]):
|
|||
return application
|
||||
raise RuntimeError("The application instance is no longer alive.")
|
||||
|
||||
@property
|
||||
def scheduler_configuration(self) -> JSONDict:
|
||||
"""Provides configuration values that are used by :class:`JobQueue` for :attr:`scheduler`.
|
||||
|
||||
Tip:
|
||||
Since calling
|
||||
:meth:`scheduler.configure() <apscheduler.schedulers.base.BaseScheduler.configure>`
|
||||
deletes any previous setting, please make sure to pass these values to the method call
|
||||
in addition to your custom values:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
scheduler.configure(..., **job_queue.scheduler_configuration)
|
||||
|
||||
Alternatively, you can also use methods like
|
||||
:meth:`~apscheduler.schedulers.base.BaseScheduler.add_jobstore` to avoid using
|
||||
:meth:`~apscheduler.schedulers.base.BaseScheduler.configure` altogether.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
Dict[:obj:`str`, :obj:`object`]: The configuration values as dictionary.
|
||||
|
||||
"""
|
||||
timezone: object = pytz.utc
|
||||
if (
|
||||
self._application
|
||||
and isinstance(self.application.bot, ExtBot)
|
||||
and self.application.bot.defaults
|
||||
):
|
||||
timezone = self.application.bot.defaults.tzinfo or pytz.utc
|
||||
|
||||
return {
|
||||
"timezone": timezone,
|
||||
"executors": {"default": self._executor},
|
||||
}
|
||||
|
||||
def _tz_now(self) -> datetime.datetime:
|
||||
return datetime.datetime.now(self.scheduler.timezone)
|
||||
|
||||
|
@ -166,11 +212,7 @@ class JobQueue(Generic[CCT]):
|
|||
|
||||
"""
|
||||
self._application = weakref.ref(application)
|
||||
if isinstance(application.bot, ExtBot) and application.bot.defaults:
|
||||
self.scheduler.configure(
|
||||
timezone=application.bot.defaults.tzinfo or pytz.utc,
|
||||
executors={"default": self._executor},
|
||||
)
|
||||
self.scheduler.configure(**self.scheduler_configuration)
|
||||
|
||||
@staticmethod
|
||||
async def job_callback(job_queue: "JobQueue[CCT]", job: "Job[CCT]") -> None:
|
||||
|
|
|
@ -25,7 +25,7 @@ import time
|
|||
|
||||
import pytest
|
||||
|
||||
from telegram.ext import ApplicationBuilder, CallbackContext, ContextTypes, Job, JobQueue
|
||||
from telegram.ext import ApplicationBuilder, CallbackContext, ContextTypes, Defaults, Job, JobQueue
|
||||
from telegram.warnings import PTBUserWarning
|
||||
from tests.auxil.envvars import GITHUB_ACTION, TEST_WITH_OPT_DEPS
|
||||
from tests.auxil.pytest_classes import make_bot
|
||||
|
@ -106,6 +106,15 @@ class TestJobQueue:
|
|||
self.job_time = 0
|
||||
self.received_error = None
|
||||
|
||||
def test_scheduler_configuration(self, job_queue, timezone, bot):
|
||||
# Unfortunately, we can't really test the executor setting explicitly without relying
|
||||
# on protected attributes. However, this should be tested enough implicitly via all the
|
||||
# other tests in here
|
||||
assert job_queue.scheduler_configuration["timezone"] is UTC
|
||||
|
||||
tz_app = ApplicationBuilder().defaults(Defaults(tzinfo=timezone)).token(bot.token).build()
|
||||
assert tz_app.job_queue.scheduler_configuration["timezone"] is timezone
|
||||
|
||||
async def job_run_once(self, context):
|
||||
if (
|
||||
isinstance(context, CallbackContext)
|
||||
|
@ -578,7 +587,7 @@ class TestJobQueue:
|
|||
assert rec.name == "telegram.ext.Application"
|
||||
assert "No error handlers are registered" in rec.getMessage()
|
||||
|
||||
async def test_custom_context(self, bot, job_queue):
|
||||
async def test_custom_context(self, bot):
|
||||
application = (
|
||||
ApplicationBuilder()
|
||||
.token(bot.token)
|
||||
|
@ -589,6 +598,7 @@ class TestJobQueue:
|
|||
)
|
||||
.build()
|
||||
)
|
||||
job_queue = JobQueue()
|
||||
job_queue.set_application(application)
|
||||
|
||||
async def callback(context):
|
||||
|
@ -599,9 +609,11 @@ class TestJobQueue:
|
|||
type(context.bot_data),
|
||||
)
|
||||
|
||||
await job_queue.start()
|
||||
job_queue.run_once(callback, 0.1)
|
||||
await asyncio.sleep(0.15)
|
||||
assert self.result == (CustomContext, None, None, int)
|
||||
await job_queue.stop()
|
||||
|
||||
async def test_attribute_error(self):
|
||||
job = Job(self.job_run_once)
|
||||
|
|
Loading…
Reference in a new issue