From: Stefan Behnel Date: Sat, 20 Mar 2010 12:27:50 +0000 (+0100) Subject: disable type inference for closures and work around prematurely created closure field... X-Git-Tag: 0.13.beta0~2^2~94 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=64b44e3132d982372b2a323f48d880334221d4b2;p=cython.git disable type inference for closures and work around prematurely created closure fields with incorrect type information --- diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 36cd2ee8..ac399041 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -1207,6 +1207,10 @@ class CreateClosureClasses(CythonTransform): for entry in func_scope.entries.values(): # This is wasteful--we should do this later when we know # which vars are actually being used inside... + # + # Also, this happens before type inference and type + # analysis, so the entries created here may end up having + # incorrect or at least unspecified types. cname = entry.cname class_scope.declare_var(pos=entry.pos, name=entry.name, diff --git a/Cython/Compiler/TypeInference.py b/Cython/Compiler/TypeInference.py index 5c792db8..4b09cfef 100644 --- a/Cython/Compiler/TypeInference.py +++ b/Cython/Compiler/TypeInference.py @@ -188,7 +188,7 @@ class SimpleAssignmentTypeInferer: # TODO: Implement a real type inference algorithm. # (Something more powerful than just extending this one...) def infer_types(self, scope): - enabled = scope.directives['infer_types'] + enabled = not scope.is_closure_scope and scope.directives['infer_types'] verbose = scope.directives['infer_types.verbose'] if enabled == True: spanning_type = aggressive_spanning_type @@ -198,6 +198,8 @@ class SimpleAssignmentTypeInferer: for entry in scope.entries.values(): if entry.type is unspecified_type: entry.type = py_object_type + if scope.is_closure_scope: + fix_closure_entries(scope) return dependancies_by_entry = {} # entry -> dependancies @@ -259,6 +261,19 @@ class SimpleAssignmentTypeInferer: entry.type = py_object_type if verbose: message(entry.pos, "inferred '%s' to be of type '%s' (default)" % (entry.name, entry.type)) + #if scope.is_closure_scope: + # fix_closure_entries(scope) + +def fix_closure_entries(scope): + """Temporary work-around to fix field types in the closure class + that were unknown at the time of creation and only determined + during type inference. + """ + closure_entries = scope.scope_class.type.scope.entries + for name, entry in scope.entries.iteritems(): + if name in closure_entries: + closure_entry = closure_entries[name] + closure_entry.type = entry.type def find_spanning_type(type1, type2): if type1 is type2: