Skip to content

Commit 2ade43d

Browse files
authored
Merge pull request #341 from iiasa/enh/data-paths
Adjust handling of data paths in tests, CI
2 parents ea59cd9 + ff3f474 commit 2ade43d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+471
-227
lines changed

.github/workflows/pytest.yaml

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
path: message-static-data
7878
ssh-key: ${{ secrets.MESSAGE_STATIC_DATA_PRIVATE_KEY }}
7979
lfs: true
80-
# Only check out the following directories, in order to limit bandwith usage:
80+
# Only check out the following directories, in order to limit bandwidth usage:
8181
sparse-checkout: |
8282
iea/eei
8383
ssp
@@ -125,8 +125,10 @@ jobs:
125125
- name: Cache test data
126126
uses: actions/cache@v4
127127
with:
128-
path: message-local-data
129-
key: ${{ matrix.os }}
128+
path: |
129+
local-data
130+
.pytest_cache/d
131+
key: local-data-${{ matrix.os }}-upstream-${{ matrix.version.upstream }}
130132

131133
- name: Check out message-ix-models
132134
uses: francisbilham11/action-cached-lfs-checkout@v3
@@ -140,9 +142,9 @@ jobs:
140142
key: static-data-${{ matrix.os }}
141143

142144
- name: Set up uv, Python
143-
uses: astral-sh/setup-uv@v5
145+
uses: astral-sh/setup-uv@v6
144146
with:
145-
cache-dependency-glob: "**/pyproject.toml"
147+
activate-environment: true
146148
python-version: ${{ matrix.version.python }}
147149

