Commit 52138792 authored by scoder's avatar scoder

Merge pull request #120 from vitek/_type_inference

Infer variable as pyobject when del-ed, fix #768
parents a1dc8203 7cccaa06
...@@ -313,6 +313,12 @@ class NameAssignment(object): ...@@ -313,6 +313,12 @@ class NameAssignment(object):
def __repr__(self): def __repr__(self):
return '%s(entry=%r)' % (self.__class__.__name__, self.entry) return '%s(entry=%r)' % (self.__class__.__name__, self.entry)
def infer_type(self, scope):
return self.rhs.infer_type(scope)
def type_dependencies(self, scope):
return self.rhs.type_dependencies(scope)
class Argument(NameAssignment): class Argument(NameAssignment):
def __init__(self, lhs, rhs, entry): def __init__(self, lhs, rhs, entry):
...@@ -325,6 +331,13 @@ class NameDeletion(NameAssignment): ...@@ -325,6 +331,13 @@ class NameDeletion(NameAssignment):
NameAssignment.__init__(self, lhs, lhs, entry) NameAssignment.__init__(self, lhs, lhs, entry)
self.is_deletion = True self.is_deletion = True
def infer_type(self, scope):
inferred_type = self.rhs.infer_type(scope)
if (not inferred_type.is_pyobject and
inferred_type.can_coerce_to_pyobject(scope)):
return py_object_type
return inferred_type
class Uninitialized(object): class Uninitialized(object):
pass pass
......
...@@ -363,7 +363,7 @@ class SimpleAssignmentTypeInferer(object): ...@@ -363,7 +363,7 @@ class SimpleAssignmentTypeInferer(object):
continue continue
all = set() all = set()
for assmt in entry.cf_assignments: for assmt in entry.cf_assignments:
all.update(assmt.rhs.type_dependencies(scope)) all.update(assmt.type_dependencies(scope))
if all: if all:
dependancies_by_entry[entry] = all dependancies_by_entry[entry] = all
for dep in all: for dep in all:
...@@ -401,12 +401,12 @@ class SimpleAssignmentTypeInferer(object): ...@@ -401,12 +401,12 @@ class SimpleAssignmentTypeInferer(object):
# Deal with simple circular dependancies... # Deal with simple circular dependancies...
for entry, deps in dependancies_by_entry.items(): for entry, deps in dependancies_by_entry.items():
if len(deps) == 1 and deps == set([entry]): if len(deps) == 1 and deps == set([entry]):
types = [assmt.rhs.infer_type(scope) types = [assmt.infer_type(scope)
for assmt in entry.cf_assignments for assmt in entry.cf_assignments
if assmt.rhs.type_dependencies(scope) == ()] if assmt.type_dependencies(scope) == ()]
if types: if types:
entry.type = spanning_type(types, entry.might_overflow) entry.type = spanning_type(types, entry.might_overflow)
types = [assmt.rhs.infer_type(scope) types = [assmt.infer_type(scope)
for assmt in entry.cf_assignments] for assmt in entry.cf_assignments]
entry.type = spanning_type(types, entry.might_overflow) # might be wider... entry.type = spanning_type(types, entry.might_overflow) # might be wider...
resolve_dependancy(entry) resolve_dependancy(entry)
......
...@@ -9,8 +9,6 @@ def foo(x): ...@@ -9,8 +9,6 @@ def foo(x):
return a, b return a, b
_ERRORS = """ _ERRORS = """
7:9: Deletion of non-Python, non-C++ object
7:12: local variable 'b' referenced before assignment 7:12: local variable 'b' referenced before assignment
7:12: Deletion of non-Python, non-C++ object
9:12: local variable 'a' referenced before assignment 9:12: local variable 'a' referenced before assignment
""" """
# mode: run
# ticket: 768
from cython cimport typeof
def type_inference_del_int():
"""
>>> type_inference_del_int()
'Python object'
"""
x = 1
del x
return typeof(x)
def type_inference_del_dict():
"""
>>> type_inference_del_dict()
'dict object'
"""
x = {}
del x
return typeof(x)
# mode: run
# tag: cpp
# ticket: 768
from cython cimport typeof
cdef extern from "shapes.h" namespace "shapes":
cdef cppclass Shape:
float area()
cdef cppclass Circle(Shape):
int radius
Circle(int)
def type_inference_del_cpp():
"""
>>> type_inference_del_cpp()
'Circle *'
"""
x = new Circle(10)
del x
return typeof(x)
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