import Nodes
from Nodes import Node
import PyrexTypes
-from PyrexTypes import py_object_type, c_long_type, typecast, error_type
+from PyrexTypes import py_object_type, c_long_type, typecast, error_type, unspecified_type
from Builtin import list_type, tuple_type, set_type, dict_type, unicode_type, bytes_type
import Builtin
import Symtab
if not self.entry:
self.entry = env.lookup_here(self.name)
if not self.entry:
- self.entry = env.declare_var(self.name, py_object_type, self.pos)
+ if env.directives['infer_types']:
+ type = unspecified_type
+ else:
+ type = py_object_type
+ self.entry = env.declare_var(self.name, type, self.pos)
env.control_flow.set_state(self.pos, (self.name, 'initalized'), True)
env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
if self.entry.is_declared_generic:
self.target.analyse_expressions(env)
self.type = self.target.type
self.append.target = self # this is a CloneNode used in the PyList_Append in the inner loop
+ # We are analysing declarations to late.
+ self.loop.target.analyse_target_declaration(env)
+ env.infer_types()
self.loop.analyse_declarations(env)
self.loop.analyse_expressions(env)
def create_binop_node(self):
import ExprNodes
- return ExprNodes.binop_node(self.pos, self.op, self.lhs, self.rhs)
+ return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
class PrintStatNode(StatNode):
class AnalyseExpressionsTransform(CythonTransform):
def visit_ModuleNode(self, node):
+ node.scope.infer_types()
node.body.analyse_expressions(node.scope)
self.visitchildren(node)
return node
def visit_FuncDefNode(self, node):
+ node.local_scope.infer_types()
node.body.analyse_expressions(node.local_scope)
self.visitchildren(node)
return node
from StringEncoding import EncodedString
import Options, Naming
import PyrexTypes
-from PyrexTypes import py_object_type
+from PyrexTypes import py_object_type, unspecified_type
import TypeSlots
from TypeSlots import \
pyfunction_signature, pymethod_signature, \
if name in self.entries:
return 1
return 0
+
+ def infer_types(self):
+ for name, entry in self.entries.items():
+ if entry.type is unspecified_type:
+ entry.type = py_object_type
+ entry.init_to_none = Options.init_local_none # TODO: is there a better place for this?
class PreImportScope(Scope):
if not visibility in ('private', 'public', 'extern'):
error(pos, "Module-level variable cannot be declared %s" % visibility)
if not is_cdef:
+ if type is unspecified_type:
+ type = py_object_type
if not (type.is_pyobject and not type.is_extension_type):
raise InternalError(
"Non-cdef global variable is not a generic Python object")
def declare_var(self, name, type, pos,
cname = None, visibility = 'private', is_cdef = 0):
+ if type is unspecified_type:
+ type = py_object_type
# Add an entry for a class attribute.
entry = Scope.declare_var(self, name, type, pos,
cname, visibility, is_cdef)
"Non-generic Python attribute cannot be exposed for writing from Python")
return entry
else:
+ if type is unspecified_type:
+ type = py_object_type
# Add an entry for a class attribute.
entry = Scope.declare_var(self, name, type, pos,
cname, visibility, is_cdef)
class MarkAssignments(CythonTransform):
def mark_assignment(self, lhs, rhs):
- print lhs.pos[1:]
if isinstance(lhs, ExprNodes.NameNode):
+ if lhs.entry is None:
+ # TODO: This shouldn't happen...
+ # It looks like comprehension loop targets are not declared soon enough.
+ return
lhs.entry.assignments.append(rhs)
- print lhs.name, rhs
elif isinstance(lhs, ExprNodes.SequenceNode):
for arg in lhs.args:
self.mark_assignment(arg, object_expr)
def visit_ForFromStatNode(self, node):
self.mark_assignment(node.target, node.bound1)
if node.step is not None:
- self.mark_assignment(node.target, ExprNodes.binop_node(self.pos, '+', node.bound1, node.step))
+ self.mark_assignment(node.target, ExprNodes.binop_node(node.pos, '+', node.bound1, node.step))
self.visitchildren(node)
return node
return node
def visit_FromCImportStatNode(self, node):
- raise NotImplementedError # Can't occur in local scopes anyways...
+ pass # Can't be assigned to...
def visit_FromImportStatNode(self, node):
for name, target in node.items: