From: Lisandro Dalcin Date: Mon, 23 Feb 2009 20:05:13 +0000 (-0200) Subject: fix ref-counting & cleanup and add testcase for function default argument values X-Git-Tag: 0.11.rc~42^2~3 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=3a17b1cd1d257112cd0132dc6dd374d3d7aef98b;p=cython.git fix ref-counting & cleanup and add testcase for function default argument values --- diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index d6d8f4ca..3967f8dd 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -1706,6 +1706,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.put_decref_clear(entry.pystring_cname, PyrexTypes.py_object_type, nanny=False) + for entry in env.default_entries: + if entry.type.is_pyobject and entry.used: + code.putln("Py_DECREF(%s); %s = 0;" % ( + code.entry_as_pyobject(entry), entry.cname)) code.putln("Py_INCREF(Py_None); return Py_None;") code.putln('}') diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 629270dc..b1c850ab 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -992,6 +992,8 @@ class FuncDefNode(StatNode, BlockNode): else: arg.default.allocate_temps(genv) arg.default_entry = genv.add_default_value(arg.type) + if arg.type.is_pyobject: + arg.default_entry.init = 0 arg.default_entry.used = 1 arg.default_result_code = arg.default_entry.cname else: @@ -1231,15 +1233,14 @@ class FuncDefNode(StatNode, BlockNode): if default: if not default.is_literal: default.generate_evaluation_code(code) - default.make_owned_reference(code) - code.putln( - "%s = %s;" % ( - arg.default_entry.cname, - default.result_as(arg.default_entry.type))) - if default.is_temp and default.type.is_pyobject: - code.putln( - "%s = 0;" % - default.result()) + assign_code = "%s = %s;" % ( + arg.default_entry.cname, + default.result_as(arg.default_entry.type)) + if default.type.is_pyobject: + assign_code += " Py_INCREF(%s);" % \ + arg.type.as_pyobject(arg.default_entry.cname) + code.putln(assign_code) + default.generate_disposal_code(code) default.free_temps(code) # For Python class methods, create and store function object if self.assmt: diff --git a/tests/run/argdefault.pyx b/tests/run/argdefault.pyx new file mode 100644 index 00000000..6ef1faaa --- /dev/null +++ b/tests/run/argdefault.pyx @@ -0,0 +1,78 @@ +__doc__ = """ +>>> f0() +(1, 2) +>>> g0() +(1, 2) + +>>> f1() +[1, 2] +>>> g1() +[1, 2] + +>>> f2() +{1: 2} +>>> g2() +{1: 2} + +>>> f3() #doctest: +ELLIPSIS + +>>> g3() #doctest: +ELLIPSIS + + +>>> f4() #doctest: +ELLIPSIS + +>>> g4() #doctest: +ELLIPSIS + + +>>> f5() #doctest: +ELLIPSIS + +>>> g5() #doctest: +ELLIPSIS + +""" + +GLB0 = (1, 2) +def f0(arg=GLB0): + return arg +def g0(arg=(1, 2)): + return arg + + +GLB1 = [1, 2] +def f1(arg=GLB1): + return arg +def g1(arg=[1, 2]): + return arg + + +cdef GLB2 = {1: 2} +def f2(arg=GLB2): + return arg +def g2(arg={1: 2}): + return arg + + +class Foo(object): + pass +cdef GLB3 = Foo() +def f3(arg=GLB3): + return arg +def g3(arg=Foo()): + return arg + + +cdef class Bar: + pass +cdef Bar GLB4 = Bar() +def f4(arg=GLB4): + return arg +def g4(arg=Bar()): + return arg + + +cdef class Bla: + pass +cdef Bla GLB5 = Bla() +def f5(Bla arg=GLB5): + return arg +def g5(Bla arg=Bla()): + return arg