summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-11-20 15:14:07 (GMT)
committerGitHub <noreply@github.com>2017-11-20 15:14:07 (GMT)
commit44862df2eeec62adea20672b0fe2a5d3e160569e (patch)
treee8f66bbbd2b7769ca42a292f553a7ecacb29da57
parent04dee2720851ec39e831beaa3edc0c59f228f461 (diff)
downloadcpython-44862df2eeec62adea20672b0fe2a5d3e160569e.zip
cpython-44862df2eeec62adea20672b0fe2a5d3e160569e.tar.gz
cpython-44862df2eeec62adea20672b0fe2a5d3e160569e.tar.bz2
bpo-32047: -X dev enables asyncio debug mode (#4418)
The new -X dev command line option now also enables asyncio debug mode.
-rw-r--r--Doc/library/asyncio-dev.rst9
-rw-r--r--Doc/using/cmdline.rst10
-rw-r--r--Lib/asyncio/base_events.py3
-rw-r--r--Lib/asyncio/coroutines.py30
-rw-r--r--Lib/test/test_asyncio/test_base_events.py4
-rw-r--r--Lib/test/test_asyncio/test_tasks.py4
6 files changed, 42 insertions, 18 deletions
diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst
index 1838eb9..b2ad87b 100644
--- a/Doc/library/asyncio-dev.rst
+++ b/Doc/library/asyncio-dev.rst
@@ -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
diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst
index 01869d1..bf27c1e 100644
--- a/Doc/using/cmdline.rst
+++ b/Doc/using/cmdline.rst
@@ -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.
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index b94856c..bb04aef 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -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
diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py
index 520a309..a87c9f9 100644
--- a/Lib/asyncio/coroutines.py
+++ b/Lib/asyncio/coroutines.py
@@ -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:
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
index a25069e..98f2aef 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -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
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index 1d77f9f..f66f7f1 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -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):