]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-106664: selectors: add get() method to _SelectorMapping (#106665)
authorJ. Nick Koston <nick@koston.org>
Thu, 13 Jul 2023 19:18:53 +0000 (09:18 -1000)
committerGitHub <noreply@github.com>
Thu, 13 Jul 2023 19:18:53 +0000 (19:18 +0000)
It can be used to avoid raising and catching KeyError twice via __getitem__.

Co-authored-by: Inada Naoki <songofacandy@gmail.com>
Lib/selectors.py
Lib/test/test_selectors.py
Misc/NEWS.d/next/Library/2023-07-12-03-04-45.gh-issue-106664.ZeUG78.rst [new file with mode: 0644]

index af6a4f94b5008ad6c466922eb323338604c453fc..dfcc125dcd94ef49c2ea9eedfab978ebb1604b43 100644 (file)
@@ -66,12 +66,16 @@ class _SelectorMapping(Mapping):
     def __len__(self):
         return len(self._selector._fd_to_key)
 
+    def get(self, fileobj, default=None):
+        fd = self._selector._fileobj_lookup(fileobj)
+        return self._selector._fd_to_key.get(fd, default)
+
     def __getitem__(self, fileobj):
-        try:
-            fd = self._selector._fileobj_lookup(fileobj)
-            return self._selector._fd_to_key[fd]
-        except KeyError:
-            raise KeyError("{!r} is not registered".format(fileobj)) from None
+        fd = self._selector._fileobj_lookup(fileobj)
+        key = self._selector._fd_to_key.get(fd)
+        if key is None:
+            raise KeyError("{!r} is not registered".format(fileobj))
+        return key
 
     def __iter__(self):
         return iter(self._selector._fd_to_key)
index c2db88c203920a9d2c077fe58ccdc6d040ddaadb..4545cbadb796fdefe5cf0601547188706ef0b25c 100644 (file)
@@ -223,6 +223,8 @@ class BaseSelectorTestCase:
         self.assertRaises(RuntimeError, s.get_key, wr)
         self.assertRaises(KeyError, mapping.__getitem__, rd)
         self.assertRaises(KeyError, mapping.__getitem__, wr)
+        self.assertEqual(mapping.get(rd), None)
+        self.assertEqual(mapping.get(wr), None)
 
     def test_get_key(self):
         s = self.SELECTOR()
@@ -241,13 +243,17 @@ class BaseSelectorTestCase:
         self.addCleanup(s.close)
 
         rd, wr = self.make_socketpair()
+        sentinel = object()
 
         keys = s.get_map()
         self.assertFalse(keys)
         self.assertEqual(len(keys), 0)
         self.assertEqual(list(keys), [])
+        self.assertEqual(keys.get(rd), None)
+        self.assertEqual(keys.get(rd, sentinel), sentinel)
         key = s.register(rd, selectors.EVENT_READ, "data")
         self.assertIn(rd, keys)
+        self.assertEqual(key, keys.get(rd))
         self.assertEqual(key, keys[rd])
         self.assertEqual(len(keys), 1)
         self.assertEqual(list(keys), [rd.fileno()])
diff --git a/Misc/NEWS.d/next/Library/2023-07-12-03-04-45.gh-issue-106664.ZeUG78.rst b/Misc/NEWS.d/next/Library/2023-07-12-03-04-45.gh-issue-106664.ZeUG78.rst
new file mode 100644 (file)
index 0000000..c278cad
--- /dev/null
@@ -0,0 +1 @@
+:mod:`selectors`: Add ``_SelectorMapping.get()`` method and optimize ``_SelectorMapping.__getitem__()``.