changeset 57:732b6b4b2c45 pytave-new

implement dict interface to variables
author Jaroslav Hajek <highegg@gmail.com>
date Mon, 08 Jun 2009 11:58:20 +0200
parents 43a413b7c151
children 9279ecdea19e
files ChangeLog package/pytave.py test/test.py
diffstat 3 files changed, 62 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Jun 08 11:55:19 2009 +0200
+++ b/ChangeLog	Mon Jun 08 11:58:20 2009 +0200
@@ -15,6 +15,7 @@
 	(locals, globals): Default instances.
 	(_local_scope): Rename to _LocalScope
 	* test/test.py: New tests. Update old tests.
+	(testsetget, testexception): New functions.
 
 2009-06-03  Jaroslav Hajek  <highegg@gmail.com>
 
--- a/package/pytave.py	Mon Jun 08 11:55:19 2009 +0200
+++ b/package/pytave.py	Mon Jun 08 11:58:20 2009 +0200
@@ -157,46 +157,31 @@
 	"""See Octave documentation"""
 	return _pytave.feval(1, "path", paths)[0]
 
-def getvar(name, fglobal = False):
-	 """Queries a variable by name from the current Octave scope.
-	 This is pretty much equivalent to calling eval(name), but is
-	 much faster because the Octave parser is bypassed. 
-	 
-	 global specifies that a global variable should be looked up;
-	 otherwise, local variable (in the current scope) is always
-	 searched for.
+class _VariablesDict(UserDict.DictMixin):
+	def __init__(self, global_variables, native=False):
+		self.global_variables = global_variables
+		self.native = native
 
-	 If the variable is not defined, VarNameError exception is raised.
-	 """
-	 return _pytave.getvar(name, fglobal)
-
-def setvar(name, val, fglobal = False):
-	 """Sets a variable by name from the current Octave scope.
-	 It is quite fast because the Octave parser is bypassed. 
+	def __getitem__(self, name):
+		if not isinstance(name, basestring):
+			raise TypeError('Expected a string, not a ' + repr(type(name)))
+		try:
+			return _pytave.getvar(name, self.global_variables)
+		except VarNameError:
+			raise KeyError('No Octave variable named ' + name)
 
-	 global specifies that a global variable should be assigned to;
-	 otherwise, local variable (in the current scope) is always
-	 searched for.
-
-	 If the variable is not defined, a new variable is created.
-
-	 If the variable name is not valid, VarNameError exception is raised.
-	 """
-
-	 return _pytave.setvar(name, val, fglobal)
+	def __setitem__(self, name, value):
+		if not isinstance(name, basestring):
+			raise TypeError('Expected a string, not a ' + repr(type(name)))
+		_pytave.setvar(name, value, self.global_variables)
 
-def isvar(name, fglobal = False):
-	 """Checks whether a variable exists in the current Octave scope.
-	 It is quite fast because the Octave parser is bypassed. 
+	def __contains__(self, name):
+		if not isinstance(name, basestring):
+			raise TypeError('Expected a string, not a ' + repr(type(name)))
+		return _pytave.isvar(name, self.global_variables)
 
-	 global specifies that a global variable should be looked up;
-	 otherwise, local variable (in the current scope) is always
-	 searched for.
-
-	 If the variable is defined, returns True, otherwise returns False.
-	 """
-
-	 return _pytave.isvar(name, fglobal)
+locals = _VariablesDict(global_variables=False)
+globals = _VariablesDict(global_variables=True)
 
 def push_scope():
 	 """Creates a new anonymous local variable scope on the Octave call
--- a/test/test.py	Mon Jun 08 11:55:19 2009 +0200
+++ b/test/test.py	Mon Jun 08 11:58:20 2009 +0200
@@ -120,32 +120,30 @@
 	except Exception, e:
 		fail("eval: %s" % code, e)
 
-def testsetget(name,value):
-    try:
-	pytave.setvar(name,value)
-	result, = pytave.feval(1, "isequal", value, pytave.getvar(name))
-	if not result:
-	    print "FAIL: set/get: ", name," -> ",value," results diverged"
-    except Exception, e:
-	print "FAIL: set/get: ", name, ":"
+def testsetget(variables, name, value):
+	try:
+		variables[name] = value
+		if name not in variables:
+			print "FAIL: set/get: ", name,": Should exist, not there."
+		result, = pytave.feval(1, "isequal", value, variables[name])
+		if not result:
+			print "FAIL: set/get: ", name," -> ",value," results diverged"
+	except Exception, e:
+		print "FAIL: set/get: ", name, ":", e
 
-def testvarnameerror(name):
-    try:
-	pytave.setvar(name)
-	print "FAIL: ", name
-    except pytave.VarNameError:
-	pass
-    except Exception, e:
-	print "FAIL: ", name
-			fail("eval: %s : because %s != %s" % (code, results, expectations))
+def testexception(exception, func):
+	try:
+		func()
+		print "FAIL: ", name
 	except Exception, e:
-		fail("eval: %s" % code, e)
+		if not isinstance(e, exception):
+			print "FAIL:", name, ":", e
 
 def testlocalscope(x):
 
     @pytave.local_scope
     def sloppy_factorial(x):
-	pytave.setvar("x",x)
+	pytave.locals["x"] = x
 	xm1, = pytave.eval(1,"x-1")
 	if xm1 > 0:
 	    fxm1 = sloppy_factorial(xm1)
@@ -256,6 +254,29 @@
 testevalexpect(1, "{2}", ([2],))
 testevalexpect(2, "struct('foo', 2)", ({'foo': 2},))
 
+testsetget(pytave.locals, "xxx", [1,2,3])
+testsetget(pytave.globals, "xxx", [1,2,3])
+
+def func():
+	pytave.locals["this is not a valid Octave identifier"] = 1
+testexception(pytave.VarNameError, func)
+
+def func():
+	pytave.locals["nonexistentvariable"]
+testexception(KeyError, func)
+
+def func(key):
+	pytave.locals[key] = 1
+testexception(TypeError, lambda: func(0.1))
+testexception(TypeError, lambda: func(1))
+testexception(TypeError, lambda: func([]))
+
+def func(key):
+	pytave.locals[key]
+testexception(TypeError, lambda: func(0.1))
+testexception(TypeError, lambda: func(1))
+testexception(TypeError, lambda: func([]))
+
 testlocalscope(5)
 
 # Emacs