Skip to content

Commit 2ded599

Browse files
Bug fixes and improve tests
1 parent c9142dd commit 2ded599

File tree

5 files changed

+574
-649
lines changed

5 files changed

+574
-649
lines changed

docs/whats_new.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Bug fixes
1919
- Fix bug when a WITH LOOKUPS argument has subscripts. (`@enekomartinmartinez <https://github.com/enekomartinmartinez>`_)
2020
- Fix bug of exportig csv files with multiple subscripts variables. (`@rogersamso <https://github.com/rogersamso>`_)
2121
- Fix bug of missing dimensions in variables defined with not all the subscripts of a range (:issue:`364`). (`@enekomartinmartinez <https://github.com/enekomartinmartinez>`_)
22+
- Fix bug when running a model with variable final time or time step and progressbar (:issue:`361`). (`@enekomartinmartinez <https://github.com/enekomartinmartinez>`_)
2223

2324
Documentation
2425
~~~~~~~~~~~~~
@@ -31,7 +32,9 @@ Performance
3132
Internal Changes
3233
~~~~~~~~~~~~~~~~
3334
- Make PySD work with :py:mod:`parsimonius` 0.10.0. (`@enekomartinmartinez <https://github.com/enekomartinmartinez>`_)
34-
- Add netCDF4 and hdf5 dependencies. (`@rogersamso <https://github.com/rogersamso>`_)
35+
- Add netCDF4 dependency for tests. (`@rogersamso <https://github.com/rogersamso>`_)
36+
- Improve warning message when replacing a stock with a parameter. (`@enekomartinmartinez <https://github.com/enekomartinmartinez>`_)
37+
- Include more pytest parametrizations in some test and make them translate the models in temporary directories. (`@enekomartinmartinez <https://github.com/enekomartinmartinez>`_)
3538

3639

3740
v3.6.1 (2022/09/05)

pysd/py_backend/model.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ def export(self, file_name):
485485
486486
Parameters
487487
----------
488-
file_name: str
488+
file_name: str or pathlib.Path
489489
Name of the file to export the values.
490490
491491
"""
@@ -512,7 +512,7 @@ def import_pickle(self, file_name):
512512
513513
Parameters
514514
----------
515-
file_name: str
515+
file_name: str or pathlib.Path
516516
Name of the file to import the values from.
517517
518518
"""
@@ -781,8 +781,8 @@ def set_components(self, params, new=False):
781781

