def test_initial_values(self): """ Tests if expressions for initial values are handled correctly. """ code = """ [[model]] c.p = 1.0 c.q = 10 * 2 [engine] time = 0 bind time [c] dot(p) = 1 dot(q) = 2 """ myokit.parse(code) # Non-literal value code = """ [[model]] c.p = 1.0 c.q = 10 * 2 + b [engine] time = 0 bind time [c] dot(p) = 1 dot(q) = 2 """ self.assertRaises(myokit.ParseError, myokit.parse, code)
def test_cyclical_reference_error(self): """ Test cyclical reference errors. """ code = """ [[model]] [engine] time = 0 bind time [c] x = y y = x """ self.assertRaises(myokit.ParseError, myokit.parse, code) with self.assertRaises(myokit.ParseError) as e: myokit.parse(code) e = e.exception self.assertIsInstance(e.cause, myokit.IntegrityError) self.assertIsInstance(e.cause, myokit.CyclicalDependencyError) self.assertIn(e.line, [8, 9]) self.assertEqual(e.char, 12) from myokit._parsing import NAME if e.line == 8: self.assertEqual(e.cause.token(), (NAME, 'x', 8, 12)) else: self.assertEqual(e.cause.token(), (NAME, 'y', 9, 12))
def test_unresolved_reference_error(self): """ Test unresolved reference errors. """ code = """ [[model]] [engine] time = 0 bind time [c] x = a """ self.assertRaises(myokit.ParseError, myokit.parse, code) try: myokit.parse(code) except myokit.ParseError as e: self.assertIsInstance(e.cause, myokit.IntegrityError) self.assertIsInstance(e.cause, myokit.UnresolvedReferenceError) # Token is not set when resolving name (string) self.assertIsNone(e.cause.token()) # But line and char should be set in parse error by parser self.assertEqual(e.line, 8) self.assertEqual(e.char, 16) # Check str() method (only implemented for parse errors) str(e)
def load_script(filename): """ Loads the script section from an ``mmt`` file. Raises a :class:`SectionNotFoundError` if no script section is found. """ filename = _examplify(filename) with open(filename, 'r') as f: section = myokit.split(f)[2] if not section.strip(): raise myokit.SectionNotFoundError('Script section not found.') return myokit.parse(section.splitlines())[2]
def load(filename): """ Reads an ``mmt`` file and returns a tuple ``(model, protocol, embedded script)``. If the file specified by ``filename`` doesn't contain one of these parts the corresponding entry in the tuple will be ``None``. """ f = open(_examplify(filename), 'r') try: return myokit.parse(f) finally: f.close()
def test_clone_code_parse(self): # Test the cloning, code and parse() by exporting models and # reading them in again. models = [ 'conditional.mmt', ] for model in models: m1 = myokit.load_model(os.path.join(DIR_DATA, model)) c1 = m1.code() m2 = myokit.parse(c1)[0] c2 = m2.code() self.assertEqual(c1, c2) m3 = m2.clone() c3 = m3.code() self.assertEqual(c1, c3)
def test_aliases(self): code = """ [[model]] [engine] time = 0 bind time [c] p = 1 [d] use c.p q = 2 * p [e] use c.p as ploep r = 10 * ploep """ myokit.parse(code) # Duplicate alias is allowed code = """ [[model]] [engine] time = 0 bind time [c] p = 1 [d] use c.p as one use c.p as two q = 2 * one """ myokit.parse(code) # Duplicate name code = """ [[model]] [engine] time = 0 bind time [c] p = 1 [d] q = 10 use c.p as q """ self.assertRaises(myokit.ParseError, myokit.parse, code) # API Alias m = myokit.Model('InvalidNameAlias') c = m.add_component('c') p = c.add_variable('p') p.set_rhs('4 / 20') q = c.add_variable('q') q.set_rhs('-sqrt(3)') d = m.add_component('d') r = d.add_variable('r') r.set_rhs('1 / 1e2') d.add_alias('p', p) # Invalid name self.assertRaises(myokit.InvalidNameError, d.add_alias, '_plf', q) # Duplicate names self.assertRaises(myokit.DuplicateName, d.add_alias, 'p', q) self.assertRaises(myokit.DuplicateName, c.add_alias, 'p', r)