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/_datablock.py CHANGED
@@ -4,15 +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
-
7
+ import array
10
8
  import os
11
9
  import sys
12
- import array
13
- import numpy as np
10
+
14
11
  import myokit
15
12
 
13
+ import numpy as np
14
+
16
15
 
17
16
  # Readme file for DataBlock1d binary files
18
17
  README_SAVE_1D = """
@@ -85,7 +84,7 @@ header, and little-endian:
85
84
  ENC = 'utf-8'
86
85
 
87
86
 
88
- class DataBlock1d(object):
87
+ class DataBlock1d:
89
88
  """
90
89
  Container for time-series of 1d rectangular data arrays.
91
90
 
@@ -476,17 +475,10 @@ class DataBlock1d(object):
476
475
  'This method requires the ``zlib`` module to be installed.')
477
476
 
478
477
  # Get size of single and double types on this machine
479
- try:
480
- dsize = {
481
- 'd': len(array.array('d', [1]).tobytes()),
482
- 'f': len(array.array('f', [1]).tobytes()),
483
- }
484
- except (AttributeError, TypeError): # pragma: no python 3 cover
485
- # List dtype as str for Python 2.7.10 (see #225)
486
- dsize = {
487
- b'd': len(array.array(b'd', [1]).tostring()),
488
- b'f': len(array.array(b'f', [1]).tostring()),
489
- }
478
+ dsize = {
479
+ 'd': len(array.array('d', [1]).tobytes()),
480
+ 'f': len(array.array('f', [1]).tobytes()),
481
+ }
490
482
 
491
483
  # Read data from file
492
484
  try:
@@ -544,8 +536,6 @@ class DataBlock1d(object):
544
536
  nt = int(next(head))
545
537
  nx = int(next(head))
546
538
  dtype = next(head)[1:-1]
547
- # Convert dtype to str for Python 2.7.10 (see #225)
548
- dtype = str(dtype)
549
539
  if dtype not in dsize:
550
540
  raise myokit.DataBlockReadError(
551
541
  'Unable to read DataBlock1d: Unrecognized data type "'
@@ -573,10 +563,7 @@ class DataBlock1d(object):
573
563
  'Unable to read DataBlock1d: Header indicates larger data'
574
564
  ' than found in the body.')
575
565
  data = array.array(dtype)
576
- try:
577
- data.frombytes(body[start:end])
578
- except AttributeError: # pragma: no python 3 cover
579
- data.fromstring(body[start:end])
566
+ data.frombytes(body[start:end])
580
567
  if sys.byteorder == 'big': # pragma: no cover
581
568
  data.byteswap()
582
569
  data = np.array(data)
@@ -597,10 +584,7 @@ class DataBlock1d(object):
597
584
  'Unable to read DataBlock1d: Header indicates larger'
598
585
  ' data than found in the body.')
599
586
  data = array.array(dtype)
600
- try:
601
- data.frombytes(body[start:end])
602
- except AttributeError: # pragma: no python 3 cover
603
- data.fromstring(body[start:end])
587
+ data.frombytes(body[start:end])
604
588
  if sys.byteorder == 'big': # pragma: no cover
605
589
  data.byteswap()
606
590
  data = np.array(data)
@@ -619,10 +603,7 @@ class DataBlock1d(object):
619
603
  'Unable to read DataBlock1d: Header indicates larger'
620
604
  ' data than found in the body.')
621
605
  data = array.array(dtype)
622
- try:
623
- data.frombytes(body[start:end])
624
- except AttributeError: # pragma: no python 3 cover
625
- data.fromstring(body[start:end])
606
+ data.frombytes(body[start:end])
626
607
  if sys.byteorder == 'big': # pragma: no cover
627
608
  data.byteswap()
628
609
  data = np.array(data).reshape(nt, nx, order='C')
@@ -680,8 +661,7 @@ class DataBlock1d(object):
680
661
  'This method requires the ``zlib`` module to be installed.')
681
662
 
682
663
  # Data type
