From f315c1c01676bfabb5b1c6628642668f1ef436a6 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Thu, 23 Jul 2015 09:10:44 +0300 Subject: Issue #24687: Plug refleak on SyntaxError in function parameters annotations. --- Lib/test/test_coroutines.py | 4 ++++ Lib/test/test_grammar.py | 3 ++- Misc/NEWS | 3 +++ Python/compile.c | 27 +++++++++++++-------------- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 94994e5..14682ca 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -211,6 +211,10 @@ class AsyncBadSyntaxTest(unittest.TestCase): pass """, + """async def foo(a:await b): + pass + """, + """def baz(): async def foo(a=await b): pass diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index ca6b5d0..9b41df1 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -534,7 +534,8 @@ class GrammarTests(unittest.TestCase): # Not allowed at class scope check_syntax_error(self, "class foo:yield 1") check_syntax_error(self, "class foo:yield from ()") - + # Check annotation refleak on SyntaxError + check_syntax_error(self, "def g(a:(yield)): pass") def test_raise(self): # 'raise' test [',' test] diff --git a/Misc/NEWS b/Misc/NEWS index bbd8e92..98b60e8 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,9 @@ Core and Builtins - Issue #24619: New approach for tokenizing async/await. As a consequence, is is now possible to have one-line 'async def foo(): await ..' functions. +- Issue #24687: Plug refleak on SyntaxError in function parameters + annotations. + Library ------- diff --git a/Python/compile.c b/Python/compile.c index 33cc8c2..027e3ab 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1559,32 +1559,31 @@ compiler_visit_argannotation(struct compiler *c, identifier id, VISIT(c, expr, annotation); mangled = _Py_Mangle(c->u->u_private, id); if (!mangled) - return -1; + return 0; if (PyList_Append(names, mangled) < 0) { Py_DECREF(mangled); - return -1; + return 0; } Py_DECREF(mangled); } - return 0; + return 1; } static int compiler_visit_argannotations(struct compiler *c, asdl_seq* args, PyObject *names) { - int i, error; + int i; for (i = 0; i < asdl_seq_LEN(args); i++) { arg_ty arg = (arg_ty)asdl_seq_GET(args, i); - error = compiler_visit_argannotation( + if (!compiler_visit_argannotation( c, arg->arg, arg->annotation, - names); - if (error) - return error; + names)) + return 0; } - return 0; + return 1; } static int @@ -1604,16 +1603,16 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, if (!names) return -1; - if (compiler_visit_argannotations(c, args->args, names)) + if (!compiler_visit_argannotations(c, args->args, names)) goto error; if (args->vararg && args->vararg->annotation && - compiler_visit_argannotation(c, args->vararg->arg, + !compiler_visit_argannotation(c, args->vararg->arg, args->vararg->annotation, names)) goto error; - if (compiler_visit_argannotations(c, args->kwonlyargs, names)) + if (!compiler_visit_argannotations(c, args->kwonlyargs, names)) goto error; if (args->kwarg && args->kwarg->annotation && - compiler_visit_argannotation(c, args->kwarg->arg, + !compiler_visit_argannotation(c, args->kwarg->arg, args->kwarg->annotation, names)) goto error; @@ -1622,7 +1621,7 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, if (!return_str) goto error; } - if (compiler_visit_argannotation(c, return_str, returns, names)) { + if (!compiler_visit_argannotation(c, return_str, returns, names)) { goto error; } -- cgit v0.12