From 64b44e3132d982372b2a323f48d880334221d4b2 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 20 Mar 2010 13:27:50 +0100 Subject: [PATCH] disable type inference for closures and work around prematurely created closure fields with incorrect type information --- Cython/Compiler/ParseTreeTransforms.py | 4 ++++ Cython/Compiler/TypeInference.py | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) 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: -- 2.26.2