# Coerce arguments
for i in range(min(max_nargs, actual_nargs)):
formal_type = func_type.args[i].type
- self.args[i] = self.args[i].coerce_to(formal_type, env)
+ arg = self.args[i].coerce_to(formal_type, env)
+ if arg.is_attribute or not arg.is_simple:
+ # we do not own the argument's reference, but we must
+ # make sure it cannot be collected before we return
+ # from the function, so we create an owned temp
+ # reference to it
+ arg = arg.coerce_to_temp(env)
+ self.args[i] = arg
for i in range(max_nargs, actual_nargs):
if self.args[i].type.is_pyobject:
error(self.args[i].pos,
--- /dev/null
+
+cdef class Owner:
+ cdef object x
+
+cdef call_me_with_owner(Owner owner, x):
+ owner.x = "def" # overwrite external reference
+ return x # crashes if x is not owned by function or caller
+
+def test_ext_type_attr():
+ """
+ >>> test_ext_type_attr()
+ 'abc5'
+ """
+ owner = Owner()
+ owner.x = ''.join("abc%d" % 5) # non-interned object
+ return call_me_with_owner(owner, owner.x)
+
+cdef call_me_with_list(list l, x):
+ l[:] = [(1,2), (3,4)] # overwrite external reference
+ return x # crashes if x is not owned by function or caller
+
+def test_index():
+ """
+ >>> test_index()
+ [3, 4]
+ """
+ l = [[1,2],[3,4]]
+ return call_me_with_list(l, l[1])