def select(self, timeout=None):
timeout = None if timeout is None else max(timeout, 0)
- max_ev = len(self._fd_to_key)
+ # If max_ev is 0, kqueue will ignore the timeout. For consistent
+ # behavior with the other selector classes, we prevent that here
+ # (using max). See https://bugs.python.org/issue29255
+ max_ev = max(len(self._fd_to_key), 1)
ready = []
try:
kev_list = self._selector.control(None, max_ev, timeout)
with self.assertRaises(KeyError):
s.get_key(bad_f)
+ def test_empty_select_timeout(self):
+ # Issues #23009, #29255: Make sure timeout is applied when no fds
+ # are registered.
+ s = self.SELECTOR()
+ self.addCleanup(s.close)
+
+ t0 = time()
+ self.assertEqual(s.select(1), [])
+ t1 = time()
+ dt = t1 - t0
+ # Tolerate 2.0 seconds for very slow buildbots
+ self.assertTrue(0.8 <= dt <= 2.0, dt)
+
@unittest.skipUnless(hasattr(selectors, 'DevpollSelector'),
"Test needs selectors.DevpollSelector")