From ac871a9e3ba72f60b7de22d157674efa3f6d398e Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 5 Feb 2011 19:21:47 +0100 Subject: [PATCH] error handling fixes for argument unpacking when args/kwargs are in closures --- Cython/Compiler/Nodes.py | 10 +++++----- tests/run/args_unpacking_in_closure_T658.pyx | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 tests/run/args_unpacking_in_closure_T658.pyx diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 9251e018..5895f46b 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -2387,9 +2387,9 @@ class DefNode(FuncDefNode): self.generate_arg_decref(self.star_arg, code) if self.starstar_arg: if self.starstar_arg.entry.xdecref_cleanup: - code.put_var_xdecref(self.starstar_arg.entry) + code.put_var_xdecref_clear(self.starstar_arg.entry) else: - code.put_var_decref(self.starstar_arg.entry) + code.put_var_decref_clear(self.starstar_arg.entry) code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name) # The arguments are put into the closure one after the # other, so when type errors are found, all references in @@ -2429,11 +2429,11 @@ class DefNode(FuncDefNode): def generate_arg_xdecref(self, arg, code): if arg: - code.put_var_xdecref(arg.entry) + code.put_var_xdecref_clear(arg.entry) def generate_arg_decref(self, arg, code): if arg: - code.put_var_decref(arg.entry) + code.put_var_decref_clear(arg.entry) def generate_stararg_copy_code(self, code): if not self.star_arg: @@ -2641,7 +2641,7 @@ class DefNode(FuncDefNode): if self.starstar_arg: code.putln("") code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname) - code.put_decref(self.starstar_arg.entry.cname, py_object_type) + code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type) code.putln('return %s;' % self.error_value()) code.putln('}') else: diff --git a/tests/run/args_unpacking_in_closure_T658.pyx b/tests/run/args_unpacking_in_closure_T658.pyx new file mode 100644 index 00000000..c81d8365 --- /dev/null +++ b/tests/run/args_unpacking_in_closure_T658.pyx @@ -0,0 +1,14 @@ + +def outer(int x, *args, **kwargs): + """ + >>> inner = outer(1, 2, a=3) + >>> inner() + (1, (2,), {'a': 3}) + + >>> inner = outer('abc', 2, a=3) + Traceback (most recent call last): + TypeError: an integer is required + """ + def inner(): + return x, args, kwargs + return inner -- 2.26.2