mirror of
https://github.com/python/cpython.git
synced 2025-12-23 09:19:18 +00:00
bpo-32410: Make SendfileNotAvailableError exception public (#5243)
This commit is contained in:
parent
2507e29a9e
commit
7464e87a65
6 changed files with 42 additions and 25 deletions
|
|
@ -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
|
||||
-------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ import threading
|
|||
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."""
|
||||
|
||||
|
|
|
|||
|
|
@ -313,16 +313,16 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
|
|||
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 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
|
|||
# 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)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ from unittest import mock
|
|||
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 @@ class BaseLoopSendfileTests(test_utils.TestCase):
|
|||
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 @@ class BaseLoopSendfileTests(test_utils.TestCase):
|
|||
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))
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ if sys.platform == 'win32':
|
|||
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 @@ class SelectorEventLoopUnixSockSendfileTests(test_utils.TestCase):
|
|||
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 @@ class SelectorEventLoopUnixSockSendfileTests(test_utils.TestCase):
|
|||
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 @@ class SelectorEventLoopUnixSockSendfileTests(test_utils.TestCase):
|
|||
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 @@ class SelectorEventLoopUnixSockSendfileTests(test_utils.TestCase):
|
|||
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 @@ class SelectorEventLoopUnixSockSendfileTests(test_utils.TestCase):
|
|||
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 @@ class SelectorEventLoopUnixSockSendfileTests(test_utils.TestCase):
|
|||
|
||||
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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue