summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYury Selivanov <yselivanov@sprymix.com>2015-07-23 06:10:44 (GMT)
committerYury Selivanov <yselivanov@sprymix.com>2015-07-23 06:10:44 (GMT)
commitf315c1c01676bfabb5b1c6628642668f1ef436a6 (patch)
tree078327f0ab7ab7c2a7ac347d9cb4669e98a6d201
parent2f07a66dedb6f69cbe601f7ca2c3fca66898ffe3 (diff)
downloadcpython-f315c1c01676bfabb5b1c6628642668f1ef436a6.zip
cpython-f315c1c01676bfabb5b1c6628642668f1ef436a6.tar.gz
cpython-f315c1c01676bfabb5b1c6628642668f1ef436a6.tar.bz2
Issue #24687: Plug refleak on SyntaxError in function parameters annotations.
-rw-r--r--Lib/test/test_coroutines.py4
-rw-r--r--Lib/test/test_grammar.py3
-rw-r--r--Misc/NEWS3
-rw-r--r--Python/compile.c27
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;
}