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
|
||||
scheduler:
|
||||
|
||||
.. class:: scheduler(timefunc, delayfunc)
|
||||
.. class:: scheduler(timefunc=time.time, delayfunc=time.sleep)
|
||||
|
||||
The :class:`scheduler` class defines a generic interface to scheduling events.
|
||||
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
|
||||
applications.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
*timefunc* and *delayfunc* parameters are optional.
|
||||
|
||||
Example::
|
||||
|
||||
>>> import sched, time
|
||||
|
@ -79,26 +82,38 @@ Scheduler Objects
|
|||
: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
|
||||
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
|
||||
*priority*.
|
||||
|
||||
Executing the event means executing ``action(*argument)``. *argument* must be a
|
||||
sequence holding the parameters for *action*.
|
||||
Executing the event means executing ``action(*argument, **kwargs)``.
|
||||
*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
|
||||
(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
|
||||
other arguments, the effect and the return value are the same as those for
|
||||
:meth:`enterabs`.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
*argument* parameter is optional.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
*kwargs* parameter was added.
|
||||
|
||||
.. method:: scheduler.cancel(event)
|
||||
|
||||
|
|
|
@ -572,6 +572,22 @@ should be used. For example, this will send a ``'HEAD'`` request::
|
|||
|
||||
(: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
|
||||
=============
|
||||
|
||||
|
@ -744,4 +760,3 @@ Other issues
|
|||
.. Issue #10998: the -Q command-line flag and related artifacts have been
|
||||
removed. Code checking sys.flags.division_warning will need updating.
|
||||
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 the global state of your particular time and delay functions.
|
||||
|
||||
import time
|
||||
import heapq
|
||||
from collections import namedtuple
|
||||
|
||||
__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 __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)
|
||||
|
@ -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)
|
||||
|
||||
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
|
||||
functions"""
|
||||
self._queue = []
|
||||
self.timefunc = timefunc
|
||||
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.
|
||||
|
||||
Returns an ID for the event which can be used to remove it,
|
||||
if necessary.
|
||||
|
||||
"""
|
||||
event = Event(time, priority, action, argument)
|
||||
event = Event(time, priority, action, argument, kwargs)
|
||||
heapq.heappush(self._queue, event)
|
||||
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.
|
||||
|
||||
This is actually the more commonly used interface.
|
||||
|
||||
"""
|
||||
time = self.timefunc() + delay
|
||||
return self.enterabs(time, priority, action, argument)
|
||||
return self.enterabs(time, priority, action, argument, kwargs)
|
||||
|
||||
def cancel(self, event):
|
||||
"""Remove an event from the queue.
|
||||
|
@ -111,7 +113,7 @@ class scheduler:
|
|||
timefunc = self.timefunc
|
||||
pop = heapq.heappop
|
||||
while q:
|
||||
time, priority, action, argument = checked_event = q[0]
|
||||
time, priority, action, argument, kwargs = checked_event = q[0]
|
||||
now = timefunc()
|
||||
if now < time:
|
||||
delayfunc(time - now)
|
||||
|
@ -120,7 +122,7 @@ class scheduler:
|
|||
# Verify that the event was not removed or altered
|
||||
# by another thread after we last looked at q[0].
|
||||
if event is checked_event:
|
||||
action(*argument)
|
||||
action(*argument, **kwargs)
|
||||
delayfunc(0) # Let other threads run
|
||||
else:
|
||||
heapq.heappush(q, event)
|
||||
|
|
|
@ -72,6 +72,18 @@ class TestCase(unittest.TestCase):
|
|||
scheduler.run()
|
||||
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():
|
||||
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
|
||||
and the list is in rough alphabetical order by last names.
|
||||
|
||||
Matt Mulsow
|
||||
Rajiv Abraham
|
||||
David Abrahams
|
||||
Ron Adam
|
||||
|
|
|
@ -387,6 +387,11 @@ Core and Builtins
|
|||
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
|
||||
make _multiprocessing.win32.WaitForMultipleObjects interruptible when
|
||||
the wait_flag parameter is false. Patch by sbt.
|
||||
|
|
Loading…
Reference in New Issue