Issue #24687: Plug refleak on SyntaxError in function parameters annotations.

This commit is contained in:
Yury Selivanov 2015-07-23 09:10:44 +03:00
parent 2f07a66ded
commit f315c1c016
4 changed files with 22 additions and 15 deletions

View File

@ -211,6 +211,10 @@ class AsyncBadSyntaxTest(unittest.TestCase):
pass pass
""", """,
"""async def foo(a:await b):
pass
""",
"""def baz(): """def baz():
async def foo(a=await b): async def foo(a=await b):
pass pass

View File

@ -534,7 +534,8 @@ class GrammarTests(unittest.TestCase):
# Not allowed at class scope # Not allowed at class scope
check_syntax_error(self, "class foo:yield 1") check_syntax_error(self, "class foo:yield 1")
check_syntax_error(self, "class foo:yield from ()") 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): def test_raise(self):
# 'raise' test [',' test] # 'raise' test [',' test]

View File

@ -22,6 +22,9 @@ Core and Builtins
- Issue #24619: New approach for tokenizing async/await. As a consequence, - Issue #24619: New approach for tokenizing async/await. As a consequence,
is is now possible to have one-line 'async def foo(): await ..' functions. is is now possible to have one-line 'async def foo(): await ..' functions.
- Issue #24687: Plug refleak on SyntaxError in function parameters
annotations.
Library Library
------- -------

View File

@ -1559,33 +1559,32 @@ compiler_visit_argannotation(struct compiler *c, identifier id,
VISIT(c, expr, annotation); VISIT(c, expr, annotation);
mangled = _Py_Mangle(c->u->u_private, id); mangled = _Py_Mangle(c->u->u_private, id);
if (!mangled) if (!mangled)
return -1; return 0;
if (PyList_Append(names, mangled) < 0) { if (PyList_Append(names, mangled) < 0) {
Py_DECREF(mangled); Py_DECREF(mangled);
return -1; return 0;
} }
Py_DECREF(mangled); Py_DECREF(mangled);
} }
return 0; return 1;
} }
static int static int
compiler_visit_argannotations(struct compiler *c, asdl_seq* args, compiler_visit_argannotations(struct compiler *c, asdl_seq* args,
PyObject *names) PyObject *names)
{ {
int i, error; int i;
for (i = 0; i < asdl_seq_LEN(args); i++) { for (i = 0; i < asdl_seq_LEN(args); i++) {
arg_ty arg = (arg_ty)asdl_seq_GET(args, i); arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
error = compiler_visit_argannotation( if (!compiler_visit_argannotation(
c, c,
arg->arg, arg->arg,
arg->annotation, arg->annotation,
names); names))
if (error)
return error;
}
return 0; return 0;
} }
return 1;
}
static int static int
compiler_visit_annotations(struct compiler *c, arguments_ty args, compiler_visit_annotations(struct compiler *c, arguments_ty args,
@ -1604,16 +1603,16 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,
if (!names) if (!names)
return -1; return -1;
if (compiler_visit_argannotations(c, args->args, names)) if (!compiler_visit_argannotations(c, args->args, names))
goto error; goto error;
if (args->vararg && args->vararg->annotation && if (args->vararg && args->vararg->annotation &&
compiler_visit_argannotation(c, args->vararg->arg, !compiler_visit_argannotation(c, args->vararg->arg,
args->vararg->annotation, names)) args->vararg->annotation, names))
goto error; goto error;
if (compiler_visit_argannotations(c, args->kwonlyargs, names)) if (!compiler_visit_argannotations(c, args->kwonlyargs, names))
goto error; goto error;
if (args->kwarg && args->kwarg->annotation && if (args->kwarg && args->kwarg->annotation &&
compiler_visit_argannotation(c, args->kwarg->arg, !compiler_visit_argannotation(c, args->kwarg->arg,
args->kwarg->annotation, names)) args->kwarg->annotation, names))
goto error; goto error;
@ -1622,7 +1621,7 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,
if (!return_str) if (!return_str)
goto error; goto error;
} }
if (compiler_visit_argannotation(c, return_str, returns, names)) { if (!compiler_visit_argannotation(c, return_str, returns, names)) {
goto error; goto error;
} }