]> granicus.if.org Git - python/commitdiff
bpo-32047: -X dev enables asyncio debug mode (#4418)
authorVictor Stinner <victor.stinner@gmail.com>
Mon, 20 Nov 2017 15:14:07 +0000 (07:14 -0800)
committerGitHub <noreply@github.com>
Mon, 20 Nov 2017 15:14:07 +0000 (07:14 -0800)
The new -X dev command line option now also enables asyncio debug
mode.

Doc/library/asyncio-dev.rst
Doc/using/cmdline.rst
Lib/asyncio/base_events.py
Lib/asyncio/coroutines.py
Lib/test/test_asyncio/test_base_events.py
Lib/test/test_asyncio/test_tasks.py

index 1838eb95a7d52230336a56faa1c992003af8e8b0..b2ad87b5d020572c70cb9abe661252b422973919 100644 (file)
@@ -21,7 +21,9 @@ enable *debug mode*.
 To enable all debug checks for an application:
 
 * Enable the asyncio debug mode globally by setting the environment variable
-  :envvar:`PYTHONASYNCIODEBUG` to ``1``, or by calling :meth:`AbstractEventLoop.set_debug`.
+  :envvar:`PYTHONASYNCIODEBUG` to ``1``, using ``-X dev`` command line option
+  (see the :option:`-X` option), or by calling
+  :meth:`AbstractEventLoop.set_debug`.
 * Set the log level of the :ref:`asyncio logger <asyncio-logger>` to
   :py:data:`logging.DEBUG`. For example, call
   ``logging.basicConfig(level=logging.DEBUG)`` at startup.
@@ -42,6 +44,11 @@ Examples debug checks:
 * :exc:`ResourceWarning` warnings are emitted when transports and event loops
   are :ref:`not closed explicitly <asyncio-close-transports>`.
 
+.. versionchanged:: 3.7
+
+   The new ``-X dev`` command line option can now also be used to enable
+   the debug mode.
+
 .. seealso::
 
    The :meth:`AbstractEventLoop.set_debug` method and the :ref:`asyncio logger
index 01869d117f7cd8121ffa68ca08852fc19978ad86..bf27c1e2b56c4cd6ef88faf6ef864b2c4aa584e1 100644 (file)
@@ -414,16 +414,18 @@ Miscellaneous options
      application.  Typical usage is ``python3 -X importtime -c 'import
      asyncio'``.  See also :envvar:`PYTHONPROFILEIMPORTTIME`.
    * ``-X dev`` enables the "developer mode": enable debug checks at runtime.
-     In short, ``python3 -X dev ...`` behaves as ``PYTHONMALLOC=debug python3
+     In short, ``python3 -X dev ...`` behaves as ``PYTHONMALLOC=debug PYTHONASYNCIODEBUG=1 python3
      -W default -X faulthandler ...``, except that the :envvar:`PYTHONMALLOC`
-     environment variable is not set in practice. Developer mode:
+     and :envvar:`PYTHONASYNCIODEBUG` environment variables are not set in
+     practice. Developer mode:
 
      * Add ``default`` warnings option. For example, display
        :exc:`DeprecationWarning` and :exc:`ResourceWarning` warnings.
-     * Install debug hooks on memory allocators as if :envvar:`PYTHONMALLOC`
-       is set to ``debug``.
+     * Install debug hooks on memory allocators: see the
+       :c:func:`PyMem_SetupDebugHooks` C function.
      * Enable the :mod:`faulthandler` module to dump the Python traceback
        on a crash.
+     * Enable :ref:`asyncio debug mode <asyncio-debug-mode>`.
 
    It also allows passing arbitrary values and retrieving them through the
    :data:`sys._xoptions` dictionary.
index b94856c93936183513699e0eade4907107069608..bb04aef76e874e1cb9fc5bab0d8f719284279db7 100644 (file)
@@ -244,8 +244,7 @@ class BaseEventLoop(events.AbstractEventLoop):
         self._thread_id = None
         self._clock_resolution = time.get_clock_info('monotonic').resolution
         self._exception_handler = None
-        self.set_debug((not sys.flags.ignore_environment
-                        and bool(os.environ.get('PYTHONASYNCIODEBUG'))))
+        self.set_debug(coroutines._is_debug_mode())
         # In debug mode, if the execution of a callback or a step of a task
         # exceed this duration in seconds, the slow callback/task is logged.
         self.slow_callback_duration = 0.1
index 520a309f846049e9b9bb719037e0a54f34798ace..a87c9f9b0b6b5778f6d89de500675db947306a53 100644 (file)
@@ -19,17 +19,25 @@ from .log import logger
 # Opcode of "yield from" instruction
 _YIELD_FROM = opcode.opmap['YIELD_FROM']
 
-# If you set _DEBUG to true, @coroutine will wrap the resulting
-# generator objects in a CoroWrapper instance (defined below).  That
-# instance will log a message when the generator is never iterated
-# over, which may happen when you forget to use "yield from" with a
-# coroutine call.  Note that the value of the _DEBUG flag is taken
-# when the decorator is used, so to be of any use it must be set
-# before you define your coroutines.  A downside of using this feature
-# is that tracebacks show entries for the CoroWrapper.__next__ method
-# when _DEBUG is true.
-_DEBUG = (not sys.flags.ignore_environment and
-          bool(os.environ.get('PYTHONASYNCIODEBUG')))
+
+def _is_debug_mode():
+    # If you set _DEBUG to true, @coroutine will wrap the resulting
+    # generator objects in a CoroWrapper instance (defined below).  That
+    # instance will log a message when the generator is never iterated
+    # over, which may happen when you forget to use "yield from" with a
+    # coroutine call.  Note that the value of the _DEBUG flag is taken
+    # when the decorator is used, so to be of any use it must be set
+    # before you define your coroutines.  A downside of using this feature
+    # is that tracebacks show entries for the CoroWrapper.__next__ method
+    # when _DEBUG is true.
+    debug = (not sys.flags.ignore_environment and
+             bool(os.environ.get('PYTHONASYNCIODEBUG')))
+    if hasattr(sys, '_xoptions') and 'dev' in sys._xoptions:
+        debug = True
+    return debug
+
+
+_DEBUG = _is_debug_mode()
 
 
 try:
index a25069efb5cdcbadadcdf8b828188cd770f89b01..98f2aef56276622670c830a11d2dce3860e214ac 100644 (file)
@@ -822,6 +822,10 @@ class BaseEventLoopTests(test_utils.TestCase):
                                                PYTHONASYNCIODEBUG='1')
         self.assertEqual(stdout.rstrip(), b'False')
 
+        sts, stdout, stderr = assert_python_ok('-E', '-X', 'dev',
+                                               '-c', code)
+        self.assertEqual(stdout.rstrip(), b'True')
+
     def test_create_task(self):
         class MyTask(asyncio.Task):
             pass
index 1d77f9f2c4d180a49d784304d2e0f87877a92758..f66f7f1e1706fb34f9a2d758bc4a8161057edb6e 100644 (file)
@@ -2350,6 +2350,10 @@ class GatherTestsBase:
                                                PYTHONPATH=aio_path)
         self.assertEqual(stdout.rstrip(), b'False')
 
+        sts, stdout, stderr = assert_python_ok('-E', '-X', 'dev',
+                                               '-c', code)
+        self.assertEqual(stdout.rstrip(), b'True')
+
 
 class FutureGatherTests(GatherTestsBase, test_utils.TestCase):