683
- # Create dtype as str for Python 2.7.10 (see #225)
684
- dtype = str('d') # Only supporting doubles right now
664
+ dtype = 'd' # Only supporting doubles right now
685
665
 
686
666
  # Create header
687
667
  head_str = []
@@ -706,10 +686,7 @@ class DataBlock1d(object):
706
686
  if sys.byteorder == 'big': # pragma: no cover
707
687
  for ar in body_str:
708
688
  ar.byteswap()
709
- try:
710
- body_str = b''.join([ar.tobytes() for ar in body_str])
711
- except AttributeError: # pragma: no python 3 cover
712
- body_str = b''.join([ar.tostring() for ar in body_str])
689
+ body_str = b''.join([ar.tobytes() for ar in body_str])
713
690
 
714
691
  # Write
715
692
  head = zipfile.ZipInfo('header_block1d.txt')
@@ -803,7 +780,7 @@ class DataBlock1d(object):
803
780
  return self._1d[variable][:, x]
804
781
 
805
782
 
806
- class DataBlock2d(object):
783
+ class DataBlock2d:
807
784
  """
808
785
  Container for time-series of 2d rectangular data arrays.
809
786
 
@@ -1274,17 +1251,10 @@ class DataBlock2d(object):
1274
1251
  'This method requires the ``zlib`` module to be installed.')
1275
1252
 
1276
1253
  # Get size of single and double types on this machine
1277
- try:
1278
- dsize = {
1279
- 'd': len(array.array('d', [1]).tobytes()),
1280
- 'f': len(array.array('f', [1]).tobytes()),
1281
- }
1282
- except (AttributeError, TypeError): # pragma: no python 3 cover
1283
- # List dtype as str for Python 2.7.10 (see #225)
1284
- dsize = {
1285
- b'd': len(array.array(b'd', [1]).tostring()),
1286
- b'f': len(array.array(b'f', [1]).tostring()),
1287
- }
1254
+ dsize = {
1255
+ 'd': len(array.array('d', [1]).tobytes()),
1256
+ 'f': len(array.array('f', [1]).tobytes()),
1257
+ }
1288
1258
 
1289
1259
  # Read data from file
1290
1260
  try:
@@ -1353,8 +1323,7 @@ class DataBlock2d(object):
1353
1323
  nx = int(next(head))
1354
1324
 
1355
1325
  # Get dtype
1356
- # Convert dtype to str for Python 2.7.10 (see #225)
1357
- dtype = str(next(head))[1:-1]
1326
+ dtype = next(head)[1:-1]
1358
1327
  if dtype not in dsize:
1359
1328
  raise myokit.DataBlockReadError(
1360
1329
  'Unable to read DataBlock2d: Unrecognized data type "'
@@ -1384,10 +1353,7 @@ class DataBlock2d(object):
1384
1353
  ' than found in the body.')
1385
1354
 
1386
1355
  data = array.array(dtype)
1387
- try:
1388
- data.frombytes(body[start:end])
1389
- except AttributeError: # pragma: no python 3 cover
1390
- data.fromstring(body[start:end])
1356
+ data.frombytes(body[start:end])
1391
1357
  if sys.byteorder == 'big': # pragma: no cover
1392
1358
  data.byteswap()
1393
1359
  data = np.array(data)
@@ -1408,10 +1374,7 @@ class DataBlock2d(object):
1408
1374
  'Unable to read DataBlock2d: Header indicates larger'
1409
1375
  ' data than found in the body.')
1410
1376
  data = array.array(dtype)
1411
- try:
1412
- data.frombytes(body[start:end])
1413
- except AttributeError: # pragma: no python 3 cover
1414
- data.fromstring(body[start:end])
1377
+ data.frombytes(body[start:end])
1415
1378
  if sys.byteorder == 'big': # pragma: no cover
1416
1379
  data.byteswap()
1417
1380
  data = np.array(data)
@@ -1430,10 +1393,7 @@ class DataBlock2d(object):
1430
1393
  'Unable to read DataBlock2d: Header indicates larger'
1431
1394
  ' data than found in the body.')
1432
1395
  data = array.array(dtype)
1433
- try:
1434
- data.frombytes(body[start:end])
1435
- except AttributeError: # pragma: no python 3 cover
1436
- data.fromstring(body[start:end])
1396
+ data.frombytes(body[start:end])
1437
1397
  if sys.byteorder == 'big': # pragma: no cover
1438
1398
  data.byteswap()
1439
1399
  data = np.array(data).reshape(nt, ny, nx, order='C')
@@ -1496,8 +1456,7 @@ class DataBlock2d(object):
1496
1456
  'This method requires the ``zlib`` module to be installed.')
1497
1457
 
1498
1458
  # Data type
1499
- # Create dtype as str for Python 2.7.10 (see #225)
1500
- dtype = str('d') # Only supporting doubles right now
1459
+ dtype = 'd' # Only supporting doubles right now
1501
1460
 
1502
1461
  # Create header
1503
1462
  head_str = []
@@ -1523,10 +1482,7 @@ class DataBlock2d(object):
1523
1482
  if sys.byteorder == 'big': # pragma: no cover
1524
1483
  for ar in body_str:
1525
1484
  ar.byteswap()
1526
- try:
1527
- body_str = b''.join([ar.tobytes() for ar in body_str])
1528
- except AttributeError: # pragma: no python 3 cover
1529
- body_str = b''.join([ar.tostring() for ar in body_str])
1485
+ body_str = b''.join([ar.tobytes() for ar in body_str])
1530
1486
 
1531
1487
  # Write
1532
1488
  head = zipfile.ZipInfo('header_block2d.txt')
@@ -1671,7 +1627,7 @@ class DataBlock2d(object):
1671
1627
  return self._2d[variable][:, y, x]
1672
1628
 
1673
1629
 
1674
- class ColorMap(object):
1630
+ class ColorMap:
1675
1631
  """
