def test_connected_expr(self): ConnectedExprEvaluator("var1[x]", self.top)._parse() try: ConnectedExprEvaluator("var1[x]", self.top, is_dest=True)._parse() except Exception as err: self.assertEqual(str(err), "bad destination expression 'var1[x]':" " only constant indices are allowed for arrays and slices") else: self.fail("Exception expected") ConnectedExprEvaluator("var1(2.3)", self.top)._parse() try: ConnectedExprEvaluator("var1(2.3)", self.top, is_dest=True)._parse() except Exception as err: self.assertEqual(str(err), "bad destination expression 'var1(2.3)':" " not assignable") else: self.fail("Exception expected") ConnectedExprEvaluator("var1[1:5:2]", self.top)._parse() ConnectedExprEvaluator("var1[1:5:2]", self.top, is_dest=True)._parse() ConnectedExprEvaluator("var1[1:x:2]", self.top)._parse() try: ConnectedExprEvaluator("var1[1:x:2]", self.top, is_dest=True)._parse() except Exception as err: self.assertEqual(str(err), "bad destination expression" " 'var1[1:x:2]': only constant indices are allowed" " for arrays and slices") else: self.fail("Exception expected")
def check_connect(self, src, dest, scope): """Check validity of connecting a source expression to a destination expression.""" if self.get_source(dest) is not None: scope.raise_exception( "'%s' is already connected to source '%s'" % (dest, self.get_source(dest)), RuntimeError) destexpr = ConnectedExprEvaluator(dest, scope, getter='get_wrapped_attr', is_dest=True) srcexpr = ConnectedExprEvaluator(src, scope, getter='get_wrapped_attr') srccomps = srcexpr.get_referenced_compnames() destcomps = destexpr.get_referenced_compnames() if destcomps and destcomps.pop() in srccomps: raise RuntimeError("'%s' and '%s' refer to the same component." % (src, dest)) return srcexpr, destexpr
def check_connect(self, src, dest, scope): """Check validity of connecting a source expression to a destination expression, and determine if we need to create links to pseudocomps. """ if self.get_source(dest) is not None: scope.raise_exception( "'%s' is already connected to source '%s'" % (dest, self.get_source(dest)), RuntimeError) destexpr = ConnectedExprEvaluator(dest, scope, is_dest=True) srcexpr = ConnectedExprEvaluator(src, scope, getter='get_attr') srccomps = srcexpr.get_referenced_compnames() destcomps = list(destexpr.get_referenced_compnames()) if destcomps and destcomps[0] in srccomps: raise RuntimeError("'%s' and '%s' refer to the same component." % (src, dest)) return srcexpr, destexpr, self._needs_pseudo(scope, srcexpr, destexpr)
def check_connect(self, src, dest, scope): """Check validity of connecting a source expression to a destination expression, and determine if we need to create links to pseudocomps. """ if self.get_source(dest) is not None: scope.raise_exception( "'%s' is already connected to source '%s'" % (dest, self.get_source(dest)), RuntimeError) destexpr = ConnectedExprEvaluator(dest, scope, is_dest=True) srcexpr = ConnectedExprEvaluator(src, scope, getter='get_attr_w_copy') srccomps = srcexpr.get_referenced_compnames() destcomps = list(destexpr.get_referenced_compnames()) if destcomps and destcomps[0] in srccomps: raise RuntimeError("'%s' and '%s' refer to the same component." % (src, dest)) try: return srcexpr, destexpr, self._needs_pseudo(srcexpr, destexpr) except AttributeError as err: exc_type, value, traceback = sys.exc_info() invalid_vars = srcexpr.get_unresolved() + destexpr.get_unresolved() parts = invalid_vars[0].rsplit('.', 1) parent = repr(scope.name) if scope.name else 'top level assembly' vname = repr(parts[0]) if len(parts) > 1: parent = repr(parts[0]) vname = repr(parts[1]) msg = "{parent} has no variable {vname}" msg = msg.format(parent=parent, vname=vname) raise AttributeError, AttributeError(msg), traceback
def __init__(self, parent, srcexpr, destexpr=None, translate=True, pseudo_type=None): if destexpr is None: destexpr = DummyExpr() self.name = _get_new_name() self._inmap = {} # mapping of component vars to our inputs self._meta = {} self._valid = False self._parent = parent self._inputs = [] self.force_fd = False self._provideJ_bounds = None self._pseudo_type = pseudo_type # a string indicating the type of pseudocomp # this is, e.g., 'units', 'constraint', 'objective', # or 'multi_var_expr' self._orig_src = srcexpr.text self._orig_dest = destexpr.text self.Jsize = None varmap = {} rvarmap = {} for i, ref in enumerate(srcexpr.refs()): in_name = 'in%d' % i self._inputs.append(in_name) self._inmap[ref] = in_name varmap[ref] = in_name rvarmap.setdefault(_get_varname(ref), set()).add(ref) setattr(self, in_name, None) refs = list(destexpr.refs()) if refs: if len(refs) == 1: setattr(self, 'out0', None) else: raise RuntimeError( "output of PseudoComponent must reference only one variable" ) varmap[refs[0]] = 'out0' rvarmap.setdefault(_get_varname(refs[0]), set()).add(refs[0]) for name, meta in srcexpr.get_metadata(): for rname in rvarmap[name]: self._meta[varmap[rname]] = meta for name, meta in destexpr.get_metadata(): for rname in rvarmap[name]: self._meta[varmap[rname]] = meta if translate: xformed_src = transform_expression(srcexpr.text, self._inmap) else: xformed_src = srcexpr.text out_units = self._meta['out0'].get('units') pq = None if out_units is not None: # evaluate the src expression using UnitsOnlyPQ objects tmpdict = {} # First, replace values with UnitsOnlyPQ objects for inp in self._inputs: units = self._meta[inp].get('units') if units: tmpdict[inp] = UnitsOnlyPQ(0., units) else: tmpdict[inp] = 0. pq = eval(xformed_src, _expr_dict, tmpdict) self._srcunits = pq.unit unitnode = ast.parse(xformed_src) try: unitxform = unit_xform(unitnode, self._srcunits, out_units) except Exception as err: raise TypeError("Incompatible units for '%s' and '%s': %s" % (srcexpr.text, destexpr.text, err)) unit_src = print_node(unitxform) xformed_src = unit_src else: self._srcunits = None self._srcexpr = ConnectedExprEvaluator(xformed_src, scope=self) # this is just the equation string (for debugging) if self._orig_dest: self._outdests = [self._orig_dest] if pq is None: sunit = dunit = '' else: sunit = "'%s'" % pq.get_unit_name() dunit = "'%s'" % out_units self._orig_expr = "%s %s -> %s %s" % (self._orig_src, sunit, self._orig_dest, dunit) else: self._outdests = [] self._orig_expr = self._orig_src #if destexpr and destexpr.text: #out = destexpr.text #else: #out = 'out0' #if translate: #src = transform_expression(self._srcexpr.text, #_invert_dict(self._inmap)) #else: #src = self._srcexpr.text #self._expr_conn = (src, out) # the actual expression connection self.missing_deriv_policy = 'error'