Issue #16641: Fix default values of sched.scheduler.enter arguments were modifiable.

This commit is contained in:
Serhiy Storchaka 2012-12-29 21:13:45 +02:00
parent e912496c60
commit c04957bff3
3 changed files with 23 additions and 11 deletions

View file

@ -36,19 +36,22 @@ Example::
>>> import sched, time >>> import sched, time
>>> s = sched.scheduler(time.time, time.sleep) >>> s = sched.scheduler(time.time, time.sleep)
>>> def print_time(): print("From print_time", time.time()) >>> def print_time(a='default'):
... print("From print_time", time.time(), a)
... ...
>>> def print_some_times(): >>> def print_some_times():
... print(time.time()) ... print(time.time())
... s.enter(5, 1, print_time, ()) ... s.enter(10, 1, print_time)
... s.enter(10, 1, print_time, ()) ... s.enter(5, 2, print_time, argument=('positional',))
... s.enter(5, 1, print_time, kwargs={'a': 'keyword'})
... s.run() ... s.run()
... print(time.time()) ... print(time.time())
... ...
>>> print_some_times() >>> print_some_times()
930343690.257 930343690.257
From print_time 930343695.274 From print_time 930343695.274 positional
From print_time 930343700.273 From print_time 930343695.275 keyword
From print_time 930343700.273 default
930343700.276 930343700.276
.. _scheduler-objects: .. _scheduler-objects:
@ -59,7 +62,7 @@ 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=[], kwargs={}) .. 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.
@ -67,8 +70,10 @@ Scheduler Objects
*priority*. *priority*.
Executing the event means executing ``action(*argument, **kwargs)``. Executing the event means executing ``action(*argument, **kwargs)``.
*argument* must be a sequence holding the parameters for *action*. Optional *argument* argument must be a sequence holding the parameters
*kwargs* must be a dictionary holding the keyword parameters for *action*. for *action* if any used.
Optional *kwargs* argument must be a dictionary holding the keyword
parameters for *action* if any used.
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`).
@ -80,7 +85,7 @@ Scheduler Objects
*kwargs* parameter was added. *kwargs* parameter was added.
.. method:: scheduler.enter(delay, priority, action, argument=[], kwargs={}) .. 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

View file

@ -50,6 +50,8 @@ def __le__(s, o): return (s.time, s.priority) <= (o.time, o.priority)
def __gt__(s, o): return (s.time, s.priority) > (o.time, o.priority) def __gt__(s, o): return (s.time, s.priority) > (o.time, o.priority)
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)
_sentinel = object()
class scheduler: class scheduler:
def __init__(self, timefunc=_time, delayfunc=time.sleep): def __init__(self, timefunc=_time, delayfunc=time.sleep):
@ -60,19 +62,21 @@ def __init__(self, timefunc=_time, delayfunc=time.sleep):
self.timefunc = timefunc self.timefunc = timefunc
self.delayfunc = delayfunc self.delayfunc = delayfunc
def enterabs(self, time, priority, action, argument=[], kwargs={}): def enterabs(self, time, priority, action, argument=(), kwargs=_sentinel):
"""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.
""" """
if kwargs is _sentinel:
kwargs = {}
with self._lock: with self._lock:
event = Event(time, priority, action, argument, kwargs) 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=[], kwargs={}): def enter(self, delay, priority, action, argument=(), kwargs=_sentinel):
"""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.

View file

@ -124,6 +124,9 @@ Core and Builtins
Library Library
------- -------
- Issue #16641: Fix default values of sched.scheduler.enter arguments were
modifiable.
- Issue #16504: IDLE now catches SyntaxErrors raised by tokenizer. Patch by - Issue #16504: IDLE now catches SyntaxErrors raised by tokenizer. Patch by
Roger Serwy. Roger Serwy.