mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Issue #19172: Add a get_map() method to selectors.
This commit is contained in:
parent
7613542a27
commit
4574b49703
3 changed files with 61 additions and 1 deletions
|
@ -164,6 +164,14 @@ below:
|
||||||
This returns the :class:`SelectorKey` instance associated to this file
|
This returns the :class:`SelectorKey` instance associated to this file
|
||||||
object, or raises :exc:`KeyError` if the file object is not registered.
|
object, or raises :exc:`KeyError` if the file object is not registered.
|
||||||
|
|
||||||
|
.. method:: get_map()
|
||||||
|
|
||||||
|
Return a mapping of file objects to selector keys.
|
||||||
|
|
||||||
|
This returns a :class:`~collections.abc.Mapping` instance mapping
|
||||||
|
registered file objects to their associated :class:`SelectorKey`
|
||||||
|
instance.
|
||||||
|
|
||||||
|
|
||||||
.. class:: DefaultSelector()
|
.. class:: DefaultSelector()
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ This module allows high-level and efficient I/O multiplexing, built upon the
|
||||||
|
|
||||||
|
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
from collections import namedtuple
|
from collections import namedtuple, Mapping
|
||||||
import functools
|
import functools
|
||||||
import select
|
import select
|
||||||
import sys
|
import sys
|
||||||
|
@ -44,6 +44,25 @@ SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data'])
|
||||||
selected event mask and attached data."""
|
selected event mask and attached data."""
|
||||||
|
|
||||||
|
|
||||||
|
class _SelectorMapping(Mapping):
|
||||||
|
"""Mapping of file objects to selector keys."""
|
||||||
|
|
||||||
|
def __init__(self, selector):
|
||||||
|
self._selector = selector
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._selector._fd_to_key)
|
||||||
|
|
||||||
|
def __getitem__(self, fileobj):
|
||||||
|
try:
|
||||||
|
return self._selector._fd_to_key[_fileobj_to_fd(fileobj)]
|
||||||
|
except KeyError:
|
||||||
|
raise KeyError("{!r} is not registered".format(fileobj)) from None
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self._selector._fd_to_key)
|
||||||
|
|
||||||
|
|
||||||
class BaseSelector(metaclass=ABCMeta):
|
class BaseSelector(metaclass=ABCMeta):
|
||||||
"""Base selector class.
|
"""Base selector class.
|
||||||
|
|
||||||
|
@ -62,6 +81,8 @@ class BaseSelector(metaclass=ABCMeta):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# this maps file descriptors to keys
|
# this maps file descriptors to keys
|
||||||
self._fd_to_key = {}
|
self._fd_to_key = {}
|
||||||
|
# read-only mapping returned by get_map()
|
||||||
|
self._map = _SelectorMapping(self)
|
||||||
|
|
||||||
def register(self, fileobj, events, data=None):
|
def register(self, fileobj, events, data=None):
|
||||||
"""Register a file object.
|
"""Register a file object.
|
||||||
|
@ -162,6 +183,10 @@ class BaseSelector(metaclass=ABCMeta):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise KeyError("{!r} is not registered".format(fileobj)) from None
|
raise KeyError("{!r} is not registered".format(fileobj)) from None
|
||||||
|
|
||||||
|
def get_map(self):
|
||||||
|
"""Return a mapping of file objects to selector keys."""
|
||||||
|
return self._map
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,33 @@ class BaseSelectorTestCase(unittest.TestCase):
|
||||||
# unknown file obj
|
# unknown file obj
|
||||||
self.assertRaises(KeyError, s.get_key, 999999)
|
self.assertRaises(KeyError, s.get_key, 999999)
|
||||||
|
|
||||||
|
def test_get_map(self):
|
||||||
|
s = self.SELECTOR()
|
||||||
|
self.addCleanup(s.close)
|
||||||
|
|
||||||
|
rd, wr = socketpair()
|
||||||
|
self.addCleanup(rd.close)
|
||||||
|
self.addCleanup(wr.close)
|
||||||
|
|
||||||
|
keys = s.get_map()
|
||||||
|
self.assertFalse(keys)
|
||||||
|
self.assertEqual(len(keys), 0)
|
||||||
|
self.assertEqual(list(keys), [])
|
||||||
|
key = s.register(rd, selectors.EVENT_READ, "data")
|
||||||
|
self.assertIn(rd, keys)
|
||||||
|
self.assertEqual(key, keys[rd])
|
||||||
|
self.assertEqual(len(keys), 1)
|
||||||
|
self.assertEqual(list(keys), [rd.fileno()])
|
||||||
|
self.assertEqual(list(keys.values()), [key])
|
||||||
|
|
||||||
|
# unknown file obj
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
keys[999999]
|
||||||
|
|
||||||
|
# Read-only mapping
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
del keys[rd]
|
||||||
|
|
||||||
def test_select(self):
|
def test_select(self):
|
||||||
s = self.SELECTOR()
|
s = self.SELECTOR()
|
||||||
self.addCleanup(s.close)
|
self.addCleanup(s.close)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue