[Python-checkins] bpo-32410: Make SendfileNotAvailableError exception public (#5243)

Andrew Svetlov webhook-mailer at python.org
Fri Jan 19 13:04:32 EST 2018


https://github.com/python/cpython/commit/7464e87a6511d3626b04c9833a262a77b1f21e23
commit: 7464e87a6511d3626b04c9833a262a77b1f21e23
branch: master
author: Andrew Svetlov <andrew.svetlov at gmail.com>
committer: GitHub <noreply at github.com>
date: 2018-01-19T20:04:29+02:00
summary:

bpo-32410: Make SendfileNotAvailableError exception public (#5243)

files:
M Doc/library/asyncio-eventloop.rst
M Lib/asyncio/base_events.py
M Lib/asyncio/events.py
M Lib/asyncio/unix_events.py
M Lib/test/test_asyncio/test_base_events.py
M Lib/test/test_asyncio/test_unix_events.py

diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index e63180b750a..6cee171b65a 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -726,7 +726,7 @@ Low-level socket operations
    the file when the platform does not support the sendfile syscall
    (e.g. Windows or SSL socket on Unix).
 
-   Raise :exc:`RuntimeError` if the system does not support
+   Raise :exc:`SendfileNotAvailableError` if the system does not support
    *sendfile* syscall and *fallback* is ``False``.
 
    .. versionadded:: 3.7
@@ -980,6 +980,18 @@ Handle
       .. versionadded:: 3.7
 
 
+SendfileNotAvailableError
+-------------------------
+
+
+.. exception:: SendfileNotAvailableError
+
+   Sendfile syscall is not available, subclass of :exc:`RuntimeError`.
+
+   Raised if the OS does not support senfile syscall for
+   given socket or file type.
+
+
 Event loop examples
 -------------------
 
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index b6a9384d95b..00c84a835c8 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -154,10 +154,6 @@ def _run_until_complete_cb(fut):
     futures._get_loop(fut).stop()
 
 
-class _SendfileNotAvailable(RuntimeError):
-    pass
-
-
 class Server(events.AbstractServer):
 
     def __init__(self, loop, sockets):
@@ -659,17 +655,16 @@ def _getaddrinfo_debug(self, host, port, family, type, proto, flags):
         try:
             return await self._sock_sendfile_native(sock, file,
                                                     offset, count)
-        except _SendfileNotAvailable as exc:
-            if fallback:
-                return await self._sock_sendfile_fallback(sock, file,
-                                                          offset, count)
-            else:
-                raise RuntimeError(exc.args[0]) from None
+        except events.SendfileNotAvailableError as exc:
+            if not fallback:
+                raise
+        return await self._sock_sendfile_fallback(sock, file,
+                                                  offset, count)
 
     async def _sock_sendfile_native(self, sock, file, offset, count):
         # NB: sendfile syscall is not supported for SSL sockets and
         # non-mmap files even if sendfile is supported by OS
-        raise _SendfileNotAvailable(
+        raise events.SendfileNotAvailableError(
             f"syscall sendfile is not available for socket {sock!r} "
             "and file {file!r} combination")
 
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py
index b06721f3b03..d5365dc480d 100644
--- a/Lib/asyncio/events.py
+++ b/Lib/asyncio/events.py
@@ -3,7 +3,7 @@
 __all__ = (
     'AbstractEventLoopPolicy',
     'AbstractEventLoop', 'AbstractServer',
-    'Handle', 'TimerHandle',
+    'Handle', 'TimerHandle', 'SendfileNotAvailableError',
     'get_event_loop_policy', 'set_event_loop_policy',
     'get_event_loop', 'set_event_loop', 'new_event_loop',
     'get_child_watcher', 'set_child_watcher',
@@ -20,6 +20,14 @@
 from . import format_helpers
 
 
+class SendfileNotAvailableError(RuntimeError):
+    """Sendfile syscall is not available.
+
+    Raised if OS does not support senfile syscall for given socket or
+    file type.
+    """
+
+
 class Handle:
     """Object returned by callback registration methods."""
 
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index f40ef12f265..028a0ca8f83 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -313,16 +313,16 @@ def _child_watcher_callback(self, pid, returncode, transp):
         try:
             os.sendfile
         except AttributeError as exc:
-            raise base_events._SendfileNotAvailable(
+            raise events.SendfileNotAvailableError(
                 "os.sendfile() is not available")
         try:
             fileno = file.fileno()
         except (AttributeError, io.UnsupportedOperation) as err:
-            raise base_events._SendfileNotAvailable("not a regular file")
+            raise events.SendfileNotAvailableError("not a regular file")
         try:
             fsize = os.fstat(fileno).st_size
         except OSError as err:
-            raise base_events._SendfileNotAvailable("not a regular file")
+            raise events.SendfileNotAvailableError("not a regular file")
         blocksize = count if count else fsize
         if not blocksize:
             return 0  # empty file
@@ -365,7 +365,7 @@ def _sock_sendfile_native_impl(self, fut, registered_fd, sock, fileno,
                 # one being 'file' is not a regular mmap(2)-like
                 # file, in which case we'll fall back on using
                 # plain send().
-                err = base_events._SendfileNotAvailable(
+                err = events.SendfileNotAvailableError(
                     "os.sendfile call failed")
                 self._sock_sendfile_update_filepos(fileno, offset, total_sent)
                 fut.set_exception(err)
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
index 085124f5372..fc3b81096da 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -14,6 +14,7 @@
 import asyncio
 from asyncio import base_events
 from asyncio import constants
+from asyncio import events
 from test.test_asyncio import utils as test_utils
 from test import support
 from test.support.script_helper import assert_python_ok
@@ -1860,7 +1861,7 @@ def cleanup():
     def test__sock_sendfile_native_failure(self):
         sock, proto = self.prepare()
 
-        with self.assertRaisesRegex(base_events._SendfileNotAvailable,
+        with self.assertRaisesRegex(events.SendfileNotAvailableError,
                                     "sendfile is not available"):
             self.run_loop(self.loop._sock_sendfile_native(sock, self.file,
                                                           0, None))
@@ -1871,7 +1872,7 @@ def test__sock_sendfile_native_failure(self):
     def test_sock_sendfile_no_fallback(self):
         sock, proto = self.prepare()
 
-        with self.assertRaisesRegex(RuntimeError,
+        with self.assertRaisesRegex(events.SendfileNotAvailableError,
                                     "sendfile is not available"):
             self.run_loop(self.loop.sock_sendfile(sock, self.file,
                                                   fallback=False))
diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py
index 4e2b76bb472..8646bf765e9 100644
--- a/Lib/test/test_asyncio/test_unix_events.py
+++ b/Lib/test/test_asyncio/test_unix_events.py
@@ -23,6 +23,7 @@
 import asyncio
 from asyncio import log
 from asyncio import base_events
+from asyncio import events
 from asyncio import unix_events
 from test.test_asyncio import utils as test_utils
 
@@ -517,7 +518,7 @@ def test_with_offset_and_count(self):
     def test_sendfile_not_available(self):
         sock, proto = self.prepare()
         with mock.patch('asyncio.unix_events.os', spec=[]):
-            with self.assertRaisesRegex(base_events._SendfileNotAvailable,
+            with self.assertRaisesRegex(events.SendfileNotAvailableError,
                                         "os[.]sendfile[(][)] is not available"):
                 self.run_loop(self.loop._sock_sendfile_native(sock, self.file,
                                                               0, None))
@@ -526,7 +527,7 @@ def test_sendfile_not_available(self):
     def test_sendfile_not_a_file(self):
         sock, proto = self.prepare()
         f = object()
-        with self.assertRaisesRegex(base_events._SendfileNotAvailable,
+        with self.assertRaisesRegex(events.SendfileNotAvailableError,
                                     "not a regular file"):
             self.run_loop(self.loop._sock_sendfile_native(sock, f,
                                                           0, None))
@@ -535,7 +536,7 @@ def test_sendfile_not_a_file(self):
     def test_sendfile_iobuffer(self):
         sock, proto = self.prepare()
         f = io.BytesIO()
-        with self.assertRaisesRegex(base_events._SendfileNotAvailable,
+        with self.assertRaisesRegex(events.SendfileNotAvailableError,
                                     "not a regular file"):
             self.run_loop(self.loop._sock_sendfile_native(sock, f,
                                                           0, None))
@@ -545,7 +546,7 @@ def test_sendfile_not_regular_file(self):
         sock, proto = self.prepare()
         f = mock.Mock()
         f.fileno.return_value = -1
-        with self.assertRaisesRegex(base_events._SendfileNotAvailable,
+        with self.assertRaisesRegex(events.SendfileNotAvailableError,
                                     "not a regular file"):
             self.run_loop(self.loop._sock_sendfile_native(sock, f,
                                                           0, None))
@@ -631,7 +632,7 @@ def test_os_error_first_call(self):
         with self.assertRaises(KeyError):
             self.loop._selector.get_key(sock)
         exc = fut.exception()
-        self.assertIsInstance(exc, base_events._SendfileNotAvailable)
+        self.assertIsInstance(exc, events.SendfileNotAvailableError)
         self.assertEqual(0, self.file.tell())
 
     def test_os_error_next_call(self):
@@ -656,7 +657,7 @@ def test_exception(self):
 
         fileno = self.file.fileno()
         fut = self.loop.create_future()
-        err = RuntimeError()
+        err = events.SendfileNotAvailableError()
         with mock.patch('os.sendfile', side_effect=err):
             self.loop._sock_sendfile_native_impl(fut, sock.fileno(),
                                                  sock, fileno,



More information about the Python-checkins mailing list