mirror of https://github.com/python/cpython
Fix 13245:
sched.scheduler class constructor's timefunc and delayfunct parameters are now optional. scheduler.enter and scheduler.enterabs methods gained a new kwargs parameter. Patch contributed by Matt Mulsow.
This commit is contained in:
parent
ca4f20782e
commit
be55d99b3d
|
@ -14,7 +14,7 @@
|
||||||
The :mod:`sched` module defines a class which implements a general purpose event
|
The :mod:`sched` module defines a class which implements a general purpose event
|
||||||
scheduler:
|
scheduler:
|
||||||
|
|
||||||
.. class:: scheduler(timefunc, delayfunc)
|
.. class:: scheduler(timefunc=time.time, delayfunc=time.sleep)
|
||||||
|
|
||||||
The :class:`scheduler` class defines a generic interface to scheduling events.
|
The :class:`scheduler` class defines a generic interface to scheduling events.
|
||||||
It needs two functions to actually deal with the "outside world" --- *timefunc*
|
It needs two functions to actually deal with the "outside world" --- *timefunc*
|
||||||
|
@ -25,6 +25,9 @@ scheduler:
|
||||||
event is run to allow other threads an opportunity to run in multi-threaded
|
event is run to allow other threads an opportunity to run in multi-threaded
|
||||||
applications.
|
applications.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.3
|
||||||
|
*timefunc* and *delayfunc* parameters are optional.
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
>>> import sched, time
|
>>> import sched, time
|
||||||
|
@ -79,26 +82,38 @@ Scheduler Objects
|
||||||
:class:`scheduler` instances have the following methods and attributes:
|
:class:`scheduler` instances have the following methods and attributes:
|
||||||
|
|
||||||
|
|
||||||
.. method:: scheduler.enterabs(time, priority, action, argument)
|
.. method:: scheduler.enterabs(time, priority, action, argument=[], kwargs={})
|
||||||
|
|
||||||
Schedule a new event. The *time* argument should be a numeric type compatible
|
Schedule a new event. The *time* argument should be a numeric type compatible
|
||||||
with the return value of the *timefunc* function passed to the constructor.
|
with the return value of the *timefunc* function passed to the constructor.
|
||||||
Events scheduled for the same *time* will be executed in the order of their
|
Events scheduled for the same *time* will be executed in the order of their
|
||||||
*priority*.
|
*priority*.
|
||||||
|
|
||||||
Executing the event means executing ``action(*argument)``. *argument* must be a
|
Executing the event means executing ``action(*argument, **kwargs)``.
|
||||||
sequence holding the parameters for *action*.
|
*argument* must be a sequence holding the parameters for *action*.
|
||||||
|
*kwargs* must be a dictionary holding the keyword parameters for *action*.
|
||||||
|
|
||||||
Return value is an event which may be used for later cancellation of the event
|
Return value is an event which may be used for later cancellation of the event
|
||||||
(see :meth:`cancel`).
|
(see :meth:`cancel`).
|
||||||
|
|
||||||
|
.. versionchanged:: 3.3
|
||||||
|
*argument* parameter is optional.
|
||||||
|
|
||||||
.. method:: scheduler.enter(delay, priority, action, argument)
|
.. versionadded:: 3.3
|
||||||
|
*kwargs* parameter was added.
|
||||||
|
|
||||||
|
|
||||||
|
.. method:: scheduler.enter(delay, priority, action, argument=[], kwargs={})
|
||||||
|
|
||||||
Schedule an event for *delay* more time units. Other than the relative time, the
|
Schedule an event for *delay* more time units. Other than the relative time, the
|
||||||
other arguments, the effect and the return value are the same as those for
|
other arguments, the effect and the return value are the same as those for
|
||||||
:meth:`enterabs`.
|
:meth:`enterabs`.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.3
|
||||||
|
*argument* parameter is optional.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
*kwargs* parameter was added.
|
||||||
|
|
||||||
.. method:: scheduler.cancel(event)
|
.. method:: scheduler.cancel(event)
|
||||||
|
|
||||||
|
|
|
@ -572,6 +572,22 @@ should be used. For example, this will send a ``'HEAD'`` request::
|
||||||
|
|
||||||
(:issue:`1673007`)
|
(:issue:`1673007`)
|
||||||
|
|
||||||
|
sched
|
||||||
|
-----
|
||||||
|
|
||||||
|
* *timefunc* and *delayfunct* parameters of :class:`~sched.scheduler` class
|
||||||
|
constructor are now optional and defaults to :func:`time.time` and
|
||||||
|
:func:`time.sleep` respectively. (Contributed by Matt Mulsow in
|
||||||
|
:issue:`8809`)
|
||||||
|
|
||||||
|
* :meth:`~sched.scheduler.enter` and :meth:`~sched.scheduler.enterabs`
|
||||||
|
*argument* parameter is now optional. (Contributed by Matt Mulsow in
|
||||||
|
:issue:`8809`)
|
||||||
|
|
||||||
|
* :meth:`~sched.scheduler.enter` and :meth:`~sched.scheduler.enterabs`
|
||||||
|
now accept a *kwargs* parameter. (Contributed by Matt Mulsow in
|
||||||
|
:issue:`8809`)
|
||||||
|
|
||||||
Optimizations
|
Optimizations
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
@ -744,4 +760,3 @@ Other issues
|
||||||
.. Issue #10998: the -Q command-line flag and related artifacts have been
|
.. Issue #10998: the -Q command-line flag and related artifacts have been
|
||||||
removed. Code checking sys.flags.division_warning will need updating.
|
removed. Code checking sys.flags.division_warning will need updating.
|
||||||
Contributed by Éric Araujo.
|
Contributed by Éric Araujo.
|
||||||
|
|
||||||
|
|
18
Lib/sched.py
18
Lib/sched.py
|
@ -28,12 +28,13 @@ has another way to reference private data (besides global variables).
|
||||||
# XXX instead of having to define a module or class just to hold
|
# XXX instead of having to define a module or class just to hold
|
||||||
# XXX the global state of your particular time and delay functions.
|
# XXX the global state of your particular time and delay functions.
|
||||||
|
|
||||||
|
import time
|
||||||
import heapq
|
import heapq
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
__all__ = ["scheduler"]
|
__all__ = ["scheduler"]
|
||||||
|
|
||||||
class Event(namedtuple('Event', 'time, priority, action, argument')):
|
class Event(namedtuple('Event', 'time, priority, action, argument, kwargs')):
|
||||||
def __eq__(s, o): return (s.time, s.priority) == (o.time, o.priority)
|
def __eq__(s, o): return (s.time, s.priority) == (o.time, o.priority)
|
||||||
def __ne__(s, o): return (s.time, s.priority) != (o.time, o.priority)
|
def __ne__(s, o): return (s.time, s.priority) != (o.time, o.priority)
|
||||||
def __lt__(s, o): return (s.time, s.priority) < (o.time, o.priority)
|
def __lt__(s, o): return (s.time, s.priority) < (o.time, o.priority)
|
||||||
|
@ -42,32 +43,33 @@ class Event(namedtuple('Event', 'time, priority, action, argument')):
|
||||||
def __ge__(s, o): return (s.time, s.priority) >= (o.time, o.priority)
|
def __ge__(s, o): return (s.time, s.priority) >= (o.time, o.priority)
|
||||||
|
|
||||||
class scheduler:
|
class scheduler:
|
||||||
def __init__(self, timefunc, delayfunc):
|
|
||||||
|
def __init__(self, timefunc=time.time, delayfunc=time.sleep):
|
||||||
"""Initialize a new instance, passing the time and delay
|
"""Initialize a new instance, passing the time and delay
|
||||||
functions"""
|
functions"""
|
||||||
self._queue = []
|
self._queue = []
|
||||||
self.timefunc = timefunc
|
self.timefunc = timefunc
|
||||||
self.delayfunc = delayfunc
|
self.delayfunc = delayfunc
|
||||||
|
|
||||||
def enterabs(self, time, priority, action, argument):
|
def enterabs(self, time, priority, action, argument=[], kwargs={}):
|
||||||
"""Enter a new event in the queue at an absolute time.
|
"""Enter a new event in the queue at an absolute time.
|
||||||
|
|
||||||
Returns an ID for the event which can be used to remove it,
|
Returns an ID for the event which can be used to remove it,
|
||||||
if necessary.
|
if necessary.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
event = Event(time, priority, action, argument)
|
event = Event(time, priority, action, argument, kwargs)
|
||||||
heapq.heappush(self._queue, event)
|
heapq.heappush(self._queue, event)
|
||||||
return event # The ID
|
return event # The ID
|
||||||
|
|
||||||
def enter(self, delay, priority, action, argument):
|
def enter(self, delay, priority, action, argument=[], kwargs={}):
|
||||||
"""A variant that specifies the time as a relative time.
|
"""A variant that specifies the time as a relative time.
|
||||||
|
|
||||||
This is actually the more commonly used interface.
|
This is actually the more commonly used interface.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
time = self.timefunc() + delay
|
time = self.timefunc() + delay
|
||||||
return self.enterabs(time, priority, action, argument)
|
return self.enterabs(time, priority, action, argument, kwargs)
|
||||||
|
|
||||||
def cancel(self, event):
|
def cancel(self, event):
|
||||||
"""Remove an event from the queue.
|
"""Remove an event from the queue.
|
||||||
|
@ -111,7 +113,7 @@ class scheduler:
|
||||||
timefunc = self.timefunc
|
timefunc = self.timefunc
|
||||||
pop = heapq.heappop
|
pop = heapq.heappop
|
||||||
while q:
|
while q:
|
||||||
time, priority, action, argument = checked_event = q[0]
|
time, priority, action, argument, kwargs = checked_event = q[0]
|
||||||
now = timefunc()
|
now = timefunc()
|
||||||
if now < time:
|
if now < time:
|
||||||
delayfunc(time - now)
|
delayfunc(time - now)
|
||||||
|
@ -120,7 +122,7 @@ class scheduler:
|
||||||
# Verify that the event was not removed or altered
|
# Verify that the event was not removed or altered
|
||||||
# by another thread after we last looked at q[0].
|
# by another thread after we last looked at q[0].
|
||||||
if event is checked_event:
|
if event is checked_event:
|
||||||
action(*argument)
|
action(*argument, **kwargs)
|
||||||
delayfunc(0) # Let other threads run
|
delayfunc(0) # Let other threads run
|
||||||
else:
|
else:
|
||||||
heapq.heappush(q, event)
|
heapq.heappush(q, event)
|
||||||
|
|
|
@ -72,6 +72,18 @@ class TestCase(unittest.TestCase):
|
||||||
scheduler.run()
|
scheduler.run()
|
||||||
self.assertEqual(scheduler._queue, [])
|
self.assertEqual(scheduler._queue, [])
|
||||||
|
|
||||||
|
def test_args_kwargs(self):
|
||||||
|
flag = []
|
||||||
|
|
||||||
|
def fun(*a, **b):
|
||||||
|
flag.append(None)
|
||||||
|
self.assertEqual(a, (1,2,3))
|
||||||
|
self.assertEqual(b, {"foo":1})
|
||||||
|
|
||||||
|
scheduler = sched.scheduler(time.time, time.sleep)
|
||||||
|
z = scheduler.enterabs(0.01, 1, fun, argument=(1,2,3), kwargs={"foo":1})
|
||||||
|
scheduler.run()
|
||||||
|
self.assertEqual(flag, [None])
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
support.run_unittest(TestCase)
|
support.run_unittest(TestCase)
|
||||||
|
|
|
@ -11,6 +11,7 @@ Without you, I would've stopped working on Python long ago!
|
||||||
PS: In the standard Python distribution, this file is encoded in UTF-8
|
PS: In the standard Python distribution, this file is encoded in UTF-8
|
||||||
and the list is in rough alphabetical order by last names.
|
and the list is in rough alphabetical order by last names.
|
||||||
|
|
||||||
|
Matt Mulsow
|
||||||
Rajiv Abraham
|
Rajiv Abraham
|
||||||
David Abrahams
|
David Abrahams
|
||||||
Ron Adam
|
Ron Adam
|
||||||
|
|
|
@ -387,6 +387,11 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #13245: sched.scheduler class constructor's timefunc and
|
||||||
|
delayfunct parameters are now optional.
|
||||||
|
scheduler.enter and scheduler.enterabs methods gained a new kwargs parameter.
|
||||||
|
Patch contributed by Matt Mulsow.
|
||||||
|
|
||||||
- Issue #12328: Under Windows, refactor handling of Ctrl-C events and
|
- Issue #12328: Under Windows, refactor handling of Ctrl-C events and
|
||||||
make _multiprocessing.win32.WaitForMultipleObjects interruptible when
|
make _multiprocessing.win32.WaitForMultipleObjects interruptible when
|
||||||
the wait_flag parameter is false. Patch by sbt.
|
the wait_flag parameter is false. Patch by sbt.
|
||||||
|
|
Loading…
Reference in New Issue