def testAddLiteral(self): """Test adding a literal to an operator node.""" op = literals.Operator(name="add", symbol="+", operation=numpy.add, nin=2, nout=1) self.assertRaises(ValueError, op.getValue) op._value = 1 self.assertEqual(op.getValue(), 1) # Test addition and operations a = literals.Argument(name="a", value=0) b = literals.Argument(name="b", value=0) op.addLiteral(a) self.assertRaises(ValueError, op.getValue) op.addLiteral(b) self.assertAlmostEqual(0, op.value) a.setValue(1) b.setValue(2) self.assertAlmostEqual(3, op.value) a.setValue(None) # Test for self-references # Try to add self op = literals.Operator(name="add", symbol="+", operation=numpy.add, nin=2, nout=1) op.addLiteral(a) self.assertRaises(ValueError, op.addLiteral, op) # Try to add argument that contains self op2 = literals.Operator(name="sub", symbol="-", operation=numpy.subtract, nin=2, nout=1) op2.addLiteral(op) self.assertRaises(ValueError, op.addLiteral, op2) return
def testInit(self): """Test that everthing initializes as expected.""" op = literals.Operator(symbol="+", operation=numpy.add, nin=2) self.assertEqual("+", op.symbol) self.assertEqual(numpy.add, op.operation) self.assertEqual(2, op.nin) self.assertEqual(1, op.nout) self.assertEqual(None, op._value) self.assertEqual([], op.args) return
def __call__(self, *args): """Call the operator builder. This creates a new builder that encapsulates the operation. args -- Arguments of the operation. Raises ValueError if self.literal.nin >= 0 and len(args) != op.nin """ newobj = OperatorBuilder(self.name) # If all we have is a name, then we assume that it is the name of a # numpy operator, and we use the corresponding Operator. if self.literal is None: ufunc = getattr(numpy, self.name) newobj.literal = literals.UFuncOperator(ufunc) self.literal = newobj.literal # If the Operator is already specified, then copy its attributes to a # new Operator inside of the new OperatorBuilder. else: op = literals.Operator() op.name = self.literal.name op.symbol = self.literal.name op.nin = self.literal.nin op.nout = self.literal.nout op.operation = self.literal.operation newobj.literal = op # Now that we have a literal, let's check our inputs literal = newobj.literal if literal.nin >= 0 and len(args) != literal.nin: raise ValueError("%s takes %i arguments (%i given)"%\ (self.literal, self.literal.nin, len(args))) # Wrap scalar arguments for i, arg in enumerate(args): # Wrap the argument if it is not already if not isinstance(arg, BaseBuilder): name = self.name + "_%i" % i arg = ArgumentBuilder(value=arg, name=name, const=True) newobj.literal.addLiteral(arg.literal) return newobj
def wrapFunction(name, func, nin=2, nout=1): """Wrap a function in an OperatorBuilder instance. name -- The name of the function func -- A callable python object nin -- The number of input arguments (default 2) nout -- The number of return values (default 1) Returns the OperatorBuilder instance that wraps the function. """ op = literals.Operator() op.name = name op.symbol = name op.nin = nin op.nout = nout op.operation = func # Create the OperatorBuilder opbuilder = OperatorBuilder(name, op) return opbuilder
def testValue(self): """Test value.""" # Test addition and operations op = literals.Operator(symbol="+", operation=numpy.add, nin=2) a = literals.Argument(value=0) b = literals.Argument(value=0) op.addLiteral(a) op.addLiteral(b) self.assertAlmostEquals(0, op.value) # Test update from the nodes a.setValue(4) self.assertTrue(op._value is None) self.assertAlmostEqual(4, op.value) self.assertAlmostEqual(4, op.getValue()) b.value = 2 self.assertTrue(op._value is None) self.assertAlmostEqual(6, op.value) return
def testIdentity(self): """Make sure an Argument is an Argument.""" op = literals.Operator(symbol="+", operation=numpy.add, nin=2) self.assertTrue(abcs.issubclass(literals.Operator, abcs.OperatorABC)) self.assertTrue(abcs.isinstance(op, abcs.OperatorABC)) return