1676
1632
  *Abstract class*
1677
1633
 
myokit/_datalog.py CHANGED
@@ -4,22 +4,16 @@
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
7
  import os
11
8
  import re
12
9
  import sys
13
10
  import array
11
+
14
12
  import numpy as np
13
+
15
14
  from collections import OrderedDict
16
- import myokit
17
15
 
18
- # Strings in Python 2 and 3
19
- try:
20
- basestring
21
- except NameError: # pragma: no python 2 cover
22
- basestring = str
16
+ import myokit
23
17
 
24
18
 
25
19
  # Function to split keys into dimension-key,qname-key pairs
@@ -101,11 +95,11 @@ class DataLog(OrderedDict):
101
95
  def __init__(self, other=None, time=None):
102
96
  if other is None:
103
97
  # Create new
104
- super(DataLog, self).__init__()
98
+ super().__init__()
105
99
  self._time = None
106
100
  else:
107
101
  # Clone
108
- super(DataLog, self).__init__(other)
102
+ super().__init__(other)
109
103
  try:
110
104
  self._time = str(other._time)
111
105
  except Exception:
@@ -216,10 +210,10 @@ class DataLog(OrderedDict):
216
210
  return log
217
211
 
218
212
  def __contains__(self, key):
219
- return super(DataLog, self).__contains__(self._parse_key(key))
213
+ return super().__contains__(self._parse_key(key))
220
214
 
221
215
  def __delitem__(self, key):
222
- return super(DataLog, self).__delitem__(self._parse_key(key))
216
+ return super().__delitem__(self._parse_key(key))
223
217
 
224
218
  def extend(self, other):
225
219
  """
@@ -328,7 +322,7 @@ class DataLog(OrderedDict):
328
322
  return out
329
323
 
330
324
  def __getitem__(self, key):
331
- return super(DataLog, self).__getitem__(self._parse_key(key))
325
+ return super().__getitem__(self._parse_key(key))
332
326
 
333
327
  def has_nan(self):
334
328
  """
@@ -517,17 +511,10 @@ class DataLog(OrderedDict):
517
511
  'This method requires the ``zlib`` module to be installed.')
518
512
 
519
513
  # Get size of single and double types on this machine
