Commit 8d627ede authored by Stefan Behnel's avatar Stefan Behnel

fix in-place assignments of arbitrary objects to variables with inferred...

fix in-place assignments of arbitrary objects to variables with inferred Python builtin/extension types
parent 7a324f98
......@@ -11,6 +11,10 @@ Features added
Bugs fixed
----------
* In-place assignments to variables with inferred Python builtin/extension
types could fail with type errors if the result value type was incompatible
with the type of the previous value.
* The C code generation order of cdef classes, closures, helper code,
etc. was not deterministic, thus leading to high code churn.
......
......@@ -1690,7 +1690,7 @@ class NameNode(AtomicExprNode):
return self
def analyse_target_types(self, env):
self.analyse_entry(env)
self.analyse_entry(env, is_target=True)
if (not self.is_lvalue() and self.entry.is_cfunction and
self.entry.fused_cfunction and self.entry.as_variable):
......@@ -1750,12 +1750,12 @@ class NameNode(AtomicExprNode):
gil_message = "Accessing Python global or builtin"
def analyse_entry(self, env):
def analyse_entry(self, env, is_target=False):
#print "NameNode.analyse_entry:", self.name ###
self.check_identifier_kind()
entry = self.entry
type = entry.type
if (type.is_pyobject and self.inferred_type and
if (not is_target and type.is_pyobject and self.inferred_type and
self.inferred_type.is_builtin_type):
# assume that type inference is smarter than the static entry
type = self.inferred_type
......
......@@ -26,6 +26,37 @@ def test_object_assmt():
assert typeof(a) == "Python object", typeof(a)
assert typeof(b) == "long", typeof(b)
class RAdd(object):
other = None
def __radd__(self, other):
self._other = other
return self
def __repr__(self):
return '%s(%s)' % (type(self).__name__, self._other)
def test_inplace_assignment():
"""
>>> test_inplace_assignment()
RAdd([1, 2, 3])
"""
l = [1, 2, 3]
# inferred type of l is list, but assignment result is object
l += RAdd()
return l
def test_reassignment():
"""
>>> test_reassignment()
(1, 2, 3)
"""
l = [1, 2, 3]
l = (1, 2, 3)
return l
def test_long_vs_double(cond):
"""
>>> test_long_vs_double(0)
......
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