148150
- uses: iiasa/actions/setup-gams@main
@@ -195,12 +197,12 @@ jobs:
195197
196198
- name: Configure local data path
197199
run: |
198-
mkdir -p message-local-data/cache
199-
mix-models config set "message local data" "$(realpath message-local-data)"
200+
mkdir -p local-data
201+
mix-models config set "message local data" "$(realpath local-data)"
200202
mix-models config show
201203
# Symlink message-static-data into local data path
202-
mkdir -p ${{ github.workspace }}/message-local-data
203-
cp -rsv $(realpath message-static-data)/* message-local-data/
204+
mkdir -p ${{ github.workspace }}/local-data
205+
cp -rsv $(realpath message-static-data)/* local-data/
204206
205207
- name: Run test suite using pytest
206208
run: |
@@ -224,11 +226,11 @@ jobs:
224226
- uses: actions/checkout@v4
225227
with: { ref: "${{ needs.check.outputs.ref }}" }
226228
- uses: astral-sh/setup-uv@v6
227-
with: { enable-cache: true, python-version: "${{ env.python-version }}" }
229+
with: { python-version: "${{ env.python-version }}" }
228230
- name: Clear and re-create the pre-commit environments
229231
run: uvx pre-commit clean
230232
if: github.event_name == 'schedule' # Comment this line to force clear
231233
- run: |
232234
uvx --with=pre-commit-uv \
233235
pre-commit run \
234-
--all-files --color=always --show-diff-on-failure --verbose
236+
--all-files --color=always --show-diff-on-failure --verbose

doc/api/tests.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Test suite (:mod:`.tests`)
2+
**************************
3+
4+
The entire test suite is documented here,
5+
recursively and automatically.
6+
7+
.. autosummary::
8+
:toctree: _autosummary
9+
:template: autosummary-module.rst
10+
:recursive:
11+
12+
message_ix_models.tests

doc/api/tools.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Exogenous data (:mod:`.tools.exo_data`)
5858

5959
.. autoclass:: ExoDataSource
6060
:members:
61+
:private-members: _where
6162
:special-members: __init__, __call__
6263

6364
.. currentmodule:: message_ix_models.tools.advance

doc/conf.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,12 @@ def local_inv(name: str, *parts: str) -> Optional[str]:
223223

224224
napoleon_preprocess_types = True
225225
napoleon_type_aliases = {
226+
# Python standard library
226227
"iterable": ":class:`~collections.abc.Iterable`",
227228
"sequence": ":class:`~collections.abc.Sequence`",
228-
"Path": ":class:`~pathlib.Path`",
229229
"PathLike": ":class:`os.PathLike`",
230+
# genno
231+
"AnyQuantity": ":data:`~genno.core.quantity.AnyQuantity`",
230232
}
231233

232234
# -- Options for sphinx.ext.todo -------------------------------------------------------

doc/global/external_index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
MESSAGE-GLOBIOM
2-
====
2+
***************
33

44
MESSAGE-GLOBIOM combines the global energy systems model MESSAGE and the
55
land~use model GLOBIOM into a consistent Integrated Assessment Modeling (IAM)

doc/howto/unicc.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ However, this will show a lot of information, so it might be better to run a mor
904904
sacct --format=jobid,MaxRSS,MaxVMSize,start,end,CPUTimeRAW,NodeList
905905
906906
Resources to request for reducing MESSAGEix run time
907-
---------------------------------------------------
907+
----------------------------------------------------
908908

909909
The following information is based on non-scientific "testing" (goofing around), so take it with a grain of salt.
910910
I have found that requesting more CPUs per task can help reduce the run time of a MESSAGEix solve.

doc/index.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ Commonly used classes may be imported directly from :mod:`message_ix_models`.
5353
- :doc:`api/report/index`
5454
- :doc:`api/tools`
5555
- :doc:`api/data-sources`
56+
- :doc:`api/workflow`
5657
- :doc:`api/util`
5758
- :doc:`api/testing`
58-
- :doc:`api/workflow`
59+
- :doc:`api/tests`
5960

6061
.. toctree::
6162
:maxdepth: 2
@@ -73,9 +74,11 @@ Commonly used classes may be imported directly from :mod:`message_ix_models`.
7374
api/tools-costs
7475
api/tools-messagev
7576
api/data-sources
77+
api/workflow
7678
api/util
7779
api/testing
78-
api/workflow
80+
api/tests
81+
7982

8083
.. toctree::
8184
:maxdepth: 2

doc/whatsnew.rst

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Next release
1616
- :py:`transform="C"` / :func:`.transform_C` (:issue:`229`, :pull:`300`).
1717
- The :class:`~.web.TRANSFORM` enumeration for specifying and validating multiple transformations.
1818

19+
- Improve :class:`.ExoDataSource` with :attr:`~.ExoDataSource.use_test_data`,
20+
:attr:`~.ExoDataSource.where`, and :meth:`~.ExoDataSource._where` (:pull:`341`).
1921
- New class :class:`.Dataflow` for describing input and/or output data flows (:pull:`300`) that are read from file and attached to a :class:`.Computer`.
2022
Generalized from former :py:`.transport.files.ExogenousDataFile`.
2123
- New method :meth:`.Config.regions_from_scenario` (:pull:`300`),
@@ -29,8 +31,19 @@ Next release
2931
- :func:`.check.verbose_check` (:pull:`300`).
3032

3133
- Display entire result quantity in :func:`.report.report` / :program:`mix-models report` with :py:`verbose=True` (:pull:`300`).
34+
- New test fixtures (:pull:`341`):
35+
:func:`.advance_test_data`,
36+
:func:`.gea_test_data`,
37+
:func:`.gfei_test_data`,
38+
:func:`.iea_eei_user_data`,
39+
:func:`.iea_eweb_test_data`,
40+
:func:`.iea_eweb_user_data`,
41+
:func:`.shape_test_data`,
42+
:func:`.ssp_test_data`,
43+
:func:`.ssp_user_data`.
3244
- Bug fix: :program:`mix-models --verbose` command-line option was not stored on :class:`.Context`/:class:`~.util.Config` (:pull:`300`).
33-
- Bug fix: adjust or guard some Python usage that was not compatible with Python 3.9—the earliest version supported by :mod:`message_ix_models` (:pull:`295`, :issue:`294`).
45+
- Bug fix: adjust or guard some Python usage that was not compatible with Python 3.9
46+
—the earliest version supported by :mod:`message_ix_models` (:pull:`295`, :issue:`294`).
3447
- Drop obsolete :py:`series_of_pint_quantity()` (:pull:`289`).
3548

3649
By topic:
@@ -108,6 +121,8 @@ Documentation
108121
- Expand the :ref:`costs-usage` section of the :mod:`.tools.costs` documentation to describe the requirement for SSP input data (:issue:`313`, :pull:`322`).
109122
- Reorganize and improve the :doc:`data` documentation page (:pull:`326`).
110123

124+
.. _v2025.1.10:
125+
111126
v2025.1.10
112127
==========
113128

message_ix_models/model/transport/data.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class MaybeAdaptR11Source(ExoDataSource):
150150
_adapter: Optional[Callable] = None
151151

152152
def __init__(self, source, source_kw):
153-
from .util import path_fallback
153+
from .util import region_path_fallback
154154

155155
# Check that the given measure is supported by the current class
156156
if not source == self.id:
@@ -175,11 +175,11 @@ def __init__(self, source, source_kw):
175175

176176
filename = self.filename[measure]
177177
try:
178-
self.path = path_fallback(nodes, filename)
178+
self.path = region_path_fallback(nodes, filename)
179179
self._repr = f"Load {self.path}"
180180
except FileNotFoundError:
181181
log.info(f"Fall back to R11 data for {self.measure}")
182-
self.path = path_fallback("R11", filename)
182+
self.path = region_path_fallback("R11", filename)
183183

184184
# Identify an adapter that can convert data from R11 to `nodes`
185185
self._adapter = {"R12": adapt_R11_R12, "R14": adapt_R11_R14}.get(nodes)

message_ix_models/model/transport/emission.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from message_ix_models.util import package_data_path
1313

14-
from .util import path_fallback
14+
from .util import region_path_fallback
1515

1616
if TYPE_CHECKING:
1717
from genno.types import AnyQuantity
@@ -26,7 +26,7 @@ def get_emissions_data(context: "Context") -> "ParameterData":
2626
"""Load emissions data from a file."""
2727

2828
fn = f"{context.transport.data_source.emissions}-emission_factor.csv"
29-
qty = load_file(path_fallback(context, "emi", fn))
29+
qty = load_file(region_path_fallback(context, "emi", fn))
3030

3131
return dict(emission_factor=qty.to_dataframe())
3232

message_ix_models/model/transport/operator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ def broadcast_t_c_l(
268268
def broadcast_y_yv_ya(
269269
y: list[int], y_include: list[int], *, method: str = "product"
270270
) -> "AnyQuantity":
271-
"""Return a quantity for broadcasting y to (yv, ya).
271+
r"""Return a quantity for broadcasting y to (yv, ya).
272272
273273
This omits all :math:`y^V \notin y^{include}`.
274274

message_ix_models/model/transport/structure.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from message_ix_models.model.structure import generate_set_elements, get_region_codes
1212
from message_ix_models.util import load_package_data, package_data_path
1313

14-
from .util import path_fallback
14+
from .util import region_path_fallback
1515

1616
#: Template for disutility technologies.
1717
TEMPLATE = Code(
@@ -80,7 +80,7 @@ def make_spec(regions: str) -> Spec:
8080

8181
# Load and store the data from the YAML file: either in a subdirectory for
8282
# context.model.regions, or the top-level data directory
83-
path = path_fallback(regions, fn).relative_to(package_data_path())
83+
path = region_path_fallback(regions, fn).relative_to(package_data_path())
8484
tmp[name] = load_package_data(*path.parts)
8585

8686
# Merge contents of technology.yaml into set.yaml

message_ix_models/model/transport/testing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
reason="Graphviz missing on macos-13 GitHub Actions runners",
4848
),
4949
9: pytest.mark.xfail(reason="Missing R14 input data/config"),
50+
10: pytest.mark.usefixtures("iea_eweb_test_data", "ssp_user_data"),
5051
"gh-288": pytest.mark.xfail(
5152
reason="Temporary, for https://github.com/iiasa/message-ix-models/pull/288",
5253
),

message_ix_models/model/transport/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def has_input_commodity(technology: "Code", commodity: str) -> bool:
3232
return False
3333

3434

35-
def path_fallback(context_or_regions: Union[Context, str], *parts) -> Path:
35+
def region_path_fallback(context_or_regions: Union[Context, str], *parts) -> Path:
3636
"""Return a :class:`.Path` constructed from `parts`.
3737
3838
If ``context.model.regions`` (or a string value as the first argument) is defined

message_ix_models/project/advance/data.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@
55

66
from message_ix_models.tools.exo_data import ExoDataSource, register_source
77
from message_ix_models.tools.iamc import iamc_like_data_for_query
8-
from message_ix_models.util import (
9-
HAS_MESSAGE_DATA,
10-
iter_keys,
11-
package_data_path,
12-
private_data_path,
13-
)
8+
from message_ix_models.util import iter_keys, path_fallback
149

1510
__all__ = [
1611
"ADVANCE",
@@ -89,6 +84,8 @@ class ADVANCE(ExoDataSource):
8984

9085
id = "ADVANCE"
9186

87+
where = ["private"]
88+
9289
def __init__(self, source, source_kw):
9390
if not source == self.id:
9491
raise ValueError(source)
@@ -125,12 +122,7 @@ def __call__(self):
125122
log.debug(query)
126123

127124
# Expected location of the ADVANCE WP2 data snapshot.
128-
parts = LOCATION
129-
if HAS_MESSAGE_DATA:
130-
path = private_data_path(*parts)
131-
else:
132-
path = package_data_path("test", *parts)
133-
log.warning(f"Reading random data from {path}")
125+
path = path_fallback(*LOCATION, where=self._where())
134126

135127
return iamc_like_data_for_query(
136128
path, query, archive_member=NAME, non_iso_3166="keep"

message_ix_models/project/gea/data.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class GEA(ExoDataSource):
3939
#: By default, do not interpolate.
4040
interpolate = False
4141

42+
where = ["private"]
43+
4244
def __init__(self, source, source_kw):
4345
if source != self.id:
4446
raise ValueError(source)
@@ -58,10 +60,8 @@ def __init__(self, source, source_kw):
5860

5961
# Identify input data path
6062
self.path = path_fallback(
61-
"gea", "GEADB_ARCHIVE_20171108.zip", where="private test"
63+
"gea", "GEADB_ARCHIVE_20171108.zip", where=self._where()
6264
)
63-
if "test" in self.path.parts:
64-
log.warning(f"Reading random data from {self.path}")
6565

6666
# Assemble query
6767
self.query = " and ".join(

message_ix_models/project/shape/data.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ class SHAPE(ExoDataSource):
6565

6666
id = "SHAPE"
6767

68+
where = ["private"]
69+
6870
def __init__(self, source, source_kw):
6971
if source != self.id:
7072
raise ValueError(source)
@@ -85,13 +87,8 @@ def __init__(self, source, source_kw):
8587
version = version.replace("latest", info["latest"])
8688

8789
# Construct path to data file
88-
self.path = path_fallback(
89-
"shape",
90-
f"{self.measure}_v{version.replace('.', 'p')}{info['suffix']}",
91-
where="private test",
92-
)
93-
if "test" in self.path.parts:
94-
log.warning(f"Reading random data from {self.path}")
90+
filename = f"{self.measure}_v{version.replace('.', 'p')}{info['suffix']}"
91+
self.path = path_fallback("shape", filename, where=self._where())
9592

9693
variable = info.get("variable", self.measure)
9794
self.query = " and ".join(

0 commit comments

Comments
 (0)