[Python-checkins] cpython: Issue #23485: Enhance and update selectors doc and test_selectors

victor.stinner python-checkins at python.org
Tue Mar 31 12:17:39 CEST 2015


https://hg.python.org/cpython/rev/76d297869859
changeset:   95315:76d297869859
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Tue Mar 31 12:08:09 2015 +0200
summary:
  Issue #23485: Enhance and update selectors doc and test_selectors

Selector.select() is now retried with the recomputed timeout when interrupted
by a signal.

Write an unit test with a signal handler raising an exception, and a unit with
a signal handler which does not raise an exception (it does nothing).

files:
  Doc/library/selectors.rst  |   6 ++++
  Lib/test/test_selectors.py |  37 +++++++++++++++++++++++--
  2 files changed, 40 insertions(+), 3 deletions(-)


diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst
--- a/Doc/library/selectors.rst
+++ b/Doc/library/selectors.rst
@@ -159,6 +159,12 @@
           timeout has elapsed if the current process receives a signal: in this
           case, an empty list will be returned.
 
+      .. versionchanged:: 3.5
+         The selector is now retried with a recomputed timeout when interrupted
+         by a signal if the signal handler did not raise an exception (see
+         :pep:`475` for the rationale), instead of returning an empty list
+         of events before the timeout.
+
    .. method:: close()
 
       Close the selector.
diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py
--- a/Lib/test/test_selectors.py
+++ b/Lib/test/test_selectors.py
@@ -357,7 +357,35 @@
 
     @unittest.skipUnless(hasattr(signal, "alarm"),
                          "signal.alarm() required for this test")
-    def test_select_interrupt(self):
+    def test_select_interrupt_exc(self):
+        s = self.SELECTOR()
+        self.addCleanup(s.close)
+
+        rd, wr = self.make_socketpair()
+
+        class InterruptSelect(Exception):
+            pass
+
+        def handler(*args):
+            raise InterruptSelect
+
+        orig_alrm_handler = signal.signal(signal.SIGALRM, handler)
+        self.addCleanup(signal.signal, signal.SIGALRM, orig_alrm_handler)
+        self.addCleanup(signal.alarm, 0)
+
+        signal.alarm(1)
+
+        s.register(rd, selectors.EVENT_READ)
+        t = time()
+        # select() is interrupted by a signal which raises an exception
+        with self.assertRaises(InterruptSelect):
+            s.select(30)
+        # select() was interrupted before the timeout of 30 seconds
+        self.assertLess(time() - t, 5.0)
+
+    @unittest.skipUnless(hasattr(signal, "alarm"),
+                         "signal.alarm() required for this test")
+    def test_select_interrupt_noraise(self):
         s = self.SELECTOR()
         self.addCleanup(s.close)
 
@@ -371,8 +399,11 @@
 
         s.register(rd, selectors.EVENT_READ)
         t = time()
-        self.assertFalse(s.select(2))
-        self.assertLess(time() - t, 2.5)
+        # select() is interrupted by a signal, but the signal handler doesn't
+        # raise an exception, so select() should by retries with a recomputed
+        # timeout
+        self.assertFalse(s.select(1.5))
+        self.assertGreaterEqual(time() - t, 1.0)
 
 
 class ScalableSelectorMixIn:

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list