]> granicus.if.org Git - python/commitdiff
bpo-34075: Deprecate non-ThreadPoolExecutor in loop.set_default_executor() (GH-8533)
authorElvis Pranskevichus <elvis@magic.io>
Mon, 30 Jul 2018 10:42:43 +0000 (11:42 +0100)
committerVictor Stinner <vstinner@redhat.com>
Mon, 30 Jul 2018 10:42:43 +0000 (12:42 +0200)
Various asyncio internals expect that the default executor is a
`ThreadPoolExecutor`, so deprecate passing anything else to
`loop.set_default_executor()`.

Doc/library/asyncio-eventloop.rst
Doc/whatsnew/3.8.rst
Lib/asyncio/base_events.py
Lib/test/test_asyncio/test_base_events.py
Misc/NEWS.d/next/Library/2018-07-28-11-49-21.bpo-34075.9u1bO-.rst [new file with mode: 0644]

index 317f3fb85c54811437fb45f638b6e1ff9097ec75..cf7b6d88725e411f299825e31ff61ef8c9deb955 100644 (file)
@@ -906,7 +906,14 @@ pool of processes). By default, an event loop uses a thread pool executor
 
 .. method:: AbstractEventLoop.set_default_executor(executor)
 
-   Set the default executor used by :meth:`run_in_executor`.
+   Set *executor* as the default executor used by :meth:`run_in_executor`.
+   *executor* should be an instance of
+   :class:`~concurrent.futures.ThreadPoolExecutor`.
+
+   .. deprecated:: 3.8
+      Using an executor that is not an instance of
+      :class:`~concurrent.futures.ThreadPoolExecutor` is deprecated and
+      will trigger an error in Python 3.9.
 
 
 Error Handling API
index 3f515357e953fa2d64783f3eafa84f606aeb8300..bab1e06bedd1ecdd4fcf1ba985461641146903f4 100644 (file)
@@ -164,6 +164,12 @@ Deprecated
   They will be removed in Python 3.9.
   (Contributed by Serhiy Storchaka in :issue:`29209`.)
 
+* Passing an object that is not an instance of
+  :class:`concurrent.futures.ThreadPoolExecutor` to
+  :meth:`asyncio.AbstractEventLoop.set_default_executor()` is
+  deprecated and will be prohibited in Python 3.9.
+  (Contributed by Elvis Pranskevichus in :issue:`34075`.)
+
 
 Removed
 =======
index dc0ca3f02b9bf6323cf746cb0f2710cab3354556..75989a7641b8bbfd4e20848ae220dbad00da24e6 100644 (file)
@@ -741,6 +741,12 @@ class BaseEventLoop(events.AbstractEventLoop):
             executor.submit(func, *args), loop=self)
 
     def set_default_executor(self, executor):
+        if not isinstance(executor, concurrent.futures.ThreadPoolExecutor):
+            warnings.warn(
+                'Using the default executor that is not an instance of '
+                'ThreadPoolExecutor is deprecated and will be prohibited '
+                'in Python 3.9',
+                DeprecationWarning, 2)
         self._default_executor = executor
 
     def _getaddrinfo_debug(self, host, port, family, type, proto, flags):
index bda8cc6e3a821073e9da2ebbee739d234837f10a..f3ae1404487afa8aac30cf97a4fc256107dd1cd5 100644 (file)
@@ -1,5 +1,6 @@
 """Tests for base_events.py"""
 
+import concurrent.futures
 import errno
 import logging
 import math
@@ -211,10 +212,21 @@ class BaseEventLoopTests(test_utils.TestCase):
         self.assertFalse(self.loop._ready)
 
     def test_set_default_executor(self):
-        executor = mock.Mock()
+        class DummyExecutor(concurrent.futures.ThreadPoolExecutor):
+            def submit(self, fn, *args, **kwargs):
+                raise NotImplementedError(
+                    'cannot submit into a dummy executor')
+
+        executor = DummyExecutor()
         self.loop.set_default_executor(executor)
         self.assertIs(executor, self.loop._default_executor)
 
+    def test_set_default_executor_deprecation_warnings(self):
+        executor = mock.Mock()
+
+        with self.assertWarns(DeprecationWarning):
+            self.loop.set_default_executor(executor)
+
     def test_call_soon(self):
         def cb():
             pass
diff --git a/Misc/NEWS.d/next/Library/2018-07-28-11-49-21.bpo-34075.9u1bO-.rst b/Misc/NEWS.d/next/Library/2018-07-28-11-49-21.bpo-34075.9u1bO-.rst
new file mode 100644 (file)
index 0000000..799e68e
--- /dev/null
@@ -0,0 +1,2 @@
+Deprecate passing non-ThreadPoolExecutor instances to
+:meth:`AbstractEventLoop.set_default_executor`.