[Python-checkins] bpo-19270: Fixed sched.scheduler.cancel to cancel correct event (GH-22729)

Bar Harel webhook-mailer at python.org
Mon Oct 19 03:34:00 EDT 2020


https://github.com/python/cpython/commit/5368c2b6e23660cbce7e38dc68f859c66ac349ee
commit: 5368c2b6e23660cbce7e38dc68f859c66ac349ee
branch: master
author: Bar Harel <bzvi7919 at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020年10月19日T10:33:43+03:00
summary:
bpo-19270: Fixed sched.scheduler.cancel to cancel correct event (GH-22729)
files:
A Misc/NEWS.d/next/Library/2020-10-16-22-48-01.bpo-19270.jd_gkA.rst
M Lib/sched.py
M Lib/test/test_sched.py
diff --git a/Lib/sched.py b/Lib/sched.py
index ff87874a3a4b7..14613cf29874d 100644
--- a/Lib/sched.py
+++ b/Lib/sched.py
@@ -26,23 +26,19 @@
 import time
 import heapq
 from collections import namedtuple
+from itertools import count
 import threading
 from time import monotonic as _time
 
 __all__ = ["scheduler"]
 
-class Event(namedtuple('Event', 'time, priority, action, argument, kwargs')):
- __slots__ = []
- def __eq__(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 __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 __ge__(s, o): return (s.time, s.priority) >= (o.time, o.priority)
-
+Event = namedtuple('Event', 'time, priority, sequence, action, argument, kwargs')
 Event.time.__doc__ = ('''Numeric type compatible with the return value of the
 timefunc function passed to the constructor.''')
 Event.priority.__doc__ = ('''Events scheduled for the same time will be executed
 in the order of their priority.''')
+Event.sequence.__doc__ = ('''A continually increasing sequence number that
+ separates events if time and priority are equal.''')
 Event.action.__doc__ = ('''Executing the event means executing
 action(*argument, **kwargs)''')
 Event.argument.__doc__ = ('''argument is a sequence holding the positional
@@ -61,6 +57,7 @@ def __init__(self, timefunc=_time, delayfunc=time.sleep):
 self._lock = threading.RLock()
 self.timefunc = timefunc
 self.delayfunc = delayfunc
+ self._sequence_generator = count()
 
 def enterabs(self, time, priority, action, argument=(), kwargs=_sentinel):
 """Enter a new event in the queue at an absolute time.
@@ -71,8 +68,10 @@ def enterabs(self, time, priority, action, argument=(), kwargs=_sentinel):
 """
 if kwargs is _sentinel:
 kwargs = {}
- event = Event(time, priority, action, argument, kwargs)
+
 with self._lock:
+ event = Event(time, priority, next(self._sequence_generator),
+ action, argument, kwargs)
 heapq.heappush(self._queue, event)
 return event # The ID
 
@@ -136,7 +135,8 @@ def run(self, blocking=True):
 with lock:
 if not q:
 break
- time, priority, action, argument, kwargs = q[0]
+ (time, priority, sequence, action,
+ argument, kwargs) = q[0]
 now = timefunc()
 if time > now:
 delay = True
diff --git a/Lib/test/test_sched.py b/Lib/test/test_sched.py
index 491d7b3a745b4..7ae7baae85e2c 100644
--- a/Lib/test/test_sched.py
+++ b/Lib/test/test_sched.py
@@ -142,6 +142,17 @@ def test_cancel_concurrent(self):
 self.assertTrue(q.empty())
 self.assertEqual(timer.time(), 4)
 
+ def test_cancel_correct_event(self):
+ # bpo-19270
+ events = []
+ scheduler = sched.scheduler()
+ scheduler.enterabs(1, 1, events.append, ("a",))
+ b = scheduler.enterabs(1, 1, events.append, ("b",))
+ scheduler.enterabs(1, 1, events.append, ("c",))
+ scheduler.cancel(b)
+ scheduler.run()
+ self.assertEqual(events, ["a", "c"])
+
 def test_empty(self):
 l = []
 fun = lambda x: l.append(x)
diff --git a/Misc/NEWS.d/next/Library/2020-10-16-22-48-01.bpo-19270.jd_gkA.rst b/Misc/NEWS.d/next/Library/2020-10-16-22-48-01.bpo-19270.jd_gkA.rst
new file mode 100644
index 0000000000000..6330a91a44c54
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-10-16-22-48-01.bpo-19270.jd_gkA.rst
@@ -0,0 +1,2 @@
+:meth:`sched.scheduler.cancel()` will now cancel the correct event, if two
+events with same priority are scheduled for the same time. Patch by Bar Harel.


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /