bpo-32622: Enforce sendfile fallback policy for FALLBACK transports (#5364)
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index f532dc4..7442bf2 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -1035,7 +1035,12 @@
except events.SendfileNotAvailableError as exc:
if not fallback:
raise
- # the mode is FALLBACK or fallback is True
+
+ if not fallback:
+ raise RuntimeError(
+ f"fallback is disabled and native sendfile is not "
+ f"supported for transport {transport!r}")
+
return await self._sendfile_fallback(transport, file,
offset, count)
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index 0981bd6..b66d91d 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -27,6 +27,7 @@
import asyncio
from asyncio import base_events
+from asyncio import constants
from asyncio import coroutines
from asyncio import events
from asyncio import proactor_events
@@ -2381,6 +2382,14 @@
ret = self.run_loop(t)
self.assertEqual(ret, len(self.DATA))
+ def test_sendfile_no_fallback_for_fallback_transport(self):
+ transport = mock.Mock()
+ transport.is_closing.side_effect = lambda: False
+ transport._sendfile_compatible = constants._SendfileMode.FALLBACK
+ with self.assertRaisesRegex(RuntimeError, 'fallback is disabled'):
+ self.loop.run_until_complete(
+ self.loop.sendfile(transport, None, fallback=False))
+
if sys.platform == 'win32':