520
- try:
521
- dsize = {
522
- 'd': len(array.array('d', [1]).tobytes()),
523
- 'f': len(array.array('f', [1]).tobytes()),
524
- }
525
- except (AttributeError, TypeError): # pragma: no python 3 cover
526
- # List dtype as str for Python 2.7.10 (see #225)
527
- dsize = {
528
- b'd': len(array.array(b'd', [1]).tostring()),
529
- b'f': len(array.array(b'f', [1]).tostring()),
530
- }
514
+ dsize = {
515
+ 'd': len(array.array('d', [1]).tobytes()),
516
+ 'f': len(array.array('f', [1]).tobytes()),
517
+ }
531
518
 
532
519
  # Read data
533
520
  try:
@@ -563,7 +550,7 @@ class DataLog(OrderedDict):
563
550
  head = iter(head.splitlines())
564
551
  n = int(next(head))
565
552
  data_size = int(next(head))
566
- data_type = str(next(head)) # Cast to str for Python 2.7.10 (see #225)
553
+ data_type = next(head)
567
554
  time = next(head)
568
555
  if time:
569
556
  # Note, this field doesn't have to be present in the log!
@@ -604,10 +591,7 @@ class DataLog(OrderedDict):
604
591
 
605
592
  # Read data
606
593
  ar = array.array(data_type)
607
- try:
608
- ar.frombytes(body[start:end])
609
- except AttributeError: # pragma: no python 3 cover
610
- ar.fromstring(body[start:end])
594
+ ar.frombytes(body[start:end])
611
595
  if sys.byteorder == 'big': # pragma: no cover
612
596
  ar.byteswap()
613
597
  log[field] = ar
@@ -638,8 +622,7 @@ class DataLog(OrderedDict):
638
622
  filename = os.path.expanduser(filename)
639
623
 
640
624
  # Typecode dependent on precision
641
- # Typecode must be str for Python 2.7.10 (see #225)
642
- typecode = str('d' if precision == myokit.DOUBLE_PRECISION else 'f')
625
+ typecode = 'd' if precision == myokit.DOUBLE_PRECISION else 'f'
643
626
 
644
627
  # Error raising function
645
628
  def e(line, char, msg):
@@ -647,16 +630,9 @@ class DataLog(OrderedDict):
647
630
  'Syntax error on line ' + str(line) + ', character '
648
631
  + str(1 + char) + ': ' + msg)
649
632
 
650
- def uopen(filename):
651
- # Open a filename in 'universal newline' mode, python 2 and 3
652
- try:
653
- return open(filename, 'r', newline=None)
654
- except TypeError: # pragma: no python 3 cover
655
- return open(filename, 'U')
656
-
657
633
  quote = '"'
658
634
  delim = ','
659
- with uopen(filename) as f:
635
+ with open(filename, 'r', newline=None) as f:
660
636
  # Read header
661
637
  keys = [] # The log keys, in order of appearance
662
638
 
@@ -936,8 +912,7 @@ class DataLog(OrderedDict):
936
912
  'This method requires the `zlib` module to be installed.')
937
913
 
938
914
  # Data type
939
- # dtype must be str for Python 2.7.10 (see #225)
940
- dtype = str('d' if precision == myokit.DOUBLE_PRECISION else 'f')
915
+ dtype = 'd' if precision == myokit.DOUBLE_PRECISION else 'f'
941
916
 
942
917
  # Create data strings
943
918
  head_str = []
@@ -959,10 +934,7 @@ class DataLog(OrderedDict):
959
934
  ar = array.array(dtype, v)
960
935
  if sys.byteorder == 'big': # pragma: no cover
961
936
  ar.byteswap()
962
- try:
963
- body_str.append(ar.tobytes())
964
- except AttributeError: # pragma: no python 3 cover
965
- body_str.append(ar.tostring())
937
+ body_str.append(ar.tobytes())
966
938
  head_str = '\n'.join(head_str)
967
939
  body_str = b''.join(body_str)
968
940
 
