summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Nick Koston <nick@koston.org>2023-07-13 19:18:53 (GMT)
committerGitHub <noreply@github.com>2023-07-13 19:18:53 (GMT)
commit8d2f3c36caf9ecdee1176314b18388aef6e7f2c2 (patch)
tree8c9db77b946611cc5a758bdeee2bed5efa879bfb
parente6e0ea0113748db1e9fe675be6db9041cd5cce1f (diff)
downloadcpython-8d2f3c36caf9ecdee1176314b18388aef6e7f2c2.zip
cpython-8d2f3c36caf9ecdee1176314b18388aef6e7f2c2.tar.gz
cpython-8d2f3c36caf9ecdee1176314b18388aef6e7f2c2.tar.bz2
gh-106664: selectors: add get() method to _SelectorMapping (#106665)
It can be used to avoid raising and catching KeyError twice via __getitem__. Co-authored-by: Inada Naoki <songofacandy@gmail.com>
-rw-r--r--Lib/selectors.py14
-rw-r--r--Lib/test/test_selectors.py6
-rw-r--r--Misc/NEWS.d/next/Library/2023-07-12-03-04-45.gh-issue-106664.ZeUG78.rst1
3 files changed, 16 insertions, 5 deletions
diff --git a/Lib/selectors.py b/Lib/selectors.py
index af6a4f9..dfcc125 100644
--- a/Lib/selectors.py
+++ b/Lib/selectors.py
@@ -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)
diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py
index c2db88c..4545cba 100644
--- a/Lib/test/test_selectors.py
+++ b/Lib/test/test_selectors.py
@@ -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
index 0000000..c278cad
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-07-12-03-04-45.gh-issue-106664.ZeUG78.rst
@@ -0,0 +1 @@
+:mod:`selectors`: Add ``_SelectorMapping.get()`` method and optimize ``_SelectorMapping.__getitem__()``.