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

diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index b6a9384..00c84a8 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -154,10 +154,6 @@
     futures._get_loop(fut).stop()
 
 
-class _SendfileNotAvailable(RuntimeError):
-    pass
-
-
 class Server(events.AbstractServer):
 
     def __init__(self, loop, sockets):
@@ -659,17 +655,16 @@
         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 b06721f..d5365dc 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 f40ef12..028a0ca 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -313,16 +313,16 @@
         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 @@
                 # 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)