@@ -1006,7 +978,7 @@ class DataLog(OrderedDict):
1006
978
  If a precision argument (for example ``myokit.DOUBLE_PRECISION``)
1007
979
  is given, the output will be stored in such a way that this amount
1008
980
  of precision is guaranteed to be present in the string. If the
1009
- precision argument is set to ``None`` python's default formatting
981
+ precision argument is set to ``None`` Python's default formatting
1010
982
  is used, which may lead to smaller files.
1011
983
  ``order``
1012
984
  To specify the ordering of the log's arguments, pass in a sequence
@@ -1107,7 +1079,7 @@ class DataLog(OrderedDict):
1107
1079
  self._time = None if key is None else str(key)
1108
1080
 
1109
1081
  def __setitem__(self, key, value):
1110
- return super(DataLog, self).__setitem__(
1082
+ return super().__setitem__(
1111
1083
  self._parse_key(key), value)
1112
1084
 
1113
1085
  def split(self, value):
@@ -1422,7 +1394,7 @@ class DataLog(OrderedDict):
1422
1394
  return infos
1423
1395
 
1424
1396
 
1425
- class LoggedVariableInfo(object):
1397
+ class LoggedVariableInfo:
1426
1398
  """
1427
1399
  Contains information about the log entries for each variable. These objects
1428
1400
  should only be created by :meth:`DataLog.variable_info()`.
@@ -1629,9 +1601,7 @@ def prepare_log(
1629
1601
  be specified using the ``precision`` argument.
1630
1602
  """
1631
1603
  # Typecode dependent on precision
1632
- # Note: Cast to str() here makes it work with older versions of 2.7.x,
1633
- # where unicode isn't accepted (Python 3 of course doesn't accept bytes)
1634
- typecode = str('d' if precision == myokit.DOUBLE_PRECISION else 'f')
1604
+ typecode = 'd' if precision == myokit.DOUBLE_PRECISION else 'f'
1635
1605
 
1636
1606
  # Get all options for dimensionality
1637
1607
  if dims is None:
@@ -1874,7 +1844,7 @@ def prepare_log(
1874
1844
  'Argument `log` has unexpected type. Expecting None, integer flag,'
1875
1845
  ' sequence of names, dict or DataLog.')
1876
1846
 
1877
- if isinstance(log, basestring):
1847
+ if isinstance(log, str):
1878
1848
  raise ValueError(
1879
1849
  'String passed in as `log` argument, should be list'
1880
1850
  ' or other sequence containing strings.')
myokit/_err.py CHANGED
@@ -4,8 +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
- from __future__ import absolute_import, division
8
- from __future__ import print_function, unicode_literals
9
7
 
10
8
 
11
9
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -24,7 +22,7 @@ class MyokitError(Exception):
24
22
  *Extends:* ``Exception``
25
23
  """
26
24
  def __init__(self, message):
27
- super(MyokitError, self).__init__(message)
25
+ super().__init__(message)
28
26
 
29
27
 
30
28
  class IntegrityError(MyokitError):
@@ -37,7 +35,7 @@ class IntegrityError(MyokitError):
37
35
  *Extends:* :class:`myokit.MyokitError`
38
36
  """
39
37
  def __init__(self, message, token=None):
40
- super(IntegrityError, self).__init__(message)
38
+ super().__init__(message)
41
39
  self._token = token
42
40
 
43
41
  def token(self):
@@ -77,7 +75,7 @@ class CyclicalDependencyError(IntegrityError):
77
75
  # Set token: First item in cycle is model's defining lhs
78
76
  tok = cycle[0].var()._token
79
77
  # Raise
80
- super(CyclicalDependencyError, self).__init__(msg, tok)
78
+ super().__init__(msg, tok)
81
79
 
82
80
 
83
81
  class DataBlockReadError(MyokitError):
@@ -167,7 +165,7 @@ class IllegalReferenceError(IntegrityError):
167
165
  *Extends:* :class:`myokit.IntegrityError`
168
166
  """
169
167
  def __init__(self, reference, owner):
170
- super(IllegalReferenceError, self).__init__(
168
+ super().__init__(
171
169
  'Illegal reference: The referenced variable <' + reference.qname()
172
170
  + '> is outside the scope of <' + owner.qname() + '>.')
173
171
 
@@ -179,7 +177,7 @@ class IllegalReferenceInInitialValueError(IllegalReferenceError):
179
177
  The only way this can occur is if the reference is to a nested variable.
180
178
  """
181
179
  def __init__(self, reference, owner):
182
- super(IllegalReferenceError, self).__init__(
180
+ super(IntegrityError, self).__init__(
183
181
  'Illegal reference made in initial value: The referenced variable'
184
182
  ' <' + reference.qname() + '> is nested.')
185
183
 
@@ -203,7 +201,7 @@ class IncompatibleModelError(MyokitError):
203
201
  if model_name:
204
202
  msg += ' <' + str(model_name) + '>'
205
203
  msg += ': ' + str(message)
206
- super(IncompatibleModelError, self).__init__(msg)
204
+ super().__init__(msg)
207
205
 
208
206
 
209
207
  class IncompatibleUnitError(MyokitError):
@@ -213,7 +211,7 @@ class IncompatibleUnitError(MyokitError):
213
211
  *Extends:* :class:`myokit.MyokitError`.
214
212
  """
215
213
  def __init__(self, message, token=None):
216
- super(MyokitError, self).__init__(message)
214
+ super().__init__(message)
217
215
  self._token = token
218
216
 
219
217
  def token(self):
@@ -288,7 +286,7 @@ class MissingRhsError(IntegrityError):
288
286
  def __init__(self, var):
289
287
  msg = 'No rhs set for <' + var.qname() + '>.'
290
288
  tok = var._token
291
- super(MissingRhsError, self).__init__(msg, tok)
289
+ super().__init__(msg, tok)
292
290
 
293
291
 
294
292
  class MissingTimeVariableError(IntegrityError):
@@ -300,7 +298,7 @@ class MissingTimeVariableError(IntegrityError):
300
298
  def __init__(self):
301
299
  msg = 'No variable bound to time. At least one of the model\'s' \
302
300
  ' variables must be bound to "time".'
303
- super(MissingTimeVariableError, self).__init__(msg)
301
+ super().__init__(msg)
304
302
 
305
303
 
306
304
  class NumericalError(MyokitError):
@@ -339,7 +337,7 @@ class ParseError(MyokitError):
339
337
  self.desc = str(desc)
340
338
  self.value += ': ' + self.desc
341
339
  self.cause = cause
342
- super(ParseError, self).__init__(self.value)
340
+ super().__init__(self.value)
343
341
 
344
342
 
345
343
  class ProtocolEventError(MyokitError):
@@ -383,7 +381,7 @@ class SimulationCancelledError(MyokitError):
383
381
  *Extends:* :class:`myokit.MyokitError`
384
382
  """
385
383
  def __init__(self, message='Operation cancelled by user.'):
386
- super(SimulationCancelledError, self).__init__(message)
384
+ super().__init__(message)
387
385
 
388
386
 
389
387
  class SimultaneousProtocolEventError(MyokitError):
@@ -402,7 +400,7 @@ class UnresolvedReferenceError(IntegrityError):
402
400
  *Extends:* :class:`myokit.IntegrityError`
403
401
  """
404
402
  def __init__(self, reference, extra_message=None):
405
- super(UnresolvedReferenceError, self).__init__(
403
+ super().__init__(
406
404
  'Unknown variable: <' + reference + '>.'
407
405
  + ((' ' + extra_message) if extra_message else '')
408
406
  )
@@ -419,7 +417,7 @@ class UnusedVariableError(IntegrityError):
419
417
  def __init__(self, var):
420
418
  msg = 'Unused variable: <' + var.qname() + '>.'
421
419
  tok = var.lhs()._token
422
- super(UnusedVariableError, self).__init__(msg, tok)
420
+ super().__init__(msg, tok)
423
421
 
424
422
 
425
423
  class VariableMappingError(MyokitError):