summaryrefslogtreecommitdiff
path: root/utils.py
diff options
context:
space:
mode:
authorRobert Kern <robert.kern@gmail.com>2007-12-16 07:52:44 +0000
committerRobert Kern <robert.kern@gmail.com>2007-12-16 07:52:44 +0000
commit9f25dd88311ecbbf6e861a3c9c1c265dde1d52d1 (patch)
tree01d4a3e7ac27e94f8a904c3f23612830c66f3aad /utils.py
parentcf73c9df97192d2215a05436bffdfca9259daf9e (diff)
downloadnumpy-9f25dd88311ecbbf6e861a3c9c1c265dde1d52d1.tar.gz
Code establishing a simple format for .npy files.
Diffstat (limited to 'utils.py')
-rw-r--r--utils.py113
1 files changed, 112 insertions, 1 deletions
diff --git a/utils.py b/utils.py
index 19a10f518..048ffafc0 100644
--- a/utils.py
+++ b/utils.py
@@ -1,3 +1,4 @@
+import compiler
import os
import sys
import inspect
@@ -10,7 +11,7 @@ __all__ = ['issubclass_', 'get_numpy_include', 'issubsctype',
'issubdtype', 'deprecate', 'deprecate_with_doc',
'get_numarray_include',
'get_include', 'info', 'source', 'who',
- 'byte_bounds', 'may_share_memory']
+ 'byte_bounds', 'may_share_memory', 'safe_eval']
def issubclass_(arg1, arg2):
try:
@@ -466,3 +467,113 @@ def source(object, output=sys.stdout):
print >> output, inspect.getsource(object)
except:
print >> output, "Not available for this object."
+
+#-----------------------------------------------------------------------------
+
+# The following SafeEval class and company are adapted from Michael Spencer's
+# ASPN Python Cookbook recipe:
+# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/364469
+# Accordingly it is mostly Copyright 2006 by Michael Spencer.
+# The recipe, like most of the other ASPN Python Cookbook recipes was made
+# available under the Python license.
+# http://www.python.org/license
+
+# It has been modified to:
+# * handle unary -/+
+# * support True/False/None
+# * raise SyntaxError instead of a custom exception.
+
+class SafeEval(object):
+
+ def visit(self, node, **kw):
+ cls = node.__class__
+ meth = getattr(self,'visit'+cls.__name__,self.default)
+ return meth(node, **kw)
+
+ def default(self, node, **kw):
+ raise SyntaxError("Unsupported source construct: %s" % node.__class__)
+
+ def visitExpression(self, node, **kw):
+ for child in node.getChildNodes():
+ return self.visit(child, **kw)
+
+ def visitConst(self, node, **kw):
+ return node.value
+
+ def visitDict(self, node,**kw):
+ return dict([(self.visit(k),self.visit(v)) for k,v in node.items])
+
+ def visitTuple(self, node, **kw):
+ return tuple([self.visit(i) for i in node.nodes])
+
+ def visitList(self, node, **kw):
+ return [self.visit(i) for i in node.nodes]
+
+ def visitUnaryAdd(self, node, **kw):
+ return +self.visit(node.getChildNodes()[0])
+
+ def visitUnarySub(self, node, **kw):
+ return -self.visit(node.getChildNodes()[0])
+
+ def visitName(self, node, **kw):
+ if node.name == 'False':
+ return False
+ elif node.name == 'True':
+ return True
+ elif node.name == 'None':
+ return None
+ else:
+ raise SyntaxError("Unknown name: %s" % node.name)
+
+def safe_eval(source):
+ """ Evaluate a string containing a Python literal expression without
+ allowing the execution of arbitrary non-literal code.
+
+ Parameters
+ ----------
+ source : str
+
+ Returns
+ -------
+ obj : object
+
+ Raises
+ ------
+ SyntaxError if the code is invalid Python expression syntax or if it
+ contains non-literal code.
+
+ Examples
+ --------
+ >>> from numpy.lib.utils import safe_eval
+ >>> safe_eval('1')
+ 1
+ >>> safe_eval('[1, 2, 3]')
+ [1, 2, 3]
+ >>> safe_eval('{"foo": ("bar", 10.0)}')
+ {'foo': ('bar', 10.0)}
+ >>> safe_eval('import os')
+ Traceback (most recent call last):
+ ...
+ SyntaxError: invalid syntax
+ >>> safe_eval('open("/home/user/.ssh/id_dsa").read()')
+ Traceback (most recent call last):
+ ...
+ SyntaxError: Unsupported source construct: compiler.ast.CallFunc
+ >>> safe_eval('dict')
+ Traceback (most recent call last):
+ ...
+ SyntaxError: Unknown name: dict
+ """
+ walker = SafeEval()
+ try:
+ ast = compiler.parse(source, "eval")
+ except SyntaxError, err:
+ raise
+ try:
+ return walker.visit(ast)
+ except SyntaxError, err:
+ raise
+
+#-----------------------------------------------------------------------------
+
+