diff options
author | Charles-François Natali <cf.natali@gmail.com> | 2014-06-20 21:41:21 (GMT) |
---|---|---|
committer | Charles-François Natali <cf.natali@gmail.com> | 2014-06-20 21:41:21 (GMT) |
commit | 6315ffa339cabdab3a609dfcde51e47412732425 (patch) | |
tree | 43f2da247995b17a5c1f04033637fa53b6078048 | |
parent | 9dca5357cc4769c2708f0daece554bc3151993a2 (diff) | |
parent | 504f5c36ef2419cb0c56450c3a733499c4576456 (diff) | |
download | cpython-6315ffa339cabdab3a609dfcde51e47412732425.zip cpython-6315ffa339cabdab3a609dfcde51e47412732425.tar.gz cpython-6315ffa339cabdab3a609dfcde51e47412732425.tar.bz2 |
Merge.
-rw-r--r-- | Doc/library/runpy.rst | 6 | ||||
-rw-r--r-- | Lib/asyncio/base_events.py | 32 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_base_events.py | 28 | ||||
-rw-r--r-- | Lib/test/test_descr.py | 2 | ||||
-rw-r--r-- | Lib/test/test_pydoc.py | 2 | ||||
-rw-r--r-- | PCbuild/prepare_ssl.py | 2 |
6 files changed, 64 insertions, 8 deletions
diff --git a/Doc/library/runpy.rst b/Doc/library/runpy.rst index ee9fbcf..a764696 100644 --- a/Doc/library/runpy.rst +++ b/Doc/library/runpy.rst @@ -28,6 +28,9 @@ The :mod:`runpy` module provides two functions: .. function:: run_module(mod_name, init_globals=None, run_name=None, alter_sys=False) + .. index:: + module: __main__ + Execute the code of the specified module and return the resulting module globals dictionary. The module's code is first located using the standard import mechanism (refer to :pep:`302` for details) and then executed in a @@ -87,6 +90,9 @@ The :mod:`runpy` module provides two functions: .. function:: run_path(file_path, init_globals=None, run_name=None) + .. index:: + module: __main__ + Execute the code at the named filesystem location and return the resulting module globals dictionary. As with a script name supplied to the CPython command line, the supplied path may refer to a Python source file, a diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 9350989..9f9067e 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -17,6 +17,7 @@ to modify the meaning of the API call itself. import collections import concurrent.futures import heapq +import inspect import logging import socket import subprocess @@ -37,6 +38,15 @@ __all__ = ['BaseEventLoop', 'Server'] _MAX_WORKERS = 5 +def _format_handle(handle): + cb = handle._callback + if inspect.ismethod(cb) and isinstance(cb.__self__, tasks.Task): + # format the task + return repr(cb.__self__) + else: + return str(handle) + + class _StopError(BaseException): """Raised to stop the event loop.""" @@ -128,6 +138,9 @@ class BaseEventLoop(events.AbstractEventLoop): self._clock_resolution = time.get_clock_info('monotonic').resolution self._exception_handler = None self._debug = False + # 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 def __repr__(self): return ('<%s running=%s closed=%s debug=%s>' @@ -823,16 +836,16 @@ class BaseEventLoop(events.AbstractEventLoop): if logger.isEnabledFor(logging.INFO): t0 = self.time() event_list = self._selector.select(timeout) - t1 = self.time() - if t1-t0 >= 1: + dt = self.time() - t0 + if dt >= 1: level = logging.INFO else: level = logging.DEBUG if timeout is not None: logger.log(level, 'poll %.3f took %.3f seconds', - timeout, t1-t0) + timeout, dt) else: - logger.log(level, 'poll took %.3f seconds', t1-t0) + logger.log(level, 'poll took %.3f seconds', dt) else: event_list = self._selector.select(timeout) self._process_events(event_list) @@ -855,7 +868,16 @@ class BaseEventLoop(events.AbstractEventLoop): ntodo = len(self._ready) for i in range(ntodo): handle = self._ready.popleft() - if not handle._cancelled: + if handle._cancelled: + continue + if self._debug: + t0 = self.time() + handle._run() + dt = self.time() - t0 + if dt >= self.slow_callback_duration: + logger.warning('Executing %s took %.3f seconds', + _format_handle(handle), dt) + else: handle._run() handle = None # Needed to break cycles when an exception occurs. diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 059b41c..352af48 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -969,6 +969,34 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): with self.assertRaises(TypeError): self.loop.run_in_executor(None, coroutine_function) + @mock.patch('asyncio.base_events.logger') + def test_log_slow_callbacks(self, m_logger): + def stop_loop_cb(loop): + loop.stop() + + @asyncio.coroutine + def stop_loop_coro(loop): + yield from () + loop.stop() + + asyncio.set_event_loop(self.loop) + self.loop.set_debug(True) + self.loop.slow_callback_duration = 0.0 + + # slow callback + self.loop.call_soon(stop_loop_cb, self.loop) + self.loop.run_forever() + fmt, *args = m_logger.warning.call_args[0] + self.assertRegex(fmt % tuple(args), + "^Executing Handle.*stop_loop_cb.* took .* seconds$") + + # slow task + asyncio.async(stop_loop_coro(self.loop), loop=self.loop) + self.loop.run_forever() + fmt, *args = m_logger.warning.call_args[0] + self.assertRegex(fmt % tuple(args), + "^Executing Task.*stop_loop_coro.* took .* seconds$") + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index e65edb2..634ba7e 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1149,7 +1149,7 @@ order (MRO) for bases """ except (TypeError, UnicodeEncodeError): pass else: - raise TestFailed("[chr(128)] slots not caught") + self.fail("[chr(128)] slots not caught") # Test leaks class Counted(object): diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 542b433..8d85c14 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -746,7 +746,7 @@ class TestDescriptions(unittest.TestCase): try: pydoc.render_doc(name) except ImportError: - self.fail('finding the doc of {!r} failed'.format(o)) + self.fail('finding the doc of {!r} failed'.format(name)) for name in ('notbuiltins', 'strrr', 'strr.translate', 'str.trrrranslate', 'builtins.strrr', diff --git a/PCbuild/prepare_ssl.py b/PCbuild/prepare_ssl.py index f9f8c12..4f11ed9 100644 --- a/PCbuild/prepare_ssl.py +++ b/PCbuild/prepare_ssl.py @@ -186,7 +186,7 @@ def main(): ssl_dir = sys.argv[1] - if not os.path.exists(ssl_dir) and os.path.isdir(ssl_dir): + if not os.path.isdir(ssl_dir): print(ssl_dir, "is not an existing directory!") sys.exit(1) |