782782
# this won't handle other statefuls...
783783
if '_integ_' + func_name in dir(self.components):
784-
warnings.warn("Replacing the equation of stock"
785-
+ "{} with params".format(key),
784+
warnings.warn("Replacing the equation of stock "
785+
"'{}' with params...".format(key),
786786
stacklevel=2)
787787

788788
new_function.__name__ = func_name
@@ -1134,8 +1134,6 @@ def run(self, params=None, return_columns=None, return_timestamps=None,
11341134
if reload:
11351135
self.reload()
11361136

1137-
self.progress = progress
1138-
11391137
self.time.add_return_timestamps(return_timestamps)
11401138
if self.time.return_timestamps is not None and not final_time:
11411139
# if not final time given the model will end in the list
@@ -1156,6 +1154,18 @@ def run(self, params=None, return_columns=None, return_timestamps=None,
11561154

11571155
self.set_initial_condition(initial_condition)
11581156

1157+
# set progressbar
1158+
if progress and (self.cache_type["final_time"] == "step" or
1159+
self.cache_type["time_step"] == "step"):
1160+
warnings.warn(
1161+
"The progressbar is not compatible with dynamic "
1162+
"final time or time step. Both variables must be "
1163+
"constants to prompt progress."
1164+
)
1165+
progress = False
1166+
1167+
self.progress = progress
1168+
11591169
if return_columns is None or isinstance(return_columns, str):
11601170
return_columns = self._default_return_columns(return_columns)
11611171

@@ -1625,7 +1635,7 @@ def set_initial_condition(self, initial_condition):
16251635
16261636
Parameters
16271637
----------
1628-
initial_condition : str or (float, dict)
1638+
initial_condition : str or (float, dict) or pathlib.Path
16291639
The starting time, and the state of the system (the values of
16301640
all the stocks) at that starting time. 'original' or 'o'uses
16311641
model-file specified initial condition. 'current' or 'c' uses
@@ -1647,19 +1657,21 @@ def set_initial_condition(self, initial_condition):
16471657
model.set_initial_value()
16481658
16491659
"""
1660+
if isinstance(initial_condition, str)\
1661+
and initial_condition.lower() not in ["original", "o",
1662+
"current", "c"]:
1663+
initial_condition = Path(initial_condition)
16501664

16511665
if isinstance(initial_condition, tuple):
16521666
self.initialize()
16531667
self.set_initial_value(*initial_condition)
1668+
elif isinstance(initial_condition, Path):
1669+
self.import_pickle(initial_condition)
16541670
elif isinstance(initial_condition, str):
16551671
if initial_condition.lower() in ["original", "o"]:
16561672
self.time.set_control_vars(
16571673
initial_time=self.components._control_vars["initial_time"])
16581674
self.initialize()
1659-
elif initial_condition.lower() in ["current", "c"]:
1660-
pass
1661-
else:
1662-
self.import_pickle(initial_condition)
16631675
else:
16641676
raise TypeError(
16651677
"Invalid initial conditions. "

tests/conftest.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
import pytest
1+
import shutil
22
from pathlib import Path
33

4+
import pytest
5+
from pysd import read_vensim, read_xmile, load
6+
from pysd.translators.vensim.vensim_utils import supported_extensions as\
7+
vensim_extensions
8+
from pysd.translators.xmile.xmile_utils import supported_extensions as\
9+
xmile_extensions
10+
411

512
@pytest.fixture(scope="session")
613
def _root():
@@ -18,3 +25,24 @@ def _test_models(_root):
1825
def shared_tmpdir(tmpdir_factory):
1926
# shared temporary directory for each class
2027
return Path(tmpdir_factory.mktemp("shared"))
28+
29+
30+
@pytest.fixture
31+
def model(_root, tmp_path, model_path):
32+
"""
33+
Copy model to the tmp_path and translate it
34+
"""
35+
assert (_root / model_path).exists(), "The model doesn't exist"
36+
37+
target = tmp_path / model_path.parent.name
38+
new_path = target / model_path.name
39+
shutil.copytree(_root / model_path.parent, target)
40+
41+
if model_path.suffix.lower() in vensim_extensions:
42+
return read_vensim(new_path)
43+
elif model_path.suffix.lower() in xmile_extensions:
44+
return read_xmile(new_path)
45+
elif model_path.suffix.lower() == ".py":
46+
return load(new_path)
47+
else:
48+
return ValueError("Invalid model")

tests/pytest_pysd/pytest_output.py

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from pathlib import Path
2-
import shutil
32

43
import pytest
54
import numpy as np
@@ -11,8 +10,6 @@
1110
from pysd.py_backend.output import OutputHandlerInterface, DatasetHandler, \
1211
DataFrameHandler, ModelOutput
1312

14-
import pysd
15-
1613

1714
test_model_look = Path(
1815
"test-models/tests/get_lookups_subscripted_args/"
@@ -36,18 +33,6 @@
3633
)
3734

3835

39-
@pytest.fixture
40-
@pytest.mark.filterwarnings("ignore")
41-
def model(_root, tmp_path, model_path):
42-
"""
43-
Copy model to the tmp_path and translate it
44-
"""
45-
46-
target = tmp_path / model_path.parent
47-
shutil.copytree(_root / model_path.parent, target)
48-
return pysd.read_vensim(target / model_path.name)
49-
50-
5136
class TestOutput():
5237

5338
def test_output_handler_interface(self):
@@ -135,6 +120,16 @@ class EmptyHandler(OutputHandlerInterface):
135120
EmptyHandler.add_run_elements(
136121
EmptyHandler, "model", "capture")
137122

123+
@pytest.mark.parametrize("model_path", [test_model_look])
124+
def test_invalid_output_file(self, model):
125+
error_message = "Paths must be strings or pathlib Path objects."
126+
with pytest.raises(TypeError, match=error_message):
127+
model.run(output_file=1234)
128+
129+
error_message = "Unsupported output file format .txt"
130+
with pytest.raises(ValueError, match=error_message):
131+
model.run(output_file="file.txt")
132+
138133
@pytest.mark.parametrize(
139134
"model_path,dims,values",
140135
[

0 commit comments

Comments
 (0)