From 44bd6c0a4f126c374b23f749141cb37a94366894 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Thu, 17 Jan 2008 19:31:38 +0000 Subject: Issue #1861: Add read-only attribute listing upcoming events in the order they will be run. --- Doc/library/sched.rst | 7 ++++++- Lib/sched.py | 31 ++++++++++++++++++++++++------- Misc/NEWS | 3 +++ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index 40d9331..1007cfb 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -47,7 +47,7 @@ Example:: Scheduler Objects ----------------- -:class:`scheduler` instances have the following methods: +:class:`scheduler` instances have the following methods and attributes: .. method:: scheduler.enterabs(time, priority, action, argument) @@ -98,3 +98,8 @@ Scheduler Objects the calling code is responsible for canceling events which are no longer pertinent. +.. attribute:: scheduler.queue + + Read-only attribute returning a list of upcoming events in the order they + will be run. Each event is shown as a :term:`named tuple` with the + following fields: time, priority, action, argument. diff --git a/Lib/sched.py b/Lib/sched.py index 51c4e74..1c7bfea 100644 --- a/Lib/sched.py +++ b/Lib/sched.py @@ -29,14 +29,17 @@ has another way to reference private data (besides global variables). # XXX the global state of your particular time and delay functions. import heapq +from collections import namedtuple __all__ = ["scheduler"] +Event = namedtuple('Event', 'time, priority, action, argument') + class scheduler: def __init__(self, timefunc, delayfunc): """Initialize a new instance, passing the time and delay functions""" - self.queue = [] + self._queue = [] self.timefunc = timefunc self.delayfunc = delayfunc @@ -47,8 +50,8 @@ class scheduler: if necessary. """ - event = time, priority, action, argument - heapq.heappush(self.queue, event) + event = Event(time, priority, action, argument) + heapq.heappush(self._queue, event) return event # The ID def enter(self, delay, priority, action, argument): @@ -67,12 +70,12 @@ class scheduler: If the event is not in the queue, this raises RuntimeError. """ - self.queue.remove(event) - heapq.heapify(self.queue) + self._queue.remove(event) + heapq.heapify(self._queue) def empty(self): """Check whether the queue is empty.""" - return not self.queue + return not self._queue def run(self): """Execute events until the queue is empty. @@ -97,7 +100,7 @@ class scheduler: """ # localize variable access to minimize overhead # and to improve thread safety - q = self.queue + q = self._queue delayfunc = self.delayfunc timefunc = self.timefunc pop = heapq.heappop @@ -115,3 +118,17 @@ class scheduler: delayfunc(0) # Let other threads run else: heapq.heappush(event) + + @property + def queue(self): + """An ordered list of upcoming events. + + Events are named tuples with fields for: + time, priority, action, arguments + + """ + # Use heapq to sort the queue rather than using 'sorted(self._queue)'. + # With heapq, two events scheduled at the same time will show in + # the actual order they would be retrieved. + events = self._queue[:] + return map(heapq.heappop, [events]*len(events)) diff --git a/Misc/NEWS b/Misc/NEWS index 828aab2..7f92aaf 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -364,6 +364,9 @@ Core and builtins Library ------- +- #1861: Added an attribute to the sched module which returns an ordered + list of upcoming events (displayed as named tuples). + - #1837: The queue module now also supports a LIFO queue and a priority queue. - Issue #1831: ctypes now raises a TypeError if conflicting positional -- cgit v0.12