Commit 3a17b1cd authored by Lisandro Dalcin's avatar Lisandro Dalcin

fix ref-counting & cleanup and add testcase for function default argument values

parent 95faf8af
...@@ -1706,6 +1706,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1706,6 +1706,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.put_decref_clear(entry.pystring_cname, code.put_decref_clear(entry.pystring_cname,
PyrexTypes.py_object_type, PyrexTypes.py_object_type,
nanny=False) 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("Py_INCREF(Py_None); return Py_None;")
code.putln('}') code.putln('}')
......
...@@ -992,6 +992,8 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -992,6 +992,8 @@ class FuncDefNode(StatNode, BlockNode):
else: else:
arg.default.allocate_temps(genv) arg.default.allocate_temps(genv)
arg.default_entry = genv.add_default_value(arg.type) 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_entry.used = 1
arg.default_result_code = arg.default_entry.cname arg.default_result_code = arg.default_entry.cname
else: else:
...@@ -1231,15 +1233,14 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1231,15 +1233,14 @@ class FuncDefNode(StatNode, BlockNode):
if default: if default:
if not default.is_literal: if not default.is_literal:
default.generate_evaluation_code(code) default.generate_evaluation_code(code)
default.make_owned_reference(code) assign_code = "%s = %s;" % (
code.putln( arg.default_entry.cname,
"%s = %s;" % ( default.result_as(arg.default_entry.type))
arg.default_entry.cname, if default.type.is_pyobject:
default.result_as(arg.default_entry.type))) assign_code += " Py_INCREF(%s);" % \
if default.is_temp and default.type.is_pyobject: arg.type.as_pyobject(arg.default_entry.cname)
code.putln( code.putln(assign_code)
"%s = 0;" % default.generate_disposal_code(code)
default.result())
default.free_temps(code) default.free_temps(code)
# For Python class methods, create and store function object # For Python class methods, create and store function object
if self.assmt: if self.assmt:
......
__doc__ = """
>>> f0()
(1, 2)
>>> g0()
(1, 2)
>>> f1()
[1, 2]
>>> g1()
[1, 2]
>>> f2()
{1: 2}
>>> g2()
{1: 2}
>>> f3() #doctest: +ELLIPSIS
<argdefaultglb.Foo object at ...>
>>> g3() #doctest: +ELLIPSIS
<argdefaultglb.Foo object at ...>
>>> f4() #doctest: +ELLIPSIS
<argdefaultglb.Bar object at ...>
>>> g4() #doctest: +ELLIPSIS
<argdefaultglb.Bar object at ...>
>>> f5() #doctest: +ELLIPSIS
<argdefaultglb.Bla object at ...>
>>> g5() #doctest: +ELLIPSIS
<argdefaultglb.Bla object at ...>
"""
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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment