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 ...@@ -11,6 +11,10 @@ Features added
Bugs fixed 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, * The C code generation order of cdef classes, closures, helper code,
etc. was not deterministic, thus leading to high code churn. etc. was not deterministic, thus leading to high code churn.
......
...@@ -1690,7 +1690,7 @@ class NameNode(AtomicExprNode): ...@@ -1690,7 +1690,7 @@ class NameNode(AtomicExprNode):
return self return self
def analyse_target_types(self, env): 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 if (not self.is_lvalue() and self.entry.is_cfunction and
self.entry.fused_cfunction and self.entry.as_variable): self.entry.fused_cfunction and self.entry.as_variable):
...@@ -1750,12 +1750,12 @@ class NameNode(AtomicExprNode): ...@@ -1750,12 +1750,12 @@ class NameNode(AtomicExprNode):
gil_message = "Accessing Python global or builtin" 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 ### #print "NameNode.analyse_entry:", self.name ###
self.check_identifier_kind() self.check_identifier_kind()
entry = self.entry entry = self.entry
type = entry.type 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): self.inferred_type.is_builtin_type):
# assume that type inference is smarter than the static entry # assume that type inference is smarter than the static entry
type = self.inferred_type type = self.inferred_type
......
...@@ -26,6 +26,37 @@ def test_object_assmt(): ...@@ -26,6 +26,37 @@ def test_object_assmt():
assert typeof(a) == "Python object", typeof(a) assert typeof(a) == "Python object", typeof(a)
assert typeof(b) == "long", typeof(b) 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): def test_long_vs_double(cond):
""" """
>>> test_long_vs_double(0) >>> 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