Skip to content

Commit

Permalink
add measure to yaml indicator description (#1664)
Browse files Browse the repository at this point in the history
<!--Please ensure the PR fulfills the following requirements! -->
<!-- If this is your first PR, make sure to add your details to the
AUTHORS.rst! -->
### Pull Request Checklist:
- [ ] This PR addresses an already opened issue (for bug fixes /
features)
    - This PR fixes #xyz
- [x] Tests for the changes have been added (for bug fixes / features)
- [x] (If applicable) Documentation has been added / updated (for bug
fixes / features)
- [x] CHANGES.rst has been updated (with summary of main changes)
- [x] Link to issue (:issue:`number`) and pull request (:pull:`number`)
has been added

### What kind of change does this PR introduce?

* Add `measure` to yaml indicator description. This is a argument that
can be given to `properties`.

### Does this PR introduce a breaking change?
no

### Other information:
Without this addition, xscen documentation fails.
  • Loading branch information
juliettelavoie committed Feb 26, 2024
2 parents 43612e3 + aadb084 commit 5530daf
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 6 deletions.
8 changes: 8 additions & 0 deletions CHANGES.rst
Expand Up @@ -2,6 +2,14 @@
Changelog
=========

v0.49.0 (unreleased)
--------------------
Contributors to this version: Juliette Lavoie (:user:`juliettelavoie`).

Bug fixes
^^^^^^^^^
* Add `measure` to YAML validation schema (for building sdba properties) and allow skipping the YAML validation when building modules. ( :pull:`1664`).

v0.48.1 (2024-02-20)
--------------------
Contributors to this version: Trevor James Smith (:user:`Zeitsperre`).
Expand Down
33 changes: 33 additions & 0 deletions tests/test_modules.py
Expand Up @@ -224,6 +224,39 @@ def test_realm(tmp_path):
assert mod.ice_extent.realm == "ocean"


def test_validate(tmp_path):
# Regression test for #1425
yml = """
realm: land
indicators:
ice_extent:
base: sea_ice_extent
realm: ocean
this_is_not_accepted: True
"""
fh = tmp_path / "test.yml"
fh.write_text(yml)

with pytest.raises(yamale.YamaleError):
build_indicator_module_from_yaml(fh, name="test")

build_indicator_module_from_yaml(fh, name="test2", validate=False)

sch = r"""
realm: str(required=False)
indicators: map(include('indicator'), key=regex(r'^[-\w]+$'))
---
indicator:
base: str(required=False)
realm: str(required=False)
this_is_not_accepted: bool()
"""
fsch = tmp_path / "schema.yml"
fsch.write_text(sch)
build_indicator_module_from_yaml(fh, name="test3", validate=fsch)


class TestOfficialYaml(yamale.YamaleTestCase):
base_dir = str(Path(__file__).parent.parent / "xclim" / "data")
schema = "schema.yml"
Expand Down
23 changes: 17 additions & 6 deletions xclim/core/indicator.py
Expand Up @@ -1664,6 +1664,7 @@ def build_indicator_module_from_yaml( # noqa: C901
mode: str = "raise",
encoding: str = "UTF8",
reload: bool = False,
validate: bool | PathLike = True,
) -> ModuleType:
"""Build or extend an indicator module from a YAML file.
Expand Down Expand Up @@ -1694,6 +1695,10 @@ def build_indicator_module_from_yaml( # noqa: C901
reload : bool
If reload is True and the module already exists, it is first removed before being rebuilt.
If False (default), indicators are added or updated, but not removed.
validate : bool or path
If True (default), the yaml module is validated against xclim's schema.
Can also be the path to a yml schema against which to validate.
Or False, in which case validation is simply skipped.
Returns
-------
Expand Down Expand Up @@ -1731,13 +1736,19 @@ def build_indicator_module_from_yaml( # noqa: C901
with ymlpath.open(encoding=encoding) as f:
yml = safe_load(f)

# Read schema
schema = yamale.make_schema(Path(__file__).parent.parent / "data" / "schema.yml")
if validate is not False:
# Read schema
if validate is not True:
schema = yamale.make_schema(validate)
else:
schema = yamale.make_schema(
Path(__file__).parent.parent / "data" / "schema.yml"
)

# Validate - a YamaleError will be raised if the module does not comply with the schema.
yamale.validate(
schema, yamale.make_data(content=ymlpath.read_text(encoding=encoding))
)
# Validate - a YamaleError will be raised if the module does not comply with the schema.
yamale.validate(
schema, yamale.make_data(content=ymlpath.read_text(encoding=encoding))
)

# Load values from top-level in yml.
# Priority of arguments differ.
Expand Down
1 change: 1 addition & 0 deletions xclim/data/schema.yml
Expand Up @@ -15,6 +15,7 @@ indicator:
compute: str(required=False)
input: map(str(), key=str(), required=False)
keywords: str(required=False)
measure: str(required=False)
missing: str(required=False)
missing_options: map(key=str(), required=False)
notes: str(required=False)
Expand Down

0 comments on commit 5530daf

Please sign in to comment.