Skip to content

Commit 5f54643

Browse files
authored
Merge pull request #392 from Climate-REF/update-conda-for-pmp
Specify environment variables when running PMP diagnostic
2 parents 38090c4 + 0edcb4e commit 5f54643

File tree

5 files changed

+62
-8
lines changed

5 files changed

+62
-8
lines changed

changelog/392.feature.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Made it possible to run PMP diagnostics without having conda installed.

packages/climate-ref-core/src/climate_ref_core/providers.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,27 @@ def _get_micromamba_url() -> str:
232232
class CondaDiagnosticProvider(CommandLineDiagnosticProvider):
233233
"""
234234
A provider for diagnostics that can be run from the command line in a conda environment.
235+
236+
Parameters
237+
----------
238+
name
239+
The name of the provider.
240+
version
241+
The version of the provider.
242+
slug
243+
A slugified version of the name.
244+
repo
245+
URL of the git repository to install a development version of the package from.
246+
tag_or_commit
247+
Tag or commit to install from the `repo` repository.
248+
249+
Attributes
250+
----------
251+
env_vars
252+
Environment variables to set when running commands in the conda environment.
253+
url
254+
URL to install a development version of the package from.
255+
235256
"""
236257

237258
def __init__(
@@ -246,6 +267,7 @@ def __init__(
246267
self._conda_exe: Path | None = None
247268
self._prefix: Path | None = None
248269
self.url = f"git+{repo}@{tag_or_commit}" if repo and tag_or_commit else None
270+
self.env_vars: dict[str, str] = {}
249271

250272
@property
251273
def prefix(self) -> Path:
@@ -404,6 +426,8 @@ def run(self, cmd: Iterable[str]) -> None:
404426
*cmd,
405427
]
406428
logger.info(f"Running '{' '.join(cmd)}'")
429+
env_vars = os.environ.copy()
430+
env_vars.update(self.env_vars)
407431
try:
408432
# This captures the log output until the execution is complete
409433
# We could poll using `subprocess.Popen` if we want something more responsive
@@ -413,6 +437,7 @@ def run(self, cmd: Iterable[str]) -> None:
413437
stdout=subprocess.PIPE,
414438
stderr=subprocess.STDOUT,
415439
text=True,
440+
env=env_vars,
416441
)
417442
logger.info("Command output: \n" + res.stdout)
418443
logger.info("Command execution successful")

packages/climate-ref-core/tests/unit/test_providers.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,12 @@ def test_run(self, mocker, tmp_path, provider, env_exists):
294294
):
295295
provider.run(["mock-command"])
296296
else:
297+
mocker.patch.object(
298+
climate_ref_core.providers.os.environ,
299+
"copy",
300+
return_value={"existing_var": "existing_value"},
301+
)
302+
provider.env_vars = {"test_var": "test_value"}
297303
provider.run(["mock-command"])
298304

299305
run.assert_called_with(
@@ -308,4 +314,5 @@ def test_run(self, mocker, tmp_path, provider, env_exists):
308314
stdout=subprocess.PIPE,
309315
stderr=subprocess.STDOUT,
310316
text=True,
317+
env={"existing_var": "existing_value", "test_var": "test_value"},
311318
)

packages/climate-ref-pmp/src/climate_ref_pmp/__init__.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,45 @@
22
Rapid evaluating CMIP data
33
"""
44

5+
from __future__ import annotations
6+
57
import importlib.metadata
8+
import os
9+
from typing import TYPE_CHECKING
10+
11+
from loguru import logger
612

713
from climate_ref_core.dataset_registry import DATASET_URL, dataset_registry_manager
814
from climate_ref_core.providers import CondaDiagnosticProvider
915
from climate_ref_pmp.diagnostics import ENSO, AnnualCycle, ExtratropicalModesOfVariability
1016

17+
if TYPE_CHECKING:
18+
from climate_ref.config import Config
19+
1120
__version__ = importlib.metadata.version("climate-ref-pmp")
1221

22+
1323
# Create the PMP diagnostics provider
1424
# PMP uses a conda environment to run the diagnostics
15-
provider = CondaDiagnosticProvider("PMP", __version__)
25+
class PMPDiagnosticProvider(CondaDiagnosticProvider):
26+
"""
27+
Provider for PMP diagnostics.
28+
"""
29+
30+
def configure(self, config: Config) -> None:
31+
"""Configure the provider."""
32+
super().configure(config)
33+
self.env_vars["PCMDI_CONDA_EXE"] = str(self.get_conda_exe())
34+
# This is a workaround for a fatal error in internal_Finalize of MPICH
35+
# when running in a conda environment on MacOS.
36+
# It is not clear if this is a bug in MPICH or a problem with the conda environment.
37+
if "FI_PROVIDER" not in os.environ: # pragma: no branch
38+
logger.debug("Setting env variable 'FI_PROVIDER=tcp'")
39+
self.env_vars["FI_PROVIDER"] = "tcp"
40+
41+
42+
provider = PMPDiagnosticProvider("PMP", __version__)
43+
1644

1745
# Annual cycle diagnostics and metrics
1846
provider.register(AnnualCycle())

packages/climate-ref-pmp/src/climate_ref_pmp/pmp_driver.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,6 @@ def build_pmp_command(
159159
# Note this uses the driver script from the REF env *not* the PMP conda env
160160
_parameter_file = _get_resource("climate_ref_pmp.params", parameter_file, use_resources=True)
161161

162-
# This is a workaround for a fatal error in internal_Finalize of MPICH
163-
# when running in a conda environment on MacOS.
164-
# It is not clear if this is a bug in MPICH or a problem with the conda environment.
165-
if "FI_PROVIDER" not in os.environ: # pragma: no branch
166-
logger.debug("Setting env variable 'FI_PROVIDER=tcp'")
167-
os.environ["FI_PROVIDER"] = "tcp"
168-
169162
# Run the driver script inside the PMP conda environment
170163
cmd = [
171164
driver_file,

0 commit comments

Comments
 (0)