diff -r 6c5f9c6c25ea Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py Wed Sep 14 18:17:32 2016 +0300 +++ b/Lib/asyncio/tasks.py Wed Sep 14 18:31:13 2016 -0400 @@ -519,7 +519,7 @@ h.cancel() -def async(coro_or_future, *, loop=None): +def async_(coro_or_future, *, loop=None): """Wrap a coroutine in a future. If the argument is a Future, it is returned directly. @@ -532,6 +532,11 @@ return ensure_future(coro_or_future, loop=loop) +# Silence DeprecationWarning: +globals()['async'] = async_ +async_.__name__ = 'async' +del async_ + def ensure_future(coro_or_future, *, loop=None): """Wrap a coroutine or an awaitable in a future. diff -r 6c5f9c6c25ea Lib/test/test_coroutines.py --- a/Lib/test/test_coroutines.py Wed Sep 14 18:17:32 2016 +0300 +++ b/Lib/test/test_coroutines.py Wed Sep 14 18:31:13 2016 -0400 @@ -358,57 +358,110 @@ with self.subTest(code=code), self.assertRaises(SyntaxError): compile(code, "", "exec") + def test_badsyntax_2(self): + samples = [ + """def foo(): + await = 1 + """, + + """class Bar: + def async(): pass + """, + + """class Bar: + async = 1 + """, + + """class async: + pass + """, + + """class await: + pass + """, + + """import math as await""", + + """def async(): + pass""", + + """def foo(*, await=1): + pass""" + + """async = 1""", + + """print(await=1)""" + ] + + for code in samples: + with self.subTest(code=code), self.assertWarnsRegex( + DeprecationWarning, + "'await' will become reserved keywords"): + compile(code, "", "exec") + + def test_badsyntax_3(self): + with self.assertRaises(DeprecationWarning): + with warnings.catch_warnings(): + warnings.simplefilter("error") + compile("async = 1", "", "exec") + def test_goodsyntax_1(self): # Tests for issue 24619 - def foo(await): - async def foo(): pass - async def foo(): - pass - return await + 1 - self.assertEqual(foo(10), 11) + samples = [ + '''def foo(await): + async def foo(): pass + async def foo(): + pass + return await + 1 + ''', - def foo(await): - async def foo(): pass - async def foo(): pass - return await + 2 - self.assertEqual(foo(20), 22) + '''def foo(await): + async def foo(): pass + async def foo(): pass + return await + 1 + ''', - def foo(await): + '''def foo(await): - async def foo(): pass + async def foo(): pass - async def foo(): pass + async def foo(): pass - return await + 2 - self.assertEqual(foo(20), 22) + return await + 1 + ''', - def foo(await): - """spam""" - async def foo(): \ - pass - # 123 - async def foo(): pass - # 456 - return await + 2 - self.assertEqual(foo(20), 22) + '''def foo(await): + """spam""" + async def foo(): \ + pass + # 123 + async def foo(): pass + # 456 + return await + 1 + ''', - def foo(await): - def foo(): pass - def foo(): pass - async def bar(): return await_ - await_ = await - try: - bar().send(None) - except StopIteration as ex: - return ex.args[0] - self.assertEqual(foo(42), 42) + '''def foo(await): + def foo(): pass + def foo(): pass + async def bar(): return await_ + await_ = await + try: + bar().send(None) + except StopIteration as ex: + return ex.args[0] + 1 + ''' + ] - async def f(): - async def g(): pass - await z - await = 1 - self.assertTrue(inspect.iscoroutinefunction(f)) + for code in samples: + with self.subTest(code=code): + loc = {} + + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + exec(code, loc, loc) + + self.assertEqual(loc['foo'](10), 11) class TokenizerRegrTest(unittest.TestCase): diff -r 6c5f9c6c25ea Lib/test/test_grammar.py --- a/Lib/test/test_grammar.py Wed Sep 14 18:17:32 2016 +0300 +++ b/Lib/test/test_grammar.py Wed Sep 14 18:31:13 2016 -0400 @@ -1345,18 +1345,6 @@ self.assertEqual(m.other, 42) def test_async_await(self): - async = 1 - await = 2 - self.assertEqual(async, 1) - - def async(): - nonlocal await - await = 10 - async() - self.assertEqual(await, 10) - - self.assertFalse(bool(async.__code__.co_flags & inspect.CO_COROUTINE)) - async def test(): def sum(): pass diff -r 6c5f9c6c25ea Lib/xml/dom/xmlbuilder.py --- a/Lib/xml/dom/xmlbuilder.py Wed Sep 14 18:17:32 2016 +0300 +++ b/Lib/xml/dom/xmlbuilder.py Wed Sep 14 18:31:13 2016 -0400 @@ -353,14 +353,14 @@ class DocumentLS: """Mixin to create documents that conform to the load/save spec.""" - async = _AsyncDeprecatedProperty() async_ = False + locals()['async'] = _AsyncDeprecatedProperty() # Avoid DeprecationWarning def _get_async(self): return False - def _set_async(self, async): - if async: + def _set_async(self, flag): + if flag: raise xml.dom.NotSupportedErr( "asynchronous document loading is not supported") diff -r 6c5f9c6c25ea Python/ast.c --- a/Python/ast.c Wed Sep 14 18:17:32 2016 +0300 +++ b/Python/ast.c Wed Sep 14 18:31:13 2016 -0400 @@ -938,6 +938,26 @@ ast_error(c, n, "assignment to keyword"); return 1; } + if (PyUnicode_CompareWithASCIIString(name, "async") == 0 || + PyUnicode_CompareWithASCIIString(name, "await") == 0) + { + PyObject *message = PyUnicode_FromString( + "'async' and 'await' will become reserved keywords" + " in Python 3.7"); + if (message == NULL) { + return 1; + } + if (PyErr_WarnExplicitObject( + PyExc_DeprecationWarning, + message, + c->c_filename, + LINENO(n), + NULL, + NULL) < 0) + { + return 1; + } + } if (full_checks) { const char * const *p; for (p = FORBIDDEN; *p; p++) {