[Scipy-svn] r3007 - trunk/Lib/sandbox/numexpr

scipy-svn@scip... scipy-svn@scip...
Tue May 15 14:41:07 CDT 2007


Author: cookedm
Date: 2007-05-15 14:41:05 -0500 (Tue, 15 May 2007)
New Revision: 3007

Modified:
   trunk/Lib/sandbox/numexpr/compiler.py
   trunk/Lib/sandbox/numexpr/expressions.py
Log:
[numexpr] Simplify using a context for evaluating expressions (also threadsafe for Python >= 2.4)


Modified: trunk/Lib/sandbox/numexpr/compiler.py
===================================================================
--- trunk/Lib/sandbox/numexpr/compiler.py	2007-05-15 11:57:40 UTC (rev 3006)
+++ trunk/Lib/sandbox/numexpr/compiler.py	2007-05-15 19:41:05 UTC (rev 3007)
@@ -185,47 +185,29 @@
     def __str__(self):
         return 'Immediate(%d)' % (self.node.value,)
 
-def makeExpressions(context):
-    """Make private copy of the expressions module with a custom get_context().
-
-    An attempt was made to make this threadsafe, but I can't guarantee it's
-    bulletproof.
-    """
-    import sys, imp
-    modname = __name__[:__name__.rfind('.')] + '.expressions'
-    # get our own, private copy of expressions
-    imp.acquire_lock()
-    try:
-        old = sys.modules.pop(modname)
-        import expressions
-        private = sys.modules.pop(modname)
-        sys.modules[modname] = old
-    finally:
-        imp.release_lock()
-    def get_context():
-        return context
-    private.get_context = get_context
-    return private
-
 def stringToExpression(s, types, context):
     """Given a string, convert it to a tree of ExpressionNode's.
     """
-    expr = makeExpressions(context)
-    # first compile to a code object to determine the names
-    c = compile(s, '<expr>', 'eval')
-    # make VariableNode's for the names
-    names = {}
-    for name in c.co_names:
-        if name == "None":
-            names[name] = None
-        else:
-            t = types.get(name, float)
-            names[name] = expr.VariableNode(name, type_to_kind[t])
-    names.update(expr.functions)
-    # now build the expression
-    ex = eval(c, names)
-    if expressions.isConstant(ex):
-        ex = expr.ConstantNode(ex, expressions.getKind(ex))
+    old_ctx = expressions._context.ctx
+    try:
+        expressions._context.ctx = context
+        # first compile to a code object to determine the names
+        c = compile(s, '<expr>', 'eval')
+        # make VariableNode's for the names
+        names = {}
+        for name in c.co_names:
+            if name == "None":
+                names[name] = None
+            else:
+                t = types.get(name, float)
+                names[name] = expressions.VariableNode(name, type_to_kind[t])
+        names.update(expressions.functions)
+        # now build the expression
+        ex = eval(c, names)
+        if expressions.isConstant(ex):
+            ex = expressions.ConstantNode(ex, expressions.getKind(ex))
+    finally:
+        expressions._context.ctx = old_ctx
     return ex
 
 

Modified: trunk/Lib/sandbox/numexpr/expressions.py
===================================================================
--- trunk/Lib/sandbox/numexpr/expressions.py	2007-05-15 11:57:40 UTC (rev 3006)
+++ trunk/Lib/sandbox/numexpr/expressions.py	2007-05-15 19:41:05 UTC (rev 3007)
@@ -1,9 +1,11 @@
 __all__ = ['E']
 
 import operator
-import numpy
 import sys
+import threading
 
+import numpy
+
 import interpreter
 
 class Expression(object):
@@ -18,12 +20,16 @@
 
 E = Expression()
 
+try:
+    _context = threading.local()
+except AttributeError:
+    class Context(object):
+        pass
+    _context = Context()
+_context.ctx = {}
 
-def get_context():
-    """Context used to evaluate expression. Typically overridden in compiler."""
-    return {}
 def get_optimization():
-    return get_context().get('optimization', 'none')
+    return _context.ctx.get('optimization', 'none')
 
 # helper functions for creating __magic__ methods
 def ophelper(f):



More information about the Scipy-svn mailing list