myokit 1.34.0__py3-none-any.whl → 1.35.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. myokit/__init__.py +5 -23
  2. myokit/__main__.py +70 -117
  3. myokit/_aux.py +5 -8
  4. myokit/_config.py +22 -31
  5. myokit/_datablock.py +26 -70
  6. myokit/_datalog.py +23 -53
  7. myokit/_err.py +13 -15
  8. myokit/_expressions.py +35 -55
  9. myokit/_io.py +5 -22
  10. myokit/_model_api.py +34 -47
  11. myokit/_myokit_version.py +1 -5
  12. myokit/_parsing.py +17 -25
  13. myokit/_progress.py +4 -7
  14. myokit/_protocol.py +6 -9
  15. myokit/_sim/__init__.py +7 -24
  16. myokit/_sim/cable.c +1 -3
  17. myokit/_sim/cable.py +3 -5
  18. myokit/_sim/cmodel.h +1 -3
  19. myokit/_sim/cmodel.py +1 -4
  20. myokit/_sim/compiler.py +1 -4
  21. myokit/_sim/cvodessim.c +1 -4
  22. myokit/_sim/cvodessim.py +1 -4
  23. myokit/_sim/fiber_tissue.c +2 -6
  24. myokit/_sim/fiber_tissue.py +3 -5
  25. myokit/_sim/jacobian.py +6 -7
  26. myokit/_sim/mcl.h +51 -53
  27. myokit/_sim/opencl.py +9 -22
  28. myokit/_sim/openclsim.c +2 -6
  29. myokit/_sim/openclsim.py +6 -6
  30. myokit/_sim/pacing.h +2 -6
  31. myokit/_sim/rhs.c +3 -10
  32. myokit/_sim/rhs.py +4 -13
  33. myokit/_sim/sundials.py +1 -4
  34. myokit/_system.py +10 -16
  35. myokit/_unit.py +3 -12
  36. myokit/float.py +0 -3
  37. myokit/formats/__init__.py +8 -10
  38. myokit/formats/ansic/__init__.py +0 -3
  39. myokit/formats/ansic/_ewriter.py +2 -4
  40. myokit/formats/ansic/_exporter.py +0 -3
  41. myokit/formats/axon/__init__.py +1 -3
  42. myokit/formats/axon/_abf.py +12 -15
  43. myokit/formats/axon/_atf.py +5 -6
  44. myokit/formats/axon/_importer.py +0 -3
  45. myokit/formats/cellml/__init__.py +0 -3
  46. myokit/formats/cellml/_ewriter.py +3 -6
  47. myokit/formats/cellml/_exporter.py +3 -6
  48. myokit/formats/cellml/_importer.py +1 -4
  49. myokit/formats/cellml/v1/__init__.py +0 -4
  50. myokit/formats/cellml/v1/_api.py +7 -10
  51. myokit/formats/cellml/v1/_parser.py +2 -5
  52. myokit/formats/cellml/v1/_writer.py +2 -11
  53. myokit/formats/cellml/v2/__init__.py +0 -3
  54. myokit/formats/cellml/v2/_api.py +7 -16
  55. myokit/formats/cellml/v2/_parser.py +2 -5
  56. myokit/formats/cellml/v2/_writer.py +1 -4
  57. myokit/formats/channelml/__init__.py +0 -3
  58. myokit/formats/channelml/_importer.py +4 -14
  59. myokit/formats/cpp/__init__.py +1 -3
  60. myokit/formats/cpp/_ewriter.py +0 -3
  61. myokit/formats/cuda/__init__.py +0 -3
  62. myokit/formats/cuda/_ewriter.py +2 -4
  63. myokit/formats/cuda/_exporter.py +0 -3
  64. myokit/formats/easyml/__init__.py +0 -3
  65. myokit/formats/easyml/_ewriter.py +9 -11
  66. myokit/formats/easyml/_exporter.py +0 -3
  67. myokit/formats/html/__init__.py +0 -3
  68. myokit/formats/html/_exporter.py +0 -3
  69. myokit/formats/html/_flatten.py +5 -21
  70. myokit/formats/latex/__init__.py +0 -3
  71. myokit/formats/latex/_ewriter.py +1 -4
  72. myokit/formats/latex/_exporter.py +3 -5
  73. myokit/formats/mathml/__init__.py +0 -3
  74. myokit/formats/mathml/_ewriter.py +2 -11
  75. myokit/formats/mathml/_parser.py +3 -5
  76. myokit/formats/matlab/__init__.py +0 -3
  77. myokit/formats/matlab/_ewriter.py +1 -4
  78. myokit/formats/matlab/_exporter.py +0 -3
  79. myokit/formats/opencl/__init__.py +0 -3
  80. myokit/formats/opencl/_ewriter.py +2 -4
  81. myokit/formats/opencl/_exporter.py +0 -3
  82. myokit/formats/python/__init__.py +0 -3
  83. myokit/formats/python/_ewriter.py +2 -5
  84. myokit/formats/python/_exporter.py +0 -3
  85. myokit/formats/python/template/sim.py +10 -10
  86. myokit/formats/sbml/__init__.py +0 -3
  87. myokit/formats/sbml/_api.py +17 -11
  88. myokit/formats/sbml/_importer.py +1 -4
  89. myokit/formats/sbml/_parser.py +2 -5
  90. myokit/formats/stan/__init__.py +0 -3
  91. myokit/formats/stan/_ewriter.py +2 -4
  92. myokit/formats/stan/_exporter.py +1 -4
  93. myokit/formats/sympy/__init__.py +0 -3
  94. myokit/formats/sympy/_ereader.py +1 -4
  95. myokit/formats/sympy/_ewriter.py +2 -5
  96. myokit/formats/wcp/__init__.py +0 -3
  97. myokit/formats/wcp/_wcp.py +1 -7
  98. myokit/formats/xml/__init__.py +0 -3
  99. myokit/formats/xml/_exporter.py +0 -3
  100. myokit/formats/xml/_split.py +0 -3
  101. myokit/gui/__init__.py +75 -247
  102. myokit/gui/datablock_viewer.py +100 -83
  103. myokit/gui/datalog_viewer.py +32 -44
  104. myokit/gui/explorer.py +15 -21
  105. myokit/gui/ide.py +105 -125
  106. myokit/gui/progress.py +9 -9
  107. myokit/gui/source.py +405 -374
  108. myokit/gui/vargrapher.py +2 -12
  109. myokit/lib/deps.py +7 -8
  110. myokit/lib/guess.py +1 -2
  111. myokit/lib/hh.py +5 -7
  112. myokit/lib/markov.py +9 -11
  113. myokit/lib/multi.py +1 -3
  114. myokit/lib/plots.py +1 -3
  115. myokit/pacing.py +0 -3
  116. myokit/pype.py +7 -18
  117. myokit/tests/__init__.py +3 -6
  118. myokit/tests/ansic_event_based_pacing.py +1 -4
  119. myokit/tests/ansic_fixed_form_pacing.py +1 -4
  120. myokit/tests/test_aux.py +9 -23
  121. myokit/tests/test_cellml_v1_api.py +1 -16
  122. myokit/tests/test_cellml_v1_parser.py +0 -15
  123. myokit/tests/test_cellml_v1_writer.py +0 -9
  124. myokit/tests/test_cellml_v2_api.py +1 -16
  125. myokit/tests/test_cellml_v2_parser.py +0 -15
  126. myokit/tests/test_cellml_v2_writer.py +0 -9
  127. myokit/tests/test_cmodel.py +0 -9
  128. myokit/tests/test_compiler_detection.py +1 -11
  129. myokit/tests/test_component.py +0 -10
  130. myokit/tests/test_config.py +33 -66
  131. myokit/tests/test_datablock.py +1 -9
  132. myokit/tests/test_datalog.py +4 -21
  133. myokit/tests/test_dependency_checking.py +8 -23
  134. myokit/tests/test_expressions.py +0 -9
  135. myokit/tests/test_float.py +1 -5
  136. myokit/tests/test_formats.py +0 -9
  137. myokit/tests/test_formats_axon.py +1 -9
  138. myokit/tests/test_formats_cellml.py +0 -15
  139. myokit/tests/test_formats_channelml.py +0 -15
  140. myokit/tests/test_formats_easyml.py +0 -14
  141. myokit/tests/test_formats_exporters.py +1 -16
  142. myokit/tests/test_formats_expression_writers.py +1 -17
  143. myokit/tests/test_formats_html.py +0 -3
  144. myokit/tests/test_formats_importers.py +1 -16
  145. myokit/tests/test_formats_mathml_content.py +0 -9
  146. myokit/tests/test_formats_mathml_presentation.py +0 -9
  147. myokit/tests/test_formats_opencl.py +0 -10
  148. myokit/tests/test_formats_sbml.py +0 -15
  149. myokit/tests/test_formats_sympy.py +0 -9
  150. myokit/tests/test_formats_wcp.py +1 -3
  151. myokit/tests/test_io.py +6 -14
  152. myokit/tests/test_jacobian_calculator.py +1 -9
  153. myokit/tests/test_jacobian_tracer.py +0 -9
  154. myokit/tests/test_lib_deps.py +0 -9
  155. myokit/tests/test_lib_guess.py +0 -9
  156. myokit/tests/test_lib_hh.py +1 -9
  157. myokit/tests/test_lib_markov.py +1 -9
  158. myokit/tests/test_lib_multi.py +0 -9
  159. myokit/tests/test_lib_plots.py +0 -3
  160. myokit/tests/test_meta.py +0 -3
  161. myokit/tests/test_model.py +0 -10
  162. myokit/tests/test_model_building.py +2 -17
  163. myokit/tests/test_opencl_info.py +5 -14
  164. myokit/tests/test_pacing_factory.py +0 -3
  165. myokit/tests/test_pacing_system_c.py +0 -9
  166. myokit/tests/test_pacing_system_py.py +0 -9
  167. myokit/tests/test_parsing.py +5 -20
  168. myokit/tests/test_progress_reporters.py +0 -3
  169. myokit/tests/test_protocol.py +0 -9
  170. myokit/tests/test_protocol_floating_point.py +0 -9
  171. myokit/tests/test_protocol_time_series.py +0 -10
  172. myokit/tests/test_pype.py +0 -9
  173. myokit/tests/test_quantity.py +0 -9
  174. myokit/tests/test_rhs_benchmarker.py +1 -9
  175. myokit/tests/test_sbml_api.py +0 -15
  176. myokit/tests/test_sbml_parser.py +0 -15
  177. myokit/tests/test_simulation_1d.py +1 -10
  178. myokit/tests/test_simulation_cvodes.py +8 -16
  179. myokit/tests/test_simulation_cvodes_from_disk.py +0 -3
  180. myokit/tests/test_simulation_fiber_tissue.py +1 -10
  181. myokit/tests/test_simulation_log_interval.py +0 -9
  182. myokit/tests/test_simulation_opencl.py +1 -10
  183. myokit/tests/test_simulation_opencl_log_interval.py +1 -3
  184. myokit/tests/test_simulation_opencl_vs_cvode.py +1 -10
  185. myokit/tests/test_simulation_opencl_vs_sim1d.py +1 -10
  186. myokit/tests/test_system_info.py +1 -11
  187. myokit/tests/test_tools.py +0 -9
  188. myokit/tests/test_unit.py +0 -9
  189. myokit/tests/test_user_functions.py +0 -10
  190. myokit/tests/test_variable.py +0 -10
  191. myokit/tools.py +5 -21
  192. myokit/units.py +0 -3
  193. {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/METADATA +7 -7
  194. {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/RECORD +198 -200
  195. myokit/_exec_new.py +0 -15
  196. myokit/_exec_old.py +0 -15
  197. {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/LICENSE.txt +0 -0
  198. {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/WHEEL +0 -0
  199. {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/entry_points.txt +0 -0
  200. {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/top_level.txt +0 -0
myokit/_expressions.py CHANGED
@@ -5,26 +5,14 @@
5
5
  # This file is part of Myokit.
6
6
  # See http://myokit.org for copyright, sharing, and licensing details.
7
7
  #
8
- from __future__ import absolute_import, division
9
- from __future__ import print_function, unicode_literals
10
-
8
+ import io
11
9
  import math
12
10
  import numpy
13
11
 
14
12
  import myokit
15
- from myokit import IntegrityError
16
13
 
17
- # StringIO in Python 2 and 3
18
- try:
19
- from cStringIO import StringIO
20
- except ImportError:
21
- from io import StringIO
14
+ from myokit import IntegrityError
22
15
 
23
- # Strings in Python 2 and 3
24
- try:
25
- basestring
26
- except NameError: # pragma: no python 2 cover
27
- basestring = str
28
16
 
29
17
  # Expression precedence levels
30
18
  FUNCTION_CALL = 70
@@ -37,7 +25,7 @@ CONDITION_AND = 10
37
25
  LITERAL = 0
38
26
 
39
27
 
40
- class Expression(object):
28
+ class Expression:
41
29
  """
42
30
  Myokit's most generic interface for expressions. All expressions extend
43
31
  this class.
@@ -85,8 +73,8 @@ class Expression(object):
85
73
  self._cached_unit_tolerant = None
86
74
  self._cached_unit_strict = None
87
75
 
88
- def __bool__(self): # pragma: no python 2 cover
89
- """ Python 3 method to determine the outcome of "if expression". """
76
+ def __bool__(self):
77
+ # Determines the outcome of "if expression".
90
78
  return True
91
79
 
92
80
  def bracket(self, op=None):
@@ -142,7 +130,7 @@ class Expression(object):
142
130
  """
143
131
  # Note: Because variable and component names can change, the output of
144
132
  # code can not be cached (for non-literal expressions).
145
- b = StringIO()
133
+ b = io.StringIO()
146
134
  self._code(b, component)
147
135
  return b.getvalue()
148
136
 
@@ -540,8 +528,6 @@ class Expression(object):
540
528
  raise NotImplementedError
541
529
 
542
530
  def __float__(self):
543
- # Cast to float is required in Python 3: numpy float etc. are ok, but
544
- # this is deprecated.
545
531
  return float(self.eval())
546
532
 
547
533
  def __getitem__(self, key):
@@ -551,9 +537,7 @@ class Expression(object):
551
537
  if self._cached_hash is None:
552
538
  self._cached_hash = hash(self._polish())
553
539
  return self._cached_hash
554
- # Note for Python3:
555
- # In Python3, anything that has an __eq__ stops inheriting this hash
556
- # method!
540
+ # Note: anything that has an __eq__ stops inheriting this hash method!
557
541
  # From: https://docs.python.org/3.1/reference/datamodel.html
558
542
  # > If a class that overrides __eq__() needs to retain the
559
543
  # implementation of __hash__() from a parent class, the interpreter
@@ -631,10 +615,6 @@ class Expression(object):
631
615
  def __ne__(self, other):
632
616
  return not self.__eq__(other)
633
617
 
634
- def __nonzero__(self): # pragma: no python 3 cover
635
- """ Python 2 method to determine the outcome of "if expression". """
636
- return True
637
-
638
618
  def operator_rep(self):
639
619
  """
640
620
  Returns a representation of this expression's type. (For example '+' or
@@ -653,7 +633,7 @@ class Expression(object):
653
633
  variable id is immutable in the expression's lifetime.
654
634
  """
655
635
  if self._cached_polish is None:
656
- b = StringIO()
636
+ b = io.StringIO()
657
637
  self._polishb(b)
658
638
  self._cached_polish = b.getvalue()
659
639
  return self._cached_polish
@@ -670,7 +650,7 @@ class Expression(object):
670
650
 
671
651
  def pyfunc(self, use_numpy=True):
672
652
  """
673
- Converts this expression to python and returns the new function's
653
+ Converts this expression to Python and returns the new function's
674
654
  handle.
675
655
 
676
656
  By default, when converting mathematical functions such as ``log``, the
@@ -691,19 +671,19 @@ class Expression(object):
691
671
  # Create function
692
672
  local = {}
693
673
  if use_numpy:
694
- myokit._exec(c, {'numpy': numpy}, local)
674
+ exec(c, {'numpy': numpy}, local)
695
675
  else:
696
- myokit._exec(c, {'math': math}, local)
676
+ exec(c, {'math': math}, local)
697
677
 
698
678
  # Return
699
679
  return local['ex_pyfunc_generated']
700
680
 
701
681
  def pystr(self, use_numpy=False):
702
682
  """
703
- Returns a string representing this expression in python syntax.
683
+ Returns a string representing this expression in Python syntax.
704
684
 
705
685
  By default, built-in functions such as 'exp' are converted to the
706
- python version 'math.exp'. To use the numpy versions, set
686
+ Python version 'math.exp'. To use the numpy versions, set
707
687
  ``numpy=True``.
708
688
  """
709
689
  # Get expression writer
@@ -742,7 +722,7 @@ class Expression(object):
742
722
  Returns a string representing the parse tree corresponding to this
743
723
  expression.
744
724
  """
745
- b = StringIO()
725
+ b = io.StringIO()
746
726
  self._tree_str(b, 0)
747
727
  return b.getvalue()
748
728
 
@@ -855,7 +835,7 @@ class Number(Expression):
855
835
  _rbp = LITERAL
856
836
 
857
837
  def __init__(self, value, unit=None):
858
- super(Number, self).__init__()
838
+ super().__init__()
859
839
  if isinstance(value, myokit.Quantity):
860
840
  # Conversion from Quantity class
861
841
  if unit is not None:
@@ -869,7 +849,7 @@ class Number(Expression):
869
849
  self._value = float(value) if value else 0.0
870
850
  if unit is None or isinstance(unit, myokit.Unit):
871
851
  self._unit = unit
872
- elif isinstance(unit, basestring):
852
+ elif isinstance(unit, str):
873
853
  self._unit = myokit.parse_unit(unit)
874
854
  else:
875
855
  raise ValueError(
@@ -1013,10 +993,10 @@ class Name(LhsExpression):
1013
993
  *Extends:* :class:`LhsExpression`
1014
994
  """
1015
995
  _rbp = LITERAL
1016
- __hash__ = LhsExpression.__hash__ # For Python3, when __eq__ is present
996
+ __hash__ = LhsExpression.__hash__
1017
997
 
1018
998
  def __init__(self, value):
1019
- super(Name, self).__init__()
999
+ super().__init__()
1020
1000
  self._value = value
1021
1001
  self._references = set([self])
1022
1002
  self._proper = isinstance(self._value, myokit.Variable)
@@ -1054,7 +1034,7 @@ class Name(LhsExpression):
1054
1034
  except KeyError:
1055
1035
  pass
1056
1036
  b.write(self._value.qname(c))
1057
- elif isinstance(self._value, basestring):
1037
+ elif isinstance(self._value, str):
1058
1038
  # Allow strings for debugging
1059
1039
  b.write('str:' + str(self._value))
1060
1040
  else:
@@ -1125,7 +1105,7 @@ class Name(LhsExpression):
1125
1105
  return self._proper and self._value.is_state()
1126
1106
 
1127
1107
  def _polishb(self, b):
1128
- if isinstance(self._value, basestring):
1108
+ if isinstance(self._value, str):
1129
1109
  # Allow an exception for strings
1130
1110
  b.write('str:')
1131
1111
  b.write(self._value)
@@ -1153,7 +1133,7 @@ class Name(LhsExpression):
1153
1133
  b.write(' ' * n + str(self._value) + '\n')
1154
1134
 
1155
1135
  def _validate(self, trail):
1156
- super(Name, self)._validate(trail)
1136
+ super()._validate(trail)
1157
1137
  # Check value: String is allowed at construction for debugging, but
1158
1138
  # not here!
1159
1139
  if not self._proper:
@@ -1174,10 +1154,10 @@ class Derivative(LhsExpression):
1174
1154
  """
1175
1155
  _rbp = FUNCTION_CALL
1176
1156
  _nargs = [1] # Allows parsing as a function
1177
- __hash__ = LhsExpression.__hash__ # For Python3, when __eq__ is present
1157
+ __hash__ = LhsExpression.__hash__
1178
1158
 
1179
1159
  def __init__(self, op):
1180
- super(Derivative, self).__init__((op,))
1160
+ super().__init__((op,))
1181
1161
  if not isinstance(op, Name):
1182
1162
  raise IntegrityError(
1183
1163
  'The dot() operator can only be used on variables.',
@@ -1274,7 +1254,7 @@ class Derivative(LhsExpression):
1274
1254
  return self._op._value
1275
1255
 
1276
1256
  def _validate(self, trail):
1277
- super(Derivative, self)._validate(trail)
1257
+ super()._validate(trail)
1278
1258
  # Check that value is a variable has already been performed by name
1279
1259
  # Check if value is the name of a state variable
1280
1260
  if not self._op._value.is_state():
@@ -1295,7 +1275,7 @@ class PartialDerivative(LhsExpression):
1295
1275
  """
1296
1276
  _rbp = FUNCTION_CALL
1297
1277
  _nargs = [2] # Allows parsing as a function
1298
- __hash__ = LhsExpression.__hash__ # For Python3, when __eq__ is present
1278
+ __hash__ = LhsExpression.__hash__
1299
1279
 
1300
1280
  def __init__(self, var1, var2):
1301
1281
  if not isinstance(var1, (Name, Derivative)):
@@ -1306,7 +1286,7 @@ class PartialDerivative(LhsExpression):
1306
1286
  raise IntegrityError(
1307
1287
  'The second argument to a partial derivative must be a'
1308
1288
  ' variable name or an initial value.')
1309
- super(PartialDerivative, self).__init__((var1, var2))
1289
+ super().__init__((var1, var2))
1310
1290
 
1311
1291
  self._var1 = var1
1312
1292
  self._var2 = var2
@@ -1406,10 +1386,10 @@ class InitialValue(LhsExpression):
1406
1386
  """
1407
1387
  _rbp = FUNCTION_CALL
1408
1388
  _nargs = [1] # Allows parsing as a function
1409
- __hash__ = LhsExpression.__hash__ # For Python3, when __eq__ is present
1389
+ __hash__ = LhsExpression.__hash__
1410
1390
 
1411
1391
  def __init__(self, var):
1412
- super(InitialValue, self).__init__((var, ))
1392
+ super().__init__((var, ))
1413
1393
  if not isinstance(var, Name):
1414
1394
  raise IntegrityError(
1415
1395
  'The first argument to an initial value must be a variable'
@@ -1468,7 +1448,7 @@ class InitialValue(LhsExpression):
1468
1448
  return self._var._value
1469
1449
 
1470
1450
  def _validate(self, trail):
1471
- super(InitialValue, self)._validate(trail)
1451
+ super()._validate(trail)
1472
1452
  # Check if value is the name of a state variable
1473
1453
  var = self._var._value
1474
1454
  if not (isinstance(var, myokit.Variable) and var.is_state()):
@@ -1487,7 +1467,7 @@ class PrefixExpression(Expression):
1487
1467
  _rep = None
1488
1468
 
1489
1469
  def __init__(self, op):
1490
- super(PrefixExpression, self).__init__((op,))
1470
+ super().__init__((op,))
1491
1471
  self._op = op
1492
1472
 
1493
1473
  def bracket(self, op):
@@ -1586,7 +1566,7 @@ class InfixExpression(Expression):
1586
1566
  _spaces_round_operator = True
1587
1567
 
1588
1568
  def __init__(self, left, right):
1589
- super(InfixExpression, self).__init__((left, right))
1569
+ super().__init__((left, right))
1590
1570
  self._op1 = left
1591
1571
  self._op2 = right
1592
1572
 
@@ -2089,7 +2069,7 @@ class Function(Expression):
2089
2069
  _rbp = FUNCTION_CALL
2090
2070
 
2091
2071
  def __init__(self, *ops):
2092
- super(Function, self).__init__(ops)
2072
+ super().__init__(ops)
2093
2073
  if self._nargs is not None:
2094
2074
  if not len(ops) in self._nargs:
2095
2075
  raise IntegrityError(
@@ -2660,7 +2640,7 @@ class If(Function):
2660
2640
  _fname = 'if'
2661
2641
 
2662
2642
  def __init__(self, i, t, e):
2663
- super(If, self).__init__(i, t, e)
2643
+ super().__init__(i, t, e)
2664
2644
  self._i = i # if
2665
2645
  self._t = t # then
2666
2646
  self._e = e # else
@@ -2766,7 +2746,7 @@ class Piecewise(Function):
2766
2746
  _fname = 'piecewise'
2767
2747
 
2768
2748
  def __init__(self, *ops):
2769
- super(Piecewise, self).__init__(*ops)
2749
+ super().__init__(*ops)
2770
2750
 
2771
2751
  # Check number of arguments
2772
2752
  n = len(self._operands)
@@ -2854,7 +2834,7 @@ class Piecewise(Function):
2854
2834
  return iter(self._e)
2855
2835
 
2856
2836
 
2857
- class Condition(object):
2837
+ class Condition:
2858
2838
  """
2859
2839
  *Abstract class*
2860
2840
 
myokit/_io.py CHANGED
@@ -6,19 +6,11 @@
6
6
  # This file is part of Myokit.
7
7
  # See http://myokit.org for copyright, sharing, and licensing details.
8
8
  #
9
- from __future__ import absolute_import, division
10
- from __future__ import print_function, unicode_literals
11
-
12
9
  import array
10
+ import io
13
11
  import os
14
12
  import sys
15
13
 
16
- # StringIO in Python 2 and 3
17
- try:
18
- from cStringIO import StringIO
19
- except ImportError: # pragma: no python 2 cover
20
- from io import StringIO
21
-
22
14
  import myokit
23
15
 
24
16
 
@@ -145,8 +137,6 @@ def load_state_bin(filename):
145
137
  code = parts[1]
146
138
  if code not in ['d', 'f']: # pragma: no cover
147
139
  raise Exception('Invalid state file format [40].')
148
- # Convert code to str for Python 2.7.10 (see #225)
149
- code = str(code)
150
140
 
151
141
  size = int(parts[2])
152
142
  if size < 0: # pragma: no cover
@@ -154,10 +144,7 @@ def load_state_bin(filename):
154
144
 
155
145
  # Create array, read bytes into array
156
146
  ar = array.array(code)
157
- try:
158
- ar.frombytes(f.read(info))
159
- except AttributeError: # pragma: no python 3 cover
160
- ar.fromstring(f.read(info))
147
+ ar.frombytes(f.read(info))
161
148
 
162
149
  # Always store as little endian
163
150
  if sys.byteorder == 'big': # pragma: no cover
@@ -184,7 +171,7 @@ def save(filename=None, model=None, protocol=None, script=None):
184
171
  filename = os.path.expanduser(filename)
185
172
  f = open(filename, 'w')
186
173
  else:
187
- f = StringIO()
174
+ f = io.StringIO()
188
175
  out = None
189
176
  try:
190
177
  if model is not None:
@@ -297,8 +284,7 @@ def save_state_bin(filename, state, precision=myokit.DOUBLE_PRECISION):
297
284
  'This method requires the `zlib` module to be installed.')
298
285
 
299
286
  # Data type
300
- # Convert code to str for Python 2.7.10 (see #225)
301
- code = str('d' if precision == myokit.DOUBLE_PRECISION else 'f')
287
+ code = 'd' if precision == myokit.DOUBLE_PRECISION else 'f'
302
288
 
303
289
  # Create array, ensure it's little-endian
304
290
  ar = array.array(code, state)
@@ -311,10 +297,7 @@ def save_state_bin(filename, state, precision=myokit.DOUBLE_PRECISION):
311
297
  info.compress_type = zipfile.ZIP_DEFLATED
312
298
 
313
299
  # Write to compressed file
314
- try:
315
- ar = ar.tobytes()
316
- except AttributeError: # pragma: no python 3 cover
317
- ar = ar.tostring()
300
+ ar = ar.tobytes()
318
301
  with zipfile.ZipFile(filename, 'w') as f:
319
302
  f.writestr(info, ar)
320
303
 
myokit/_model_api.py CHANGED
@@ -4,25 +4,14 @@
4
4
  # This file is part of Myokit.
5
5
  # See http://myokit.org for copyright, sharing, and licensing details.
6
6
  #
7
- from __future__ import absolute_import, division
8
- from __future__ import print_function, unicode_literals
9
-
10
- from collections import OrderedDict
7
+ import io
11
8
  import math
12
9
  import re
13
- import myokit
14
10
 
15
- # StringIO in Python 2 and 3
16
- try:
17
- from cStringIO import StringIO
18
- except ImportError:
19
- from io import StringIO
11
+ from collections import OrderedDict
12
+
13
+ import myokit
20
14
 
21
- # Strings in Python 2 and 3
22
- try:
23
- basestring
24
- except NameError: # pragma: no cover
25
- basestring = str
26
15
 
27
16
  TAB = ' ' * 4
28
17
  NAME = re.compile(r'^[a-zA-Z]\w*$')
@@ -34,8 +23,6 @@ def check_name(name):
34
23
  Tests if the given name is a valid myokit name and raises a
35
24
  :class:`myokit.InvalidNameError` if it isn't.
36
25
  """
37
- # Note: Names are stored as str (so unicode in Python3)
38
- # But the regex restriction means their format is compatible with ascii.
39
26
  # Check str compatibility
40
27
  name = str(name)
41
28
 
@@ -65,7 +52,7 @@ class MetaDataContainer(dict):
65
52
  raise myokit.InvalidMetaDataNameError(
66
53
  'The key <' + str(key) + '>'
67
54
  ' is not a valid meta-data property identifier.')
68
- return super(MetaDataContainer, self).__getitem__(key)
55
+ return super().__getitem__(key)
69
56
 
70
57
  def __setitem__(self, key, item):
71
58
  # Check item
@@ -75,10 +62,10 @@ class MetaDataContainer(dict):
75
62
  raise myokit.InvalidMetaDataNameError(
76
63
  'The key <' + str(key) + '>'
77
64
  ' is not a valid meta-data property identifier.')
78
- super(MetaDataContainer, self).__setitem__(key, item)
65
+ super().__setitem__(key, item)
79
66
 
80
67
 
81
- class ObjectWithMeta(object):
68
+ class ObjectWithMeta:
82
69
  """
83
70
  Base class for objects with meta data.
84
71
 
@@ -87,7 +74,7 @@ class ObjectWithMeta(object):
87
74
  """
88
75
 
89
76
  def __init__(self):
90
- super(ObjectWithMeta, self).__init__()
77
+ super().__init__()
91
78
  self.meta = MetaDataContainer()
92
79
 
93
80
  def _clone_metadata(self, clone):
@@ -135,7 +122,7 @@ class ModelPart(ObjectWithMeta):
135
122
  The given parent should be a ModelPart or None. The name should be
136
123
  unique within the set of children for the given parent.
137
124
  """
138
- super(ModelPart, self).__init__()
125
+ super().__init__()
139
126
  self._parent = parent # This object's parent
140
127
  self._model = None # The model this object belongs to
141
128
  self._name = str(name) # Local name
@@ -153,7 +140,7 @@ class ModelPart(ObjectWithMeta):
153
140
  """
154
141
  Returns this object in ``mmt`` syntax.
155
142
  """
156
- b = StringIO()
143
+ b = io.StringIO()
157
144
  self._code(b, 0)
158
145
  return b.getvalue()
159
146
 
@@ -162,7 +149,7 @@ class ModelPart(ObjectWithMeta):
162
149
  Internal version of _code(), to be implemented by all subclasses.
163
150
 
164
151
  The argument ``t`` specifies the number of tabs to indent the code
165
- with. The argument ``b`` is a cStringIO buffer.
152
+ with. The argument ``b`` is a StringIO buffer.
166
153
  """
167
154
  raise NotImplementedError
168
155
 
@@ -249,7 +236,7 @@ class ModelPart(ObjectWithMeta):
249
236
  return self._uname
250
237
 
251
238
 
252
- class VarProvider(object):
239
+ class VarProvider:
253
240
  """
254
241
  *Abstract class*
255
242
 
@@ -463,7 +450,7 @@ class VarOwner(ModelPart, VarProvider):
463
450
  """
464
451
 
465
452
  def __init__(self, parent, name):
466
- super(VarOwner, self).__init__(parent, name)
453
+ super().__init__(parent, name)
467
454
  self._variables = {}
468
455
  # Set component
469
456
  self._component = self
@@ -789,7 +776,7 @@ class Model(ObjectWithMeta, VarProvider):
789
776
  """
790
777
 
791
778
  def __init__(self, name=None):
792
- super(Model, self).__init__()
779
+ super().__init__()
793
780
 
794
781
  # A dictionary of components
795
782
  self._components = {}
@@ -1124,7 +1111,7 @@ class Model(ObjectWithMeta, VarProvider):
1124
1111
 
1125
1112
  Line numbers can be added by setting ``line_numbers=True``.
1126
1113
  """
1127
- b = StringIO()
1114
+ b = io.StringIO()
1128
1115
  b.write('[[model]]\n')
1129
1116
  self._code(b, 0)
1130
1117
  if line_numbers:
@@ -1749,7 +1736,7 @@ class Model(ObjectWithMeta, VarProvider):
1749
1736
  'as external_component, or a string if only one '
1750
1737
  'component is provided'
1751
1738
  )
1752
- if isinstance(new_name, basestring):
1739
+ if isinstance(new_name, str):
1753
1740
  if len(external_component) != 1:
1754
1741
  raise TypeError(new_name_error_str)
1755
1742
  new_name = [new_name]
@@ -1757,7 +1744,7 @@ class Model(ObjectWithMeta, VarProvider):
1757
1744
  try:
1758
1745
  ok = (
1759
1746
  len(new_name) == len(external_component) and
1760
- all(isinstance(name, basestring) for name in new_name)
1747
+ all(isinstance(name, str) for name in new_name)
1761
1748
  )
1762
1749
  if not ok:
1763
1750
  raise TypeError(new_name_error_str)
@@ -1836,7 +1823,7 @@ class Model(ObjectWithMeta, VarProvider):
1836
1823
  'The variable <' + self_var.qname() + '> in the'
1837
1824
  ' given var_map\'s values is not part of this'
1838
1825
  ' model.')
1839
- elif isinstance(self_var, basestring):
1826
+ elif isinstance(self_var, str):
1840
1827
  try:
1841
1828
  self_var = self.var(self_var)
1842
1829
  except KeyError:
@@ -1858,7 +1845,7 @@ class Model(ObjectWithMeta, VarProvider):
1858
1845
  'The variable <' + ext_var.qname() + '> in the'
1859
1846
  ' given var_map\'s keys but is not part of the'
1860
1847
  ' source model.')
1861
- elif isinstance(ext_var, basestring):
1848
+ elif isinstance(ext_var, str):
1862
1849
  try:
1863
1850
  ext_var = ext_model.var(ext_var)
1864
1851
  except KeyError:
@@ -2597,7 +2584,7 @@ class Model(ObjectWithMeta, VarProvider):
2597
2584
 
2598
2585
  """
2599
2586
  n = self.count_states()
2600
- if isinstance(state, basestring):
2587
+ if isinstance(state, str):
2601
2588
  # String given. Parse into name:float map or list
2602
2589
  state = myokit.parse_state(state)
2603
2590
  if isinstance(state, dict):
@@ -2912,7 +2899,7 @@ class Model(ObjectWithMeta, VarProvider):
2912
2899
  accepted by :meth:`map_to_state`.
2913
2900
  """
2914
2901
  # Use map to state?
2915
- if isinstance(values, basestring) or isinstance(values, dict):
2902
+ if isinstance(values, str) or isinstance(values, dict):
2916
2903
  self._state_init = [
2917
2904
  myokit.Number(x) for x in self.map_to_state(values)]
2918
2905
  elif len(values) != len(self._state_vars):
@@ -3655,7 +3642,7 @@ class Component(VarOwner):
3655
3642
  """
3656
3643
 
3657
3644
  def __init__(self, model, name):
3658
- super(Component, self).__init__(model, name)
3645
+ super().__init__(model, name)
3659
3646
  self._alias_map = {} # Maps variable names to other variables names
3660
3647
 
3661
3648
  def _clone1(self, model, new_name=None):
@@ -3741,7 +3728,7 @@ class Component(VarOwner):
3741
3728
  var._delete(recursive=True, ignore_siblings=True)
3742
3729
 
3743
3730
  # Delete links to parent
3744
- super(Component, self)._delete()
3731
+ super()._delete()
3745
3732
 
3746
3733
  def alias(self, name):
3747
3734
  """
@@ -3873,7 +3860,7 @@ class Variable(VarOwner):
3873
3860
  """
3874
3861
 
3875
3862
  def __init__(self, parent, name):
3876
- super(Variable, self).__init__(parent, name)
3863
+ super().__init__(parent, name)
3877
3864
 
3878
3865
  # Index, only set if this is a state variable
3879
3866
  self._index = None
@@ -4280,7 +4267,7 @@ class Variable(VarOwner):
4280
4267
  self._remove_variable_internal(kid)
4281
4268
 
4282
4269
  # Remove parent links
4283
- super(Variable, self)._delete()
4270
+ super()._delete()
4284
4271
 
4285
4272
  def demote(self):
4286
4273
  """
@@ -4498,7 +4485,7 @@ class Variable(VarOwner):
4498
4485
  # Handle string and number rhs's
4499
4486
  model = self.model()
4500
4487
  if not isinstance(initial_value, myokit.Expression):
4501
- if isinstance(initial_value, basestring):
4488
+ if isinstance(initial_value, str):
4502
4489
  # Expressions are evaluated in model context
4503
4490
  initial_value = myokit.parse_expression(
4504
4491
  initial_value, context=model)
@@ -4588,9 +4575,9 @@ class Variable(VarOwner):
4588
4575
  # Create function
4589
4576
  local = {}
4590
4577
  if use_numpy:
4591
- myokit._exec(func, {'numpy': numpy}, local)
4578
+ exec(func, {'numpy': numpy}, local)
4592
4579
  else:
4593
- myokit._exec(func, {'math': math}, local)
4580
+ exec(func, {'math': math}, local)
4594
4581
  handle = local['var_pyfunc_generated']
4595
4582
 
4596
4583
  # Return
@@ -4766,7 +4753,7 @@ class Variable(VarOwner):
4766
4753
  # Handle strings and floats
4767
4754
  model = self.model()
4768
4755
  if not isinstance(value, myokit.Expression):
4769
- if isinstance(value, basestring):
4756
+ if isinstance(value, str):
4770
4757
  value = myokit.parse_expression(value, context=model)
4771
4758
  else:
4772
4759
  value = myokit.Number(value)
@@ -4834,7 +4821,7 @@ class Variable(VarOwner):
4834
4821
  """
4835
4822
  # Handle string and number rhs's
4836
4823
  if not isinstance(rhs, myokit.Expression):
4837
- if isinstance(rhs, basestring):
4824
+ if isinstance(rhs, str):
4838
4825
  rhs = myokit.parse_expression(rhs, context=self)
4839
4826
  elif rhs is not None:
4840
4827
  rhs = myokit.Number(rhs)
@@ -4885,7 +4872,7 @@ class Variable(VarOwner):
4885
4872
  """
4886
4873
  if unit is None or isinstance(unit, myokit.Unit):
4887
4874
  self._unit = unit
4888
- elif isinstance(unit, basestring):
4875
+ elif isinstance(unit, str):
4889
4876
  self._unit = myokit.parse_unit(unit)
4890
4877
  else:
4891
4878
  raise TypeError('Method set_unit() expects a myokit.Unit or None.')
@@ -5068,7 +5055,7 @@ class Variable(VarOwner):
5068
5055
  return self._rhs.eval()
5069
5056
 
5070
5057
 
5071
- class Equation(object):
5058
+ class Equation:
5072
5059
  """
5073
5060
  Defines an equation: a statement that a left-hand side (LHS) is equal to a
5074
5061
  right-hand side (RHS) expression.
@@ -5103,7 +5090,7 @@ class Equation(object):
5103
5090
 
5104
5091
  def code(self):
5105
5092
  """ Returns an ``.mmt`` representation of this equation. """
5106
- b = StringIO()
5093
+ b = io.StringIO()
5107
5094
  self._lhs._code(b, None)
5108
5095
  b.write(' = ')
5109
5096
  self._rhs._code(b, None)
@@ -5149,7 +5136,7 @@ class EquationList(list, VarProvider):
5149
5136
  return stream(self)
5150
5137
 
5151
5138
 
5152
- class UserFunction(object):
5139
+ class UserFunction:
5153
5140
  """
5154
5141
  Represents a user function.
5155
5142
 
myokit/_myokit_version.py CHANGED
@@ -4,7 +4,6 @@
4
4
  # This file is part of Myokit.
5
5
  # See http://myokit.org for copyright, sharing, and licensing details.
6
6
  #
7
- import sys
8
7
 
9
8
  # True if this is a release, False for a development version
10
9
  __release__ = True
@@ -15,7 +14,7 @@ __release__ = True
15
14
  # incompatibility
16
15
  # - Changes to revision indicate bugfixes, tiny new features
17
16
  # - There is no significance to odd/even numbers
18
- __version_tuple__ = 1, 34, 0
17
+ __version_tuple__ = 1, 35, 0
19
18
 
20
19
  # String version of the version number
21
20
  __version__ = '.'.join([str(x) for x in __version_tuple__])
@@ -23,6 +22,3 @@ if not __release__: # pragma: no cover
23
22
  __version_tuple__ += ('dev', )
24
23
  __version__ += '.dev'
25
24
 
26
- # Don't expose x on Python2
27
- if sys.hexversion < 0x03000000: # pragma: no python 3 cover
28
- del x