mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
bpo-32047: -X dev enables asyncio debug mode (#4418)
The new -X dev command line option now also enables asyncio debug mode.
This commit is contained in:
parent
04dee27208
commit
44862df2ee
6 changed files with 42 additions and 18 deletions
|
@ -21,7 +21,9 @@ enable *debug mode*.
|
||||||
To enable all debug checks for an application:
|
To enable all debug checks for an application:
|
||||||
|
|
||||||
* Enable the asyncio debug mode globally by setting the environment variable
|
* 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
|
* Set the log level of the :ref:`asyncio logger <asyncio-logger>` to
|
||||||
:py:data:`logging.DEBUG`. For example, call
|
:py:data:`logging.DEBUG`. For example, call
|
||||||
``logging.basicConfig(level=logging.DEBUG)`` at startup.
|
``logging.basicConfig(level=logging.DEBUG)`` at startup.
|
||||||
|
@ -42,6 +44,11 @@ Examples debug checks:
|
||||||
* :exc:`ResourceWarning` warnings are emitted when transports and event loops
|
* :exc:`ResourceWarning` warnings are emitted when transports and event loops
|
||||||
are :ref:`not closed explicitly <asyncio-close-transports>`.
|
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::
|
.. seealso::
|
||||||
|
|
||||||
The :meth:`AbstractEventLoop.set_debug` method and the :ref:`asyncio logger
|
The :meth:`AbstractEventLoop.set_debug` method and the :ref:`asyncio logger
|
||||||
|
|
|
@ -414,16 +414,18 @@ Miscellaneous options
|
||||||
application. Typical usage is ``python3 -X importtime -c 'import
|
application. Typical usage is ``python3 -X importtime -c 'import
|
||||||
asyncio'``. See also :envvar:`PYTHONPROFILEIMPORTTIME`.
|
asyncio'``. See also :envvar:`PYTHONPROFILEIMPORTTIME`.
|
||||||
* ``-X dev`` enables the "developer mode": enable debug checks at runtime.
|
* ``-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`
|
-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
|
* Add ``default`` warnings option. For example, display
|
||||||
:exc:`DeprecationWarning` and :exc:`ResourceWarning` warnings.
|
:exc:`DeprecationWarning` and :exc:`ResourceWarning` warnings.
|
||||||
* Install debug hooks on memory allocators as if :envvar:`PYTHONMALLOC`
|
* Install debug hooks on memory allocators: see the
|
||||||
is set to ``debug``.
|
:c:func:`PyMem_SetupDebugHooks` C function.
|
||||||
* Enable the :mod:`faulthandler` module to dump the Python traceback
|
* Enable the :mod:`faulthandler` module to dump the Python traceback
|
||||||
on a crash.
|
on a crash.
|
||||||
|
* Enable :ref:`asyncio debug mode <asyncio-debug-mode>`.
|
||||||
|
|
||||||
It also allows passing arbitrary values and retrieving them through the
|
It also allows passing arbitrary values and retrieving them through the
|
||||||
:data:`sys._xoptions` dictionary.
|
:data:`sys._xoptions` dictionary.
|
||||||
|
|
|
@ -244,8 +244,7 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
self._thread_id = None
|
self._thread_id = None
|
||||||
self._clock_resolution = time.get_clock_info('monotonic').resolution
|
self._clock_resolution = time.get_clock_info('monotonic').resolution
|
||||||
self._exception_handler = None
|
self._exception_handler = None
|
||||||
self.set_debug((not sys.flags.ignore_environment
|
self.set_debug(coroutines._is_debug_mode())
|
||||||
and bool(os.environ.get('PYTHONASYNCIODEBUG'))))
|
|
||||||
# In debug mode, if the execution of a callback or a step of a task
|
# 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.
|
# exceed this duration in seconds, the slow callback/task is logged.
|
||||||
self.slow_callback_duration = 0.1
|
self.slow_callback_duration = 0.1
|
||||||
|
|
|
@ -19,17 +19,25 @@ from .log import logger
|
||||||
# Opcode of "yield from" instruction
|
# Opcode of "yield from" instruction
|
||||||
_YIELD_FROM = opcode.opmap['YIELD_FROM']
|
_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
|
def _is_debug_mode():
|
||||||
# instance will log a message when the generator is never iterated
|
# If you set _DEBUG to true, @coroutine will wrap the resulting
|
||||||
# over, which may happen when you forget to use "yield from" with a
|
# generator objects in a CoroWrapper instance (defined below). That
|
||||||
# coroutine call. Note that the value of the _DEBUG flag is taken
|
# instance will log a message when the generator is never iterated
|
||||||
# when the decorator is used, so to be of any use it must be set
|
# over, which may happen when you forget to use "yield from" with a
|
||||||
# before you define your coroutines. A downside of using this feature
|
# coroutine call. Note that the value of the _DEBUG flag is taken
|
||||||
# is that tracebacks show entries for the CoroWrapper.__next__ method
|
# when the decorator is used, so to be of any use it must be set
|
||||||
# when _DEBUG is true.
|
# before you define your coroutines. A downside of using this feature
|
||||||
_DEBUG = (not sys.flags.ignore_environment and
|
# is that tracebacks show entries for the CoroWrapper.__next__ method
|
||||||
bool(os.environ.get('PYTHONASYNCIODEBUG')))
|
# 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:
|
try:
|
||||||
|
|
|
@ -822,6 +822,10 @@ class BaseEventLoopTests(test_utils.TestCase):
|
||||||
PYTHONASYNCIODEBUG='1')
|
PYTHONASYNCIODEBUG='1')
|
||||||
self.assertEqual(stdout.rstrip(), b'False')
|
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):
|
def test_create_task(self):
|
||||||
class MyTask(asyncio.Task):
|
class MyTask(asyncio.Task):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -2350,6 +2350,10 @@ class GatherTestsBase:
|
||||||
PYTHONPATH=aio_path)
|
PYTHONPATH=aio_path)
|
||||||
self.assertEqual(stdout.rstrip(), b'False')
|
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):
|
class FutureGatherTests(GatherTestsBase, test_utils.TestCase):
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue