From c8af302c3af0abb5bfd65ece24de36154937c642 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 22 Nov 2016 22:53:18 +0100 Subject: Issue #28770: Update python-gdb.py for fastcalls Frame.is_other_python_frame() now also handles _PyCFunction_FastCallDict() frames. Thanks to the new code to handle fast calls, python-gdb.py is now also able to detect the frame. (grafted from f41d02d7da373ccaff97a42b66b051260bd55996) --- Lib/test/test_gdb.py | 20 ++++++++++---------- Tools/gdb/libpython.py | 47 +++++++++++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 2bd4457..60f1d92 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -679,7 +679,7 @@ class StackNavigationTests(DebuggerTests): def test_pyup_command(self): 'Verify that the "py-up" command works' bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up']) + cmds_after_breakpoint=['py-up', 'py-up']) self.assertMultilineMatches(bt, r'''^.* #[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\) @@ -698,7 +698,7 @@ $''') def test_up_at_top(self): 'Verify handling of "py-up" at the top of the stack' bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up'] * 4) + cmds_after_breakpoint=['py-up'] * 5) self.assertEndsWith(bt, 'Unable to find an older python frame\n') @@ -708,7 +708,7 @@ $''') def test_up_then_down(self): 'Verify "py-up" followed by "py-down"' bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up', 'py-down']) + cmds_after_breakpoint=['py-up', 'py-up', 'py-down']) self.assertMultilineMatches(bt, r'''^.* #[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\) @@ -727,6 +727,7 @@ class PyBtTests(DebuggerTests): self.assertMultilineMatches(bt, r'''^.* Traceback \(most recent call first\): + File ".*gdb_sample.py", line 10, in baz id\(42\) File ".*gdb_sample.py", line 7, in bar @@ -815,7 +816,6 @@ id(42) ) self.assertIn('Garbage-collecting', gdb_output) - @unittest.skip("FIXME: builtin method is not shown in py-bt and py-bt-full") @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") # Some older versions of gdb will fail with @@ -854,7 +854,7 @@ class PyPrintTests(DebuggerTests): def test_basic_command(self): 'Verify that the "py-print" command works' bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-print args']) + cmds_after_breakpoint=['py-up', 'py-print args']) self.assertMultilineMatches(bt, r".*\nlocal 'args' = \(1, 2, 3\)\n.*") @@ -863,7 +863,7 @@ class PyPrintTests(DebuggerTests): @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") def test_print_after_up(self): bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up', 'py-print c', 'py-print b', 'py-print a']) + cmds_after_breakpoint=['py-up', 'py-up', 'py-print c', 'py-print b', 'py-print a']) self.assertMultilineMatches(bt, r".*\nlocal 'c' = 3\nlocal 'b' = 2\nlocal 'a' = 1\n.*") @@ -871,7 +871,7 @@ class PyPrintTests(DebuggerTests): "Python was compiled with optimizations") def test_printing_global(self): bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-print __name__']) + cmds_after_breakpoint=['py-up', 'py-print __name__']) self.assertMultilineMatches(bt, r".*\nglobal '__name__' = '__main__'\n.*") @@ -879,7 +879,7 @@ class PyPrintTests(DebuggerTests): "Python was compiled with optimizations") def test_printing_builtin(self): bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-print len']) + cmds_after_breakpoint=['py-up', 'py-print len']) self.assertMultilineMatches(bt, r".*\nbuiltin 'len' = \n.*") @@ -888,7 +888,7 @@ class PyLocalsTests(DebuggerTests): "Python was compiled with optimizations") def test_basic_command(self): bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-locals']) + cmds_after_breakpoint=['py-up', 'py-locals']) self.assertMultilineMatches(bt, r".*\nargs = \(1, 2, 3\)\n.*") @@ -897,7 +897,7 @@ class PyLocalsTests(DebuggerTests): "Python was compiled with optimizations") def test_locals_after_up(self): bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up', 'py-locals']) + cmds_after_breakpoint=['py-up', 'py-up', 'py-locals']) self.assertMultilineMatches(bt, r".*\na = 1\nb = 2\nc = 3\n.*") diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index e4d2c1e..798b062 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1492,23 +1492,38 @@ class Frame(object): ''' if self.is_waiting_for_gil(): return 'Waiting for the GIL' - elif self.is_gc_collect(): + + if self.is_gc_collect(): return 'Garbage-collecting' - else: - # Detect invocations of PyCFunction instances: - older = self.older() - if older and older._gdbframe.name() == 'PyCFunction_Call': - # Within that frame: - # "func" is the local containing the PyObject* of the - # PyCFunctionObject instance - # "f" is the same value, but cast to (PyCFunctionObject*) - # "self" is the (PyObject*) of the 'self' - try: - # Use the prettyprinter for the func: - func = older._gdbframe.read_var('func') - return str(func) - except RuntimeError: - return 'PyCFunction invocation (unable to read "func")' + + # Detect invocations of PyCFunction instances: + older = self.older() + if not older: + return False + + caller = older._gdbframe.name() + if not caller: + return False + + if caller == 'PyCFunction_Call': + # Within that frame: + # "func" is the local containing the PyObject* of the + # PyCFunctionObject instance + # "f" is the same value, but cast to (PyCFunctionObject*) + # "self" is the (PyObject*) of the 'self' + try: + # Use the prettyprinter for the func: + func = older._gdbframe.read_var('func') + return str(func) + except RuntimeError: + return 'PyCFunction invocation (unable to read "func")' + + elif caller == '_PyCFunction_FastCallDict': + try: + func = older._gdbframe.read_var('func_obj') + return str(func) + except RuntimeError: + return 'PyCFunction invocation (unable to read "func_obj")' # This frame isn't worth reporting: return False -- cgit v0.12 From 7ae5c9691b6bdc3516063667345563a010758ce3 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Fri, 16 Dec 2016 11:51:57 -0500 Subject: Merge 3.5 (issue #28990) --- Lib/asyncio/sslproto.py | 1 + Lib/test/test_asyncio/test_sslproto.py | 10 ++++++++++ Misc/NEWS | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 991c77b..7ad28d6 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -480,6 +480,7 @@ class SSLProtocol(protocols.Protocol): self._loop.call_soon(self._app_protocol.connection_lost, exc) self._transport = None self._app_transport = None + self._wakeup_waiter(exc) def pause_writing(self): """Called when the low-level transport's buffer goes over diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 0ca6d1b..59ff0f6 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -85,5 +85,15 @@ class SslProtoHandshakeTests(test_utils.TestCase): # Restore error logging. log.logger.setLevel(log_level) + def test_connection_lost(self): + # From issue #472. + # yield from waiter hang if lost_connection was called. + waiter = asyncio.Future(loop=self.loop) + ssl_proto = self.ssl_protocol(waiter) + self.connection_made(ssl_proto) + ssl_proto.connection_lost(ConnectionAbortedError) + test_utils.run_briefly(self.loop) + self.assertIsInstance(waiter.exception(), ConnectionAbortedError) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS index 5cf929f..dc8acc8 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -14,6 +14,10 @@ Core and Builtins must not convert combined table into split table. Patch written by INADA Naoki. +- Issue #28990: Fix SSL hanging if connection is closed before handshake + completed. + (Patch by HoHo-Ho) + Windows ------- -- cgit v0.12 From f6105a55cf148281105c5e5116560976a2e33677 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Fri, 16 Dec 2016 15:29:12 -0500 Subject: Tidy Misc/NEWS for 3.6.0rc1+ cherrypicks. --- Misc/NEWS | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index dc8acc8..26e3486 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -14,14 +14,18 @@ Core and Builtins must not convert combined table into split table. Patch written by INADA Naoki. -- Issue #28990: Fix SSL hanging if connection is closed before handshake - completed. - (Patch by HoHo-Ho) +- Issue #28990: Fix asynchio SSL hanging if connection is closed before + handshake is completed. (Patch by HoHo-Ho) + +Tools/Demos +----------- + +- Issue #28770: Fix python-gdb.py for fastcalls. Windows ------- -- Issue #28896: Deprecate WindowsRegistryFinder +- Issue #28896: Deprecate WindowsRegistryFinder. Build ----- -- cgit v0.12 From 1e9aba51e20f57c5dd7a0d5f0944e11aad7646ca Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Fri, 16 Dec 2016 16:33:41 -0500 Subject: Update pydoc topics for 3.6.0rc2 --- Lib/pydoc_data/topics.py | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index c7fac33..ad3fa25 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Tue Dec 6 18:51:51 2016 +# Autogenerated by Sphinx on Fri Dec 16 16:33:16 2016 topics = {'assert': '\n' 'The "assert" statement\n' '**********************\n' @@ -2613,7 +2613,8 @@ topics = {'assert': '\n' 'functions, even if they do not contain "await" or "async" ' 'keywords.\n' '\n' - 'It is a "SyntaxError" to use "yield" expressions in "async def"\n' + 'It is a "SyntaxError" to use "yield from" expressions in "async ' + 'def"\n' 'coroutines.\n' '\n' 'An example of a coroutine function:\n' @@ -7087,7 +7088,14 @@ topics = {'assert': '\n' 'generator is done and will cause "StopIteration" to be raised. ' 'The\n' 'returned value (if any) is used as an argument to construct\n' - '"StopIteration" and becomes the "StopIteration.value" attribute.\n', + '"StopIteration" and becomes the "StopIteration.value" attribute.\n' + '\n' + 'In an asynchronous generator function, an empty "return" ' + 'statement\n' + 'indicates that the asynchronous generator is done and will cause\n' + '"StopAsyncIteration" to be raised. A non-empty "return" statement ' + 'is\n' + 'a syntax error in an asynchronous generator function.\n', 'sequence-types': '\n' 'Emulating container types\n' '*************************\n' @@ -11097,6 +11105,27 @@ topics = {'assert': '\n' 'statements.\n' ' See also the Coroutine Objects section.\n' '\n' + ' Asynchronous generator functions\n' + ' A function or method which is defined using "async def" and\n' + ' which uses the "yield" statement is called a *asynchronous\n' + ' generator function*. Such a function, when called, returns ' + 'an\n' + ' asynchronous iterator object which can be used in an "async ' + 'for"\n' + ' statement to execute the body of the function.\n' + '\n' + ' Calling the asynchronous iterator\'s "aiterator.__anext__()"\n' + ' method will return an *awaitable* which when awaited will\n' + ' execute until it provides a value using the "yield" ' + 'expression.\n' + ' When the function executes an empty "return" statement or ' + 'falls\n' + ' off the end, a "StopAsyncIteration" exception is raised and ' + 'the\n' + ' asynchronous iterator will have reached the end of the set ' + 'of\n' + ' values to be yielded.\n' + '\n' ' Built-in functions\n' ' A built-in function object is a wrapper around a C function.\n' ' Examples of built-in functions are "len()" and "math.sin()"\n' -- cgit v0.12 From f7b280956df077b90c5983eeabc8accdbb0aeb8d Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Fri, 16 Dec 2016 16:40:10 -0500 Subject: Version bump for 3.6.0rc2 --- Include/patchlevel.h | 4 ++-- Misc/NEWS | 2 +- README | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h index f59e12a..1f481b1 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 6 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_SERIAL 2 /* Version as a string */ -#define PY_VERSION "3.6.0rc1+" +#define PY_VERSION "3.6.0rc2" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Misc/NEWS b/Misc/NEWS index 26e3486..dc2ac8d4 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -5,7 +5,7 @@ Python News What's New in Python 3.6.0 release candidate 2 ============================================== -*Release date: XXXX-XX-XX* +*Release date: 2016-12-16* Core and Builtins ----------------- diff --git a/README b/README index f833c14..5d19ff1 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -This is Python version 3.6.0 release candidate 1 +This is Python version 3.6.0 release candidate 2 ================================================ Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -- cgit v0.12 From add9d43e4908f921a367e81d6170a9554cb47461 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Fri, 16 Dec 2016 16:42:30 -0500 Subject: Added tag v3.6.0rc2 for changeset 800a67f7806d --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 2c4a2c7..f49b483 100644 --- a/.hgtags +++ b/.hgtags @@ -175,3 +175,4 @@ b9fadc7d1c3f9c3c77f32f35afbe1a1cc38070e6 v3.6.0b2 8345e066c0ed713c3e510cbc8fafc1c38d6d306b v3.6.0b3 18496abdb3d5c2730a659b747a89261b2219fecf v3.6.0b4 29a273eee9a523ee178f6a66c4ac9d317c8fc84f v3.6.0rc1 +800a67f7806de45a7abd5273359e704bf147c079 v3.6.0rc2 -- cgit v0.12