Commit c04957bf authored by Serhiy Storchaka's avatar Serhiy Storchaka

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

parent e912496c
...@@ -36,19 +36,22 @@ Example:: ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
......
...@@ -50,6 +50,8 @@ class Event(namedtuple('Event', 'time, priority, action, argument, kwargs')): ...@@ -50,6 +50,8 @@ class Event(namedtuple('Event', 'time, priority, action, argument, kwargs')):
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 @@ class scheduler: ...@@ -60,19 +62,21 @@ class scheduler:
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.
......
...@@ -124,6 +124,9 @@ Core and Builtins ...@@ -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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment