diff -r 3e4676eec39b asyncio/selectors.py --- a/asyncio/selectors.py Sun Nov 03 14:07:25 2013 -0800 +++ b/asyncio/selectors.py Mon Nov 04 21:35:26 2013 +0100 @@ -138,11 +138,14 @@ key = self._fd_to_key[_fileobj_to_fd(fileobj)] except KeyError: raise KeyError("{!r} is not registered".format(fileobj)) from None - if events != key.events or data != key.data: - # TODO: If only the data changed, use a shortcut that only - # updates the data. + if events != key.events: self.unregister(fileobj) return self.register(fileobj, events, data) + elif data != key.data: + # Use a shortcut to update the data. + key = key._replace(data=data) + self._fd_to_key[key.fd] = key + return key else: return key diff -r 3e4676eec39b tests/test_selectors.py --- a/tests/test_selectors.py Sun Nov 03 14:07:25 2013 -0800 +++ b/tests/test_selectors.py Mon Nov 04 21:35:26 2013 +0100 @@ -13,8 +13,54 @@ raise NotImplementedError +class _SelectorMappingTests(unittest.TestCase): + + def test_len(self): + s = FakeSelector() + map = selectors._SelectorMapping(s) + self.assertTrue(map.__len__() == 0) + + f = unittest.mock.Mock() + f.fileno.return_value = 10 + s.register(f, selectors.EVENT_READ, None) + self.assertTrue(len(map) == 1) + + def test_getitem(self): + s = FakeSelector() + map = selectors._SelectorMapping(s) + f = unittest.mock.Mock() + f.fileno.return_value = 10 + s.register(f, selectors.EVENT_READ, None) + attended = selectors.SelectorKey(f, 10, selectors.EVENT_READ, None) + self.assertEqual(attended, map.__getitem__(f)) + + def test_getitem_key_error(self): + s = FakeSelector() + map = selectors._SelectorMapping(s) + self.assertTrue(len(map) == 0) + f = unittest.mock.Mock() + f.fileno.return_value = 10 + s.register(f, selectors.EVENT_READ, None) + self.assertRaises(KeyError, map.__getitem__, 5) + + def test_iter(self): + s = FakeSelector() + map = selectors._SelectorMapping(s) + self.assertTrue(len(map) == 0) + f = unittest.mock.Mock() + f.fileno.return_value = 5 + s.register(f, selectors.EVENT_READ, None) + counter = 0 + for fileno in map.__iter__(): + self.assertEqual(5, fileno) + counter += 1 + + for idx in map: + self.assertEqual(f, map[idx].fileobj) + self.assertEqual(1, counter) + + class BaseSelectorTests(unittest.TestCase): - def test_fileobj_to_fd(self): self.assertEqual(10, selectors._fileobj_to_fd(10)) @@ -25,6 +71,9 @@ f.fileno.side_effect = AttributeError self.assertRaises(ValueError, selectors._fileobj_to_fd, f) + f.fileno.return_value = -1 + self.assertRaises(ValueError, selectors._fileobj_to_fd, f) + def test_selector_key_repr(self): key = selectors.SelectorKey(10, 10, selectors.EVENT_READ, None) self.assertEqual( @@ -103,6 +152,22 @@ selectors.SelectorKey(fobj, 10, selectors.EVENT_READ, d2), s.get_key(fobj)) + def test_modify_data_use_a_shortcut(self): + fobj = unittest.mock.Mock() + fobj.fileno.return_value = 10 + + d1 = object() + d2 = object() + + s = FakeSelector() + key = s.register(fobj, selectors.EVENT_READ, d1) + + s.unregister = unittest.mock.Mock() + s.register = unittest.mock.Mock() + key2 = s.modify(fobj, selectors.EVENT_READ, d2) + self.assertFalse(s.unregister.called) + self.assertFalse(s.register.called) + def test_modify_same(self): fobj = unittest.mock.Mock() fobj.fileno.